WICG / color-api

A proposal and draft spec for a Color object for the Web Platform, loosely influenced by the Color.js work. Heavily WIP, if you landed here randomly, please move along.
https://wicg.github.io/color-api/
Other
130 stars 3 forks source link

The definiton of `xyz` in color-api vs. css-color specs #24

Closed danburzo closed 2 years ago

danburzo commented 2 years ago

In the CSS Color Module Level 4 spec, xyz is a predefined color space corresponding to CIEXYZ with a D50 illuminant. The color-api spec mentions xyz as the connection space between SDR color spaces. The README in this repo hints it corresponds to the "D65 relative CIE XYZ" color space.

Should these two definitions be harmonized?

svgeesus commented 2 years ago

Well spotted. This is nt inadvertent. Let me explain the history and reasoning.

Any SDR color conversion library is going to need, internally, a relative XYZ D50 and a relative XYZ D65. If it extends to HDR (for BT.2100 PQ, or Jzazbz, or ICtCp) it is going to also need an absolute XYZ D65. If it deals with color spaces that use a different whitepoint, such as DCI P3 or ACES Cg, it will also need relative XYZ with those whitepoints.

The question then becomes which of these to expose as an XYZ space for direct setting and for reading - for example to compute luminance, to do WCAG 2.1 contrast, and so on. A good implementation will also notice the source and destination whitepoints and avoid naively converting between D65 and D50 each time.

In CSS Color 4 I went with relative D50 XYZ, primarily for ICC compatibility and for consistency with D50 Lab; both are used as profile connection spaces in ICC v.4 processing.

In color.js all of the XYZs mentioned above are available internally; relative XYZ D50 and absolute XYZ D65 are exposed. This has the unfortunate effect that some behind the scenes chromatic adaptation is needed to get D65 luminances, for WCAG contrast computations of SVG filter effects and masking.

As you spotted, and thanks for noticing, in the color API I am thinking that a relative XYZ D65 is a more useful thing to expose. It avoids doing a CAT for contrast calculations, and for interconverting between most RGB spaces is what will be used internally.

If that turns out to be the best compromise, and given that color(xyz x y z /alpha) is not yet widely used, I would then propose either a breaking change to make it D65, or a verbose change to color(xyzD65 x y z /alpha) and color(xyzD50 x y z /alpha)

svgeesus commented 2 years ago

The existence of these various XYZ options, at least internally, is the reason for Add diagram for colorspace conversion

danburzo commented 2 years ago

Thanks for the explanation, @svgeesus.

The reasons you mention (common base for most RGB color spaces, WCAG luminance/contrast computation, etc.) point to D65 relative XYZ as the more useful of the two. I believe having the same identifier for it in color() and the Color API will help, and xyzD65 sounds too specific for most uses, so I'm partial to the breaking change in color(xyz) to refer to relative D65.

LeaVerou commented 2 years ago

There should definitely be a plain xyz, in both Color API and CSS, and it should refer to the same thing. We should also expose the other one, either xyzD65 or xyzD50. No opinions about which one to go with for the plain xyz, I’ll defer to @svgeesus for that.

tabatkins commented 2 years ago

I'm not certain xyz is supported anywhere yet anyway, and if it is (maybe Safari?) the usage is certainly low enough that changing the illuminant is fine.

svgeesus commented 2 years ago

It is supported in Safari Technical Preview and in BFO Publisher (WPT test results). But yes, it is safe to assume usage is low and confined to experimentation.

danburzo commented 2 years ago

Just an update that Safari 15 shipped last week with color(xyz) for XYZ with D50 white-point (but usage most likely nonexistent at this point)

svgeesus commented 2 years ago

Now resolved in CSS Color 4 so xyz in CSS and in the Color API will both refer to the exact same thing (2 degree observer, D65 adaptation) and also xyzd50 and xyzd65 are available, the latter being an alias for xyz.