-
Notifications
You must be signed in to change notification settings - Fork 693
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
[css-color-4] Gamut Mapping Clarifications #9651
Comments
Yes, the algorithm should consistently return the gamut mapped color in the |
Changes to step 1 are now done |
I notice that the introductory text about the scope and applicability of the CSS GMA is in an inconsistent state. It started off as being widely applicable (for example, it used to be required before conversion to HSL and HWB). Explanatory notes were added to say that a different algorithm would be required:
and so the section title describes the primary use case: 13.2. CSS Gamut Mapping to an RGB Destination Despite that, the pseudo-code is written to assume an arbitrary (colorimetric) destination color space, and the first line of the pseudo-code says what to do if And so, as you point out, what to do if In practice, for the color spaces defined in CSS Color 4, I think that is all that is left once (XYZ-D65, XYZ-D50, Lab, LCH, Oklab, Oklch) is excluded. Looking now (to check for upwards compatibility) at CSS Color HDR, then
Looking too at what is in Color.js, I think that there is value in keeping the wider generality of the CSS GMA, which does mean that continuing to specify |
It seems that
(and would be clear, and correct in all these cases. (Note to self, check why Color.js claims |
@jamesnw @weinig @mysteryDate @facelessuser @LeaVerou any comments on returning |
Only if Oklab is using a corrected matrix where |
Thanks for the nudge, corrected |
Does this change the values for all |
They should be the same up to ~32 bit precision. Changes in the matrix are mainly out in the 64 bit portion. You can see, the inverse matrix before just had garbage in the 64bit portion: const LabtoLMS_M = [
[ 0.99999999845051981432, 0.39633779217376785678, 0.21580375806075880339 ],
[ 1.0000000088817607767, -0.1055613423236563494, -0.063854174771705903402 ],
[ 1.0000000546724109177, -0.089484182094965759684, -1.2914855378640917399 ]
]; Now the new matrix will give you a proper LMS of [1, 1, 1] for const LabtoLMS_M = [
[ 1.0000000000000000, 0.3963377773761749, 0.2158037573099136 ],
[ 1.0000000000000000, -0.1055613458156586, -0.0638541728258133 ],
[ 1.0000000000000000, -0.0894841775298119, -1.2914855480194092 ]
]; |
The adjustment simply reduces the rounding errors. It is way below the level which would produce a visible difference in a single color conversion. |
On the one hand, the current text is very precise: <li>let clip(|color|) be a function which converts |color| to |destination|,
converts all negative components to zero,
converts all components greater that one to one,
and returns the result On the other hand, it could be expanded to cover a <li>let clip(|color|) be a function which converts |color| to |destination|,
converts all components less than the lower bound of the reference range to the lower bound,
converts all components greater than the upper bound of the reference range to the upper bound,
and returns the result Does that seem clear and understandable? |
I think that is clear and understandable. One potential alternative would be-
Or is this functionally different from clamping? Potential nits that I don't think warrant changes, and are fairly unlikely to cause confusion, but are here for documentation-
|
Closed by 5d806c1 |
In implementing the Gamut Mapping Algorithm in Color.js, I found a few areas where clarification in the pseudocode could be helpful. If any of these are too pedantic for pseudocode, feel free to ignore.
return |origin|
withconvert |origin| to |destination| and return it as the gamut mapped color
. The explicit conversion is the important bit, the "as the gamut mapped color" is for parity with the other returns.clip
, should we change it to specify it clamps to the range of the color channel, instead of 0-1? This may be a moot point, as it appears that only unbounded spaces which don't go through this portion have channel ranges besides 0-1.clip
, there's an extra pipe character at the end ofclip(color)|
The text was updated successfully, but these errors were encountered: