Untitled
unknown
lua
a year ago
4.6 kB
6
Indexable
Never
-- Combines two colors in CIELUV space. -- function<function<Color3 result>(float t)>(Color3 fromColor, Color3 toColor) -- https://www.w3.org/Graphics/Color/srgb local clamp = math.clamp local C3 = Color3.new local black = C3(0, 0, 0) -- Convert from linear RGB to scaled CIELUV local function RgbToLuv13(c) local r, g, b = c.r, c.g, c.b -- Apply inverse gamma correction r = r < 0.0404482362771076 and r/12.92 or 0.87941546140213*(r + 0.055)^2.4 g = g < 0.0404482362771076 and g/12.92 or 0.87941546140213*(g + 0.055)^2.4 b = b < 0.0404482362771076 and b/12.92 or 0.87941546140213*(b + 0.055)^2.4 -- sRGB->XYZ->CIELUV local y = 0.2125862307855956*r + 0.71517030370341085*g + 0.0722004986433362*b local z = 3.6590806972265883*r + 11.4426895800574232*g + 4.1149915024264843*b local l = y > 0.008856451679035631 and 116*y^(1/3) - 16 or 903.296296296296*y if z > 1e-15 then local x = 0.9257063972951867*r - 0.8333736323779866*g - 0.09209820666085898*b return l, l*x/z, l*(9*y/z - 0.46832) else return l, -0.19783*l, -0.46832*l end end function LerpCIELUV(c0, c1) local l0, u0, v0 = RgbToLuv13(c0) local l1, u1, v1 = RgbToLuv13(c1) return function(t) -- Interpolate local l = (1 - t)*l0 + t*l1 if l < 0.0197955 then return black end local u = ((1 - t)*u0 + t*u1)/l + 0.19783 local v = ((1 - t)*v0 + t*v1)/l + 0.46832 -- CIELUV->XYZ local y = (l + 16)/116 y = y > 0.206896551724137931 and y*y*y or 0.12841854934601665*y - 0.01771290335807126 local x = y*u/v local z = y*((3 - 0.75*u)/v - 5) -- XYZ->linear sRGB local r = 7.2914074*x - 1.5372080*y - 0.4986286*z local g = -2.1800940*x + 1.8757561*y + 0.0415175*z local b = 0.1253477*x - 0.2040211*y + 1.0569959*z -- Adjust for the lowest out-of-bounds component if r < 0 and r < g and r < b then r, g, b = 0, g - r, b - r elseif g < 0 and g < b then r, g, b = r - g, 0, b - g elseif b < 0 then r, g, b = r - b, g - b, 0 end return C3( -- Apply gamma correction and clamp the result clamp(r < 3.1306684425e-3 and 12.92*r or 1.055*r^(1/2.4) - 0.055, 0, 1), clamp(g < 3.1306684425e-3 and 12.92*g or 1.055*g^(1/2.4) - 0.055, 0, 1), clamp(b < 3.1306684425e-3 and 12.92*b or 1.055*b^(1/2.4) - 0.055, 0, 1) ) end end function BezierCIELUV(c1, c2, c3) return function(t) local lerpFunc1 = LerpCIELUV(c1, c2) local lerpFunc2 = LerpCIELUV(c2, c3) local midColor1 = lerpFunc1(t) local midColor2 = lerpFunc2(t) local lerpFunc3 = LerpCIELUV(midColor1, midColor2) return lerpFunc3(t) end end function AverageCIELUVBezier(c1, c2, c3) local bezierFunc = BezierCIELUV(c1, c2, c3) local avgColor = bezierFunc(0.5) return avgColor end local function AverageRGB(...) local r, g, b = 0, 0, 0 local count = select("#", ...) for i = 1, count do local color = select(i, ...) r += color.R^2 g += color.G^2 b += color.B^2 end return Color3.new((r / count)^0.5, (g / count)^0.5, (b / count)^0.5) end function AverageCIELUV(c1, c2, c3) local function v3FromColor(c) local l, u, v = RgbToLuv13(c) return Vector3.new(l, u, v) end local v1 = v3FromColor(c1) local v2 = v3FromColor(c2) local v3 = v3FromColor(c3) local avgVector = (v1 + v2 + v3)/3 -- Convert the resulting Vector3 back to a Color3 -- CIELUV->XYZ local y = (avgVector.x + 16)/116 y = y > 0.206896551724137931 and y*y*y or 0.12841854934601665*y - 0.01771290335807126 local x = y*avgVector.y/avgVector.z local z = y*((3 - 0.75*avgVector.y)/avgVector.z - 5) -- XYZ->linear sRGB local r = 7.2914074*x - 1.5372080*y - 0.4986286*z local g = -2.1800940*x + 1.8757561*y + 0.0415175*z local b = 0.1253477*x - 0.2040211*y + 1.0569959*z -- Apply gamma correction and clamp the result return C3( clamp(r < 3.1306684425e-3 and 12.92*r or 1.055*r^(1/2.4) - 0.055, 0, 1), clamp(g < 3.1306684425e-3 and 12.92*g or 1.055*g^(1/2.4) - 0.055, 0, 1), clamp(b < 3.1306684425e-3 and 12.92*b or 1.055*b^(1/2.4) - 0.055, 0, 1) ) end local avg = AverageRGB(game.Selection:Get()[1].Color,game.Selection:Get()[1].Color,game.Selection:Get()[3].Color) workspace.TestColor.Color = avg task.wait(2) local avg = AverageCIELUVBezier(game.Selection:Get()[1].Color,game.Selection:Get()[1].Color,game.Selection:Get()[3].Color) workspace.TestColor.Color = avg task.wait(2) local avg = AverageCIELUV(game.Selection:Get()[1].Color,game.Selection:Get()[1].Color,game.Selection:Get()[3].Color) workspace.TestColor.Color = avg return LerpCIELUV