material-foundation / material-color-utilities

Color libraries for Material You
Apache License 2.0
1.57k stars 134 forks source link

Does the HCT color model support wide gamut (colors beyond sRGB)? #131

Open FluorescentHallucinogen opened 6 months ago

FluorescentHallucinogen commented 6 months ago

I've found that material-color-utilities uses sRGB color space under the hood in many places in the code, e.g. in the image quantizer:

https://github.com/material-foundation/material-color-utilities/blob/f5d03da60c268b43928f3a24d6bf499e2564d39a/typescript/utils/image_utils.ts#L70-L75

Also

https://github.com/material-foundation/material-color-utilities/blob/f5d03da60c268b43928f3a24d6bf499e2564d39a/typescript/utils/image_utils.ts#L33

instead of:

const context = canvas.getContext('2d', { colorSpace: 'display-p3' });

This means that e.g. if we fill the whole image with any color from the P3 color space that doesn't exist in sRGB color space, then quantize function will not return the same identical color as the dominant color of that image.

E.g. OKLCH color model supports not only sRGB color space, but also wide-gamut color spaces (P3, Rec2020 and beyond). See https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl.

Technically, OKLCH can represent any color visible to the human eye.

You can play around with https://oklch.com to construct colors that can't be displayed on displays that doesn't support P3/Rec2020 or on any existing device.

It's not clear from the https://material.io/blog/science-of-color-design blog post if HCT color model supports wide gamut (colors beyond sRGB) or not?

FluorescentHallucinogen commented 6 months ago

Adding @jpohhhh, who works on color at Google, and who definitely knows the answer. 😉

facelessuser commented 6 months ago

The HCT color model is just the CAM16 color model paired with CIE Lab lightness. It can support P3 and Rec. 2020 because CAM16 and CIE Lab can support these gamuts. It should be noted that color spaces that extend outside of the visible spectrum (ProPhoto RGB) can stress the CAM16 algorithm as the geometry of the space in the blue region starts to wrap around into itself, so HCT would have similar limitations, but most reasonable gamuts should be supported. OkLCh also can experience weird distortions in its geometry when extended past the visible spectrum as well.

I've implemented HCT as a normal color space, and as you can see it can be rendered within the Rec. 2020 gamut just fine. I think this library just doesn't support gamuts beyond sRGB currently, but there is nothing limiting the potential to extend it further.

hct