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

[css-color-4] gather use cases and examples for gamut mapping #9966

Open
romainmenke opened this issue Feb 15, 2024 · 3 comments
Open

[css-color-4] gather use cases and examples for gamut mapping #9966

romainmenke opened this issue Feb 15, 2024 · 3 comments

Comments

@romainmenke
Copy link
Member

see : #9449

A lot of examples are provided by everyone in the threads around gamut mapping and I think we should try and catalogue these.

Eventually we will need to have some testing for gamut mapping in WPT and having interesting cases will help with that.

Being able to easily revisit cases with a new perspective or when trying a different algorithm will also help us make better choices.

At the same time there doesn't seem to be a good intuition for gamut mapping and how colors that can't be displayed should look. Recording the intention and expected outcome with examples will be informative.

@LeaVerou
Copy link
Member

A huge use case is when creating tints of accent colors (a prime use case for polar spaces).

Let’s take red as an example, an sRGB color, which corresponds to oklch(62.8% 0.258 29.2). Cranking up its lightness to 90% gets us not only outside P3, it gets us outside Rec.2020!
Reducing its chroma until it fits within P3 takes us down to a chroma of 0.06 (!).

https://colorjs.io/apps/gamut-mapping/?color=red&color=oklch%2890%25+0.258+29.2%29&color=oklch%2890%25+0.06+29.2%29

image

@facelessuser
Copy link

facelessuser commented Feb 17, 2024

EDIT: I wasn't using the scaling values I thought I was. Corrected examples and images to use correct scaling constants.

Also, toe function comes from https://bottosson.github.io/posts/colorpicker/#common-code. Constants are tweaked to generally get achromatic lightness values closer to Lab instead of just targeting middle gray to match Lab.

I think when it comes to tones and OkLCh, the problem is more the scaling of lightness in OkLCh, not the reducing of chroma. I also don't think the result for 90% lightness using the CSS GMA method is actually a bad result. In the example below, we will try to create tones by just changing lightness and using the CSS GMA.

The first example uses CSS GMA with OkLCh as is. The results are okay, but with the way lightness is scaled, dark tones are hard to distinguish. But when we adust our lightness scale to to be closer to CIE Lab (D65), we get reasonable, predictable tones. Tones at 90% are pretty comparable in both cases.

Example here.

Screenshot 2024-02-17 at 9 03 19 AM

Let's compare Scale LH and vs the CSS GMA + some lightness scaling. Example. Scale LH appears to have a hard time creating tones that are easy to distinguish when the lightness is too high.

Screenshot 2024-02-17 at 8 59 41 AM

If we apply the same lightness scaling to Scale LH, we still have the same issue in the 90%+ region, but the rest does look good.

Screenshot 2024-02-17 at 9 01 59 AM

@facelessuser
Copy link

I've added a GMA algorithm that can be experimented with here: https://colorjs.io/apps/gamut-mapping/?color=red&color=oklch%2890%25+0.258+29.2%29&color=oklch%2890%25+0.06+29.2%29. (source). It is a chroma-reduction approach.

It basically uses the simplicity of the RGB shape and uses ray casting, whichis easy to perform on simple, aligned cube, to find the most saturated point on the cube for a given color. This point is corrected in the perceptually uniform OkLCh space. It takes 3 attempts and is able to reduce chroma while keeping lightness and hue lower than the CSS algorithm. Tests showed worst cases (gamut mapping to display-p3) are approximately: ∆L ~= 0.011682128741787201 ∆h ~= -4.212684767726387.

It is much faster than the CSS approach which had a maximum deviation of approx. ∆L ~= 0.01935711395956019 ∆h ~= 67.51890805748971. In its defense, this worst case is at extremely low light oklch(0.015 0.8 96.5).

For a generic approach that doesn't have to approximate the shape of Oklab, I'm kind of surprised how well it turned out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants