Re: [csswg-drafts] [css-color-3][css-color-4] why opacity is applied on premultiplied color ? (#7640)

When trying to simulate the compositing that a browser currently does, and you have multiple transparent images, it is important to ensure that you take all colors into consideration. Most likely, you are missing the inclusion of `white`.

Now, I'm on a mac that uses a Display P3 monitor with a Display P3 color profile. So color management of the browser is going to cause my browser's composition to operate in Display P3. So for the sake of simplicity, I'm going to force my mac to use an sRGB profile to force the browser to calculate composition in sRGB. Behavior may vary from browser to browser depending on how they implement their color management.

Here are the browser results using Safari in https://codepen.io/. This is what we are going to simulate.

<img width="614" alt="Screen Shot 2022-08-24 at 6 58 29 AM" src="https://user-images.githubusercontent.com/1055125/186425872-de32a74d-8a55-4d6c-9423-4efda67356bd.png">

Now, we have to layer our composition, not just with `rgba( 155 , 66 , 200 , 0.5 )` and `rgba( 0, 77 , 100 , 0.8 )`, but with `white` as well, as the background will be visible through both transparent colors. So we must include the `white` background into the composition. So we are actually compositing 3 colors, not just the 2 we specified.

This is applying compositing via https://www.w3.org/TR/compositing/ using `source-over`.

We'll work from the bottom up overlaying each color until we get the final composition. After we are done calculating our final color, we will apply the `div` opacity to our result and overlay it on the `white` background.

- `c3` is `rgba( 155 , 66 , 200 , 0.5 )` overlayed on `white`.
- `c4` takes `c1` and overlays it on top of the result above (`c3`).
- Lastly, `c5` applies the `0.6` opacity to `c4` and overlays it on `white`.

```
>>> working_space = 'srgb'
>>> c1 = Color('rgba( 0, 77 , 100 , 0.8 )')
>>> c2 = Color('rgba( 155 , 66 , 200 , 0.5 )')
>>> bg = 'white'
>>> c3 = c2.compose(bg, space=working_space, out_space=working_space)
>>> c4 = c1.compose(c3, space=working_space, out_space=working_space)
>>> c5 = c4.clone().set('alpha', 0.6).compose(bg)
>>> HtmlSteps([c3, c4, c5])
[color(srgb 0.80392 0.62941 0.89216 / 1), color(srgb 0.16078 0.36745 0.49216 / 1), color(srgb 0.49647 0.62047 0.69529 / 1)]
```
We can see that the final result (`c5`) matches the browser:

<img width="1213" alt="Screen Shot 2022-08-24 at 7 00 53 AM" src="https://user-images.githubusercontent.com/1055125/186425912-465e9ebb-0cdb-43da-9ec5-f40dd07e26c5.png">

Now, is there some shortcut to apply the opacity of the `div` earlier? I'm not sure. I haven't looked into to _exactly_ how browsers sequence these events, but what we are doing above is equivalent.

You can play with the results live [here](https://facelessuser.github.io/coloraide/playground/?code=import%20coloraide%0Acoloraide%2e__version__%0A%0Aworking_space%20%3D%20%27srgb%27%0Ac1%20%3D%20Color%28%27rgba%28%200%2C%2077%20%2C%20100%20%2C%200%2e8%20%29%27%29%0Ac2%20%3D%20Color%28%27rgba%28%20155%20%2C%2066%20%2C%20200%20%2C%200%2e5%20%29%27%29%0Abg%20%3D%20%27white%27%0Ac3%20%3D%20c2%2ecompose%28bg%2C%20space%3Dworking_space%2C%20out_space%3Dworking_space%29%0Ac4%20%3D%20c1%2ecompose%28c3%2C%20space%3Dworking_space%2C%20out_space%3Dworking_space%29%0Ac5%20%3D%20c4%2eclone%28%29%2eset%28%27alpha%27%2C%200%2e6%29%2ecompose%28bg%29%0AHtmlSteps%28%5Bc3%2C%20c4%2C%20c5%5D%29).

Results may vary depending on the browser, your monitor, etc. You can change the working color space to `display-p3` if yo are on a mac using a Display P3 monitor and color profile.



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


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

Received on Wednesday, 24 August 2022 13:19:38 UTC