Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sRGB Transformations #283

Merged
merged 10 commits into from
Apr 15, 2024
Merged

sRGB Transformations #283

merged 10 commits into from
Apr 15, 2024

Conversation

jalsop24
Copy link
Contributor

@jalsop24 jalsop24 commented Oct 1, 2023

PR resolves #257. My goal is to start off by implementing the basic sRGB transfers. I think more discussion is needed to determine how to allow users to choose their own gamut.

This should be accounted for, at minimum the sRGB transfer functions could be added

My understanding of this is practically wrapping the Oklab to/from methods with sRGB conversions:

-- Converts a Color3 in RGB space to a Vector3 in Oklab space.
function Oklab.to(srgb: Color3): Vector3
	-- Now assume that the input Color3 is part of sRGB, so convert it to 
	-- linear before operating on it
	local rgb = sRGB.toLinear(srgb)

	local l = rgb.R * 0.4122214708 + rgb.G * 0.5363325363 + rgb.B * 0.0514459929
	local m = rgb.R * 0.2119034982 + rgb.G * 0.6806995451 + rgb.B * 0.1073969566
	local s = rgb.R * 0.0883024619 + rgb.G * 0.2817188376 + rgb.B * 0.6299787005

	local lRoot = l ^ (1/3)
	local mRoot = m ^ (1/3)
	local sRoot = s ^ (1/3)

	return Vector3.new(
		lRoot * 0.2104542553 + mRoot * 0.7936177850 - sRoot * 0.0040720468,
		lRoot * 1.9779984951 - mRoot * 2.4285922050 + sRoot * 0.4505937099,
		lRoot * 0.0259040371 + mRoot * 0.7827717662 - sRoot * 0.8086757660
	)
end

-- Converts a Vector3 in CIELAB space to a Color3 in RGB space.
-- The Color3 will be clamped by default unless specified otherwise.
function Oklab.from(lab: Vector3, unclamped: boolean?): Color3
	local lRoot = lab.X + lab.Y * 0.3963377774 + lab.Z * 0.2158037573
	local mRoot = lab.X - lab.Y * 0.1055613458 - lab.Z * 0.0638541728
	local sRoot = lab.X - lab.Y * 0.0894841775 - lab.Z * 1.2914855480

	local l = lRoot ^ 3
	local m = mRoot ^ 3
	local s = sRoot ^ 3

	local red = l * 4.0767416621 - m * 3.3077115913 + s * 0.2309699292
	local green = l * -1.2684380046 + m * 2.6097574011 - s * 0.3413193965
	local blue = l * -0.0041960863 - m * 0.7034186147 + s * 1.7076147010

	if not unclamped then
		red = math.clamp(red, 0, 1)
		green = math.clamp(green, 0, 1)
		blue = math.clamp(blue, 0, 1)
	end
	
	-- Perform the conversion back into sRGB before returning
	return sRGB.fromLinear(Color3.new(red, green, blue))
end

@jalsop24 jalsop24 marked this pull request as ready for review October 2, 2023 16:26
@jalsop24 jalsop24 marked this pull request as draft October 2, 2023 16:26
@jalsop24
Copy link
Contributor Author

jalsop24 commented Oct 4, 2023

Currently I'm aiming for this sort of syntax:

local Oklab = Fusion.Oklab

local bgColour = Spring(Computed(function(use)
    return if use(isRed) then Oklab.new(0.600, 0.483, 0.128) else Oklab.new(0.600, −0.100, −0.490)
end), 20, 0.5)

local frame = New "Frame" {
    BackgroundColor3 = Computed(function(use) return use(bgColour):toSRGB() end)
}

@dphfox
Copy link
Owner

dphfox commented Oct 15, 2023

New syntax for colour manipulation is outside the scope of the linked issue and should really be discussed elsewhere, please stick to the existing API surface for now. This is an internal bug where our existing contract with the user isn't being upheld - fixing this does not require changing the contract, it only requires changing our internal code to conform to it as we originally promised to users.

Other than that, I'd be happy to accept a simpler version that implements the appropriate conversions to ensure Color3 is interpreted as sRGB rather than linear RGB.

jalsop24 and others added 2 commits October 15, 2023 21:13
This reverts commit a4f095d.

Revert "Custom Oklab type"

This reverts commit 53cb996.
@jalsop24
Copy link
Contributor Author

Okay I've reverted back to a simpler implementation that focuses on the srgb <-> oklab conversion.

@jalsop24 jalsop24 marked this pull request as ready for review October 22, 2023 20:32
@dphfox dphfox merged commit 2e19c7f into dphfox:main Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Oklab <-> Color3 conversions do not use sRGB transfer functions
2 participants