mirror of
https://github.com/Ukendio/jecs.git
synced 2026-02-04 15:15:21 +00:00
111 lines
2.6 KiB
Text
111 lines
2.6 KiB
Text
|
|
--!native
|
||
|
|
--!optimize 2
|
||
|
|
--!strict
|
||
|
|
local Spring_Vector3 = require("./vector3")
|
||
|
|
|
||
|
|
export type Spring = {
|
||
|
|
type: "Color3",
|
||
|
|
d: number,
|
||
|
|
f: number,
|
||
|
|
g: Vector3,
|
||
|
|
p: Vector3,
|
||
|
|
v: Vector3
|
||
|
|
}
|
||
|
|
|
||
|
|
local function create(d: number, f: number, origo: Color3, goal: Color3): Spring
|
||
|
|
return {
|
||
|
|
type = "Color3",
|
||
|
|
d = d,
|
||
|
|
f = f,
|
||
|
|
g = Vector3.new(),
|
||
|
|
p = Vector3.new(),
|
||
|
|
v = Vector3.new(),
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
local function inverseGammaCorrectD65(c)
|
||
|
|
return c < 0.0404482362771076 and c/12.92 or 0.87941546140213*(c + 0.055)^2.4
|
||
|
|
end
|
||
|
|
|
||
|
|
local function gammaCorrectD65(c)
|
||
|
|
return c < 3.1306684425e-3 and 12.92*c or 1.055*c^(1/2.4) - 0.055
|
||
|
|
end
|
||
|
|
|
||
|
|
local function rgbToLuv(value: Vector3): Color3
|
||
|
|
-- convert RGB to a variant of cieluv space
|
||
|
|
local r, g, b = value.X, value.Y, value.Z
|
||
|
|
|
||
|
|
-- D65 sRGB inverse gamma correction
|
||
|
|
r = inverseGammaCorrectD65(r)
|
||
|
|
g = inverseGammaCorrectD65(g)
|
||
|
|
b = inverseGammaCorrectD65(b)
|
||
|
|
|
||
|
|
-- sRGB -> xyz
|
||
|
|
local x = 0.9257063972951867*r - 0.8333736323779866*g - 0.09209820666085898*b
|
||
|
|
local y = 0.2125862307855956*r + 0.71517030370341085*g + 0.0722004986433362*b
|
||
|
|
local z = 3.6590806972265883*r + 11.4426895800574232*g + 4.1149915024264843*b
|
||
|
|
|
||
|
|
-- xyz -> scaled cieluv
|
||
|
|
local l = y > 0.008856451679035631 and 116*y^(1/3) - 16 or 903.296296296296*y
|
||
|
|
|
||
|
|
local u, v
|
||
|
|
if z > 1e-14 then
|
||
|
|
u = l*x/z
|
||
|
|
v = l*(9*y/z - 0.46832)
|
||
|
|
else
|
||
|
|
u = -0.19783*l
|
||
|
|
v = -0.46832*l
|
||
|
|
end
|
||
|
|
|
||
|
|
return Color3.new(l,u,v)
|
||
|
|
end
|
||
|
|
local function luvToRgb(value: Vector3): Color3
|
||
|
|
-- convert back from modified cieluv to rgb space
|
||
|
|
local l = value.X
|
||
|
|
if l < 0.0197955 then
|
||
|
|
return Color3.new(0, 0, 0)
|
||
|
|
end
|
||
|
|
local u = value.Y/l + 0.19783
|
||
|
|
local v = value.Z/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 -> D65 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
|
||
|
|
|
||
|
|
-- clamp minimum sRGB 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
|
||
|
|
|
||
|
|
-- gamma correction from D65
|
||
|
|
-- clamp to avoid undesirable overflow wrapping behavior on certain properties (e.g. BasePart.Color)
|
||
|
|
return Color3.new(
|
||
|
|
math.min(gammaCorrectD65(r), 1),
|
||
|
|
math.min(gammaCorrectD65(g), 1),
|
||
|
|
math.min(gammaCorrectD65(b), 1)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function step(spring: Spring, dt: number): Color3
|
||
|
|
Spring_Vector3.step((spring::any), dt)
|
||
|
|
return rgbToLuv(spring.g)
|
||
|
|
end
|
||
|
|
|
||
|
|
return {
|
||
|
|
create = create,
|
||
|
|
step = step,
|
||
|
|
can_sleep = Spring_Vector3.can_sleep,
|
||
|
|
rgbToLuv = rgbToLuv
|
||
|
|
}
|