figura-skin/scripts/libs/oklab.lua
reidlab d1809b35ee
init (again)
i accidentally [doxxed myself](https://github.com/JannisX11/blockbench/issues/1322), thanks blockbench!
2025-03-15 15:35:15 -07:00

113 lines
No EOL
2.9 KiB
Lua

local lib = {}
---@param x number
---@return number
local function fromLinear(x)
if x >= 0.0031308 then
return 1.055 * math.pow(x, 1.0/2.4) - 0.055
else
return 12.92 * x
end
end
---@param x number
---@return number
local function toLinear(x)
if x >= 0.04045 then
return math.pow((x + 0.055)/(1 + 0.055), 2.4)
else
return x / 12.92
end
end
---Converts from sRGB to Linear sRGB
---@param color Vector3
---@return Vector3
function lib.srgbToLinear(color)
return vec(toLinear(color.x), toLinear(color.y), toLinear(color.z))
end
---Converts from Linear sRGB to sRGB
---@param color Vector3
---@return Vector3
function lib.linearToSrgb(color)
return vec(fromLinear(color.x), fromLinear(color.y), fromLinear(color.z))
end
---Converts from Linear sRGB to OKLAB
---@param color Vector3
---@return Vector3
function lib.linearToOklab(color)
local l = 0.4122214708 * color.r + 0.5363325363 * color.g + 0.0514459929 * color.b
local m = 0.2119034982 * color.r + 0.6806995451 * color.g + 0.1073969566 * color.b
local s = 0.0883024619 * color.r + 0.2817188376 * color.g + 0.6299787005 * color.b
local l_ = math.pow(l, 1/3)
local m_ = math.pow(m, 1/3)
local s_ = math.pow(s, 1/3)
return vec(
0.2104542553*l_ + 0.7936177850*m_ - 0.0040720468*s_,
1.9779984951*l_ - 2.4285922050*m_ + 0.4505937099*s_,
0.0259040371*l_ + 0.7827717662*m_ - 0.8086757660*s_
)
end
---Converts from OKLAB to Linear sRGB
---@param color Vector3
---@return Vector3
function lib.oklabToLinear(color)
local l_ = color.x + 0.3963377774 * color.y + 0.2158037573 * color.z;
local m_ = color.x - 0.1055613458 * color.y - 0.0638541728 * color.z;
local s_ = color.x - 0.0894841775 * color.y - 1.2914855480 * color.z;
local l = l_*l_*l_;
local m = m_*m_*m_;
local s = s_*s_*s_;
return vec(
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
)
end
---Converts from LAB to LCh
---@param color Vector3
---@return Vector3
function lib.labToLch(color)
return vec(
color.x,
math.sqrt(color.y * color.y + color.z * color.z),
math.deg(math.atan2(color.z, color.y))
)
end
---Converts from LCh to LAB
---@param color Vector3
---@return Vector3
function lib.lchToLab(color)
return vec(
color.x,
color.y * math.cos(math.rad(color.z)),
color.y * math.sin(math.rad(color.z))
)
end
---Converts from sRGB to OKLCh
---@param color Vector3
---@return Vector3
function lib.srgbToOklch(color)
return lib.labToLch(lib.linearToOklab(lib.srgbToLinear(color)))
end
---Converts from OKLCh to sRGB
---@param color Vector3
---@return Vector3
function lib.oklchToSrgb(color)
return lib.linearToSrgb(lib.oklabToLinear(lib.lchToLab(color)))
end
return lib