[csswg-drafts] [css-color-4] Premultiplication in cylindrical spaces and mixing (#11238)

raphlinus has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-color-4] Premultiplication in cylindrical spaces and mixing ==
The current spec describes [premultiplication](https://www.w3.org/TR/css-color-4/#interpolation-alpha) as not multiplying the hue component in cylindrical spaces. I think I understand the motivation of that for doing interpolation and gradients, but it does not seem to be the correct logic for doing mixing and compositing. I'm wondering what implementations should do, and specifically whether there need to be two forms of premultiplication, one for lerp, one for mixing.

The basic rule for `x over y` in premultiplied spaces is `x + (1 - x.alpha) * y`. But this breaks down for cylindrical spaces premultiplied as per the spec, as the sum of the weights on the hue components exceeds 1. (It's not a problem for lerping, as the sum of weights is always 1)

Another way of phrasing this is that the premultiplication method in the Color Level 4 draft mismatches the [definition of premultiplication](https://www.w3.org/TR/css-color-5/#color-mix-with-alpha) for `color-mix` in Color Level 5, which does not make an exception for hue.

I can think of several ways of dealing with this:

1. Simply forbid compositing in cylindrical spaces.
2. When compositing in a cylindrical space is requested, actually do it in the associated rectangular space, for example oklab when oklch is requested.
3. Define the `over` operation as `(x.hue * x.alpha + y.hue * y.alpha * (1 - x.alpha)) / (x.alpha + y.alpha * (1 - x.alpha))` for the hue component.
4. Have `PremulColor` and `LerpPremulColor` as separate types, with the former premultiplying all components, and the latter holding out hue.

One reason that choices (1) and (2) are on this list is that I'm not sure how useful it is to do compositing in a cylindrical space. I'm happy to be pointed to evidence on this.

The difference in behavior seems subtle, and it's not obvious to me that the CSS specified behavior is clearly more better or more correct than the simpler, compositing-friendly behavior. I searched for discussion where this was decided and couldn't find it. I can generate color ramps to illustrate the difference if that would be useful.

For context, this came up when we were starting to contemplate a `color_mix` method in our new Rust [color](https://github.com/linebender/color) crate. My original hope is that the `PremulColor` type we defined for CSS Color Level 4 interpolation would also efficiently support mixing/compositing, but that is not looking hopeful at the moment.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/11238 using your GitHub account


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

Received on Monday, 18 November 2024 23:45:17 UTC