facelessuser / ColorHelper

Sublime plugin that provides helpful color previews and tooltips
https://facelessuser.github.io/ColorHelper/
MIT License
254 stars 30 forks source link

Do we make Oklch chroma reduction gamut mapping optional? #214

Closed facelessuser closed 1 year ago

facelessuser commented 2 years ago

I trying to decide if we should expose the Oklch chroma reduction gamut mapping to better align with the CSS Level 4 spec. Personally, I don't think it works that great for gamut mapping, but some may want to do things like the spec dictates. But, let's just state that the spec only very recently specified a gamut mapping algorithm, I don't believe it's been real-world tested to any great extent. I suspect their recommendation will change.

The CSS Color Level 4 spec currently defines the MINDE gamut mapping algorithm as the recommended way to gamut map colors. I think some general observations have been made based on Oklab's hue preservation and such, but beyond that, I don't think it has been put through its paces yet.

Currently, I have a couple of issues with the MINDE algorithm.

  1. The way MINDE with Oklch (or any other space) can sometimes give colors that are noticeably distant from other colors. The current algorithm we use is based on their earlier experiments in the Colorjs.io library which, albeit more expensive to execute, creates much better, smooth color transitions when gamut mapping colors. MINDE seems to have been designed to be less expensive, but it also seems less accurate and can be seen when trying to create gradients.
  2. Oklch has some corner cases that produce some odd mappings. I'm not arguing that Oklch can't be used to gamut map, but what I am saying is that I am doubtful that the overly simplified approach as expressed by the MINDE algorithm is the right choice. There has been some work by the Oklab/Oklch author on gamut mapping that seems to work pretty well, but is tuned to the sRGB color space and is quite a bit more complicated.

While I agree that Oklab is a superior interpolation color space to CIELAB, I feel that CIELAB with ∆E2000 does better with gamut mapping visually, at least with the simplified algorithm they've laid out.

Granted, we aren't using MINDE as described in the spec, but using a slightly different form of chroma reduction that seems to work better, albeit a little more expensive to execute, but the results are similar, just that our approach is a bit smoother.

Here you can see we interpolate green and blue using different interpolation spaces, but all of the out-of-gamut colors are gamut mapped to sRGB with Oklch chroma reduction as required by the CSS Level 4 Color spec. Notice how poorly it does with CIELCH colors, and the right-hand side of the Oklch interpolation example has a less smooth transition to blue.

Screen Shot 2022-02-18 at 1 35 56 PM

Now notice the same interpolations then gamut mapped to sRGB with CIELCH chroma reduction. The colors look visually how you would expect. Colors, that resulted as out-of-gamut due to the interpolation in a much larger space map right back to sRGB looking quite sane. There are a number of cases where CIELCH just seems to give users what they would expect.

Screen Shot 2022-02-18 at 1 36 07 PM

CIELAB/CIELCH has its own problems and honestly isn't a great interpolation color space. I think Oklab is a great interpolation color space but doesn't perform well for gamut mapping with simple chroma reduction, there would have to be some better compensation done when gamut mapping.

The question though, do we expose the other algorithm for CSS Level 4 purists? Do we wait as we expect they will see the light and change it? Do we just not offer it because it isn't very helpful?

Anyways, this issue will track our decision on this. I've opened an issue over at CSSWG to discuss this. I want to see what they say before I make any final decisions.

facelessuser commented 2 years ago

All of this work is actually handled in ColorAide. ColorAide does currently allow users to use CIELCH or Oklch (CIELCH being the default as of 0.10.0) -- related issue https://github.com/facelessuser/coloraide/issues/118. This is more to just decide whether we hook into that ability to use the alternate algorithm.

facelessuser commented 1 year ago

Gamut mapping is configurable via 028c3229207670a8a6e36576b1a6d6feae46d5c8.