Re: [csswg-drafts] [css-color-4] CSS gamut mapping algorithm clarifications (#7653)

I have deployed another demo page to illustrate the Oklab color space specifically, when gamut mapping is performed in Oklch with a JND (just-noticeable difference) of `0.02`: [Gamut-mapping Oklab to sRGB](https://danburzo.ro/demos/color/gamut-mapping-oklab.html)

You can compare:
* `clip`: simple clipping
* `chroma-reduce`: maximum chroma along the line of constant lightness & hue, obtained through binary search
* `culori.toGamut()`, `fuzzy` and `css-color-4-smooth` are three algorithms with minute, inconsequential variations on the theme of changing the binary search test to match "roughly in gamut" (explained below)
* `css-color-4` is the current binary search algorithm defined in the spec 

The "roughly in gamut" test changes the "in gamut" test from each step of the binary search from `if (inGamut(color))` to `if (inGamut(color) || delta(color, clipped(color)) < JND)`, which I believe to be the spirit of the adjustments suggested by the spec: when the line of constant lightness & hue hovers just above the gamut boundary, you can grab a nearby in-gamut color if it's not too dissimilar and gives you better chroma.

> The idea of adding an extra step to solutions that arrive at the exact solution "too quickly" seems inappropriate and indicative of deeper problems.

The adjustment proposed can be readily baked into the binary search, but is not at all a factor for other methods, e.g. intersecting the line with a polygonal / polyhedral gamut boundary. (Is it applicable to the Newton method? I don't have an intuition for this).

> I would like to write up the code that is also capable of finding the point on the surface of the gamut that is closest to the input point in a weighted L2 sense. […] Again, various text gives motivation for the "only change chroma" scheme, but I would want to see concrete examples where it demonstrates superiority.

Experimentally, people tended to prefer gamut mapping with ~ these weights (lightness/chroma/hue): `[1, 2.6, 1.3]` (as per my reading of Ján Morovič's _Color Gamut Mapping_), that is: chroma adjustment is most tolerable, followed by hue; people judged changes in lightness least favorably. So true MINDE with a weighted Euclidean distance in a perceptually-uniformed color space would probably give the best results, but is probably more involved algorithmically. (Morovič gives an algorithm that makes use of gamut boundary polygons of constant hue.)

Chroma reduction with constant hue and lightness is straightforward algorithmically and acceptable perceptually, but hardly 'superior' (unless you compare it to naive clipping). As @svgeesus notes, its shortcomings are well-documented. Björn Ottosson has experimented with keeping the hue constant & projecting along different lines [here](https://bottosson.github.io/posts/gamutclipping/), but evaluation was done on photographic images, which have different trade-offs. 

So we're actually talking several questions:

1. Is chroma reduction the best overall gamut mapping technique for the spec to provide?
2. Is binary search the best algorithm to express the technique? 
3. Is the 'roughly in gamut' enhancement a net positive addition to the algorithm? Can it be expressed in terms of the algorithm provided?

-- 
GitHub Notification of comment by danburzo
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7653#issuecomment-1489285544 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 29 March 2023 20:45:04 UTC