color-js / color.js

Color conversion & manipulation library by the editors of the CSS Color specifications
https://colorjs.io
MIT License
1.91k stars 82 forks source link

Refine rec2100-pq support for Chrome Canary (rec2020 Experimental Feature in ver108+) #274

Closed mdrejhon closed 1 year ago

mdrejhon commented 1 year ago

Hello,

My current version of color.js I'm trialling doesn't seem to support rec2100-pq, and there is no instructions for: https://colorjs.io/docs/output.html

I am developing a HDR version of TestUFO (www.testufo.com) and some of the display motion-blur-performance tests require a color picker, such as www.testufo.com/chase amongst 30 other selectable tests at upper-right corner;

I am making it compatible with Safari "display-p3" and Chrome "rec2100-pq" (Canary support).

It kinda works but I need a color picker polyfill.

What's the ETA for rec2100 (rec2020 colorspace) support (via "rec2100-pq"), or is this already slipstreamed into the dev version (I couldn't tell, from searching around)?

I'm already blitting rec2020 .avif's to rec2100-pq <CANVAS>

Sincerely Founder of Blur Busters / TestUFO (World's most popular site for testing "Better Than 60Hz" displays)

mdrejhon commented 1 year ago

For those unaware of how I'm creating rec2020 canvas in Chrome Canary, I have to go to chrome://flags and enable "Experimental Features"

Then I do this:

 // Create HDR canvas in Chrome Canary "Experimental Features ON" (rec2100-pq, Canary 108 or later)
surface = canvas.getContext("2d", {colorSpace:'rec2100-pq', pixelFormat:'float16'});
canvas.drawingBufferColorSpace = 'rec2100-pq';
canvas.unpackColorSpace = 'rec2100-pq';

Works beautifully, and HDR AVIF sprites work fine in rec2020 colorspace.

Now I'm missing a rec2020-optimized color picker for things like background fills. Some HDR draw commands are missing, so I sometimes have to hack solutions, but I need the corresponding color picker.

While it hit the canvas first, they're also adding this colorspace to CSS eventually (buzz currently ongoing in various Chromium tickets), so best to prep color.js and use me as an early canary (pun) for a rec2020 colorpicker because I'm probably going to be first to release a web-based HDR display tester in mere weeks.

I had intended temporarily hacking it with the existing CSS color picker + a 2nd pulldown for a HDR multiplier (something loosely akin to the Krita colorpicker for editing rec2020 AVIF files, or the ), but that's an ugly hack.

I'd prefer to use color.js if this is a quick improvement or already has support in an undocumented manner.

Alternatively, developer instructions on how to modify color.js to work nicer with rec2020 colorspaces, would be welcome! Since I am protecting for mutli-colorspace support (due to Safari vs Chrome divergence in preferred HDR colorspace).

Color sharing note: I am somewhat flexible with adapting to how color.js decides to standardize HDR and WCG but I do have some specific needs. Color values inside TestUFO URLs are shareable across the Internet (e.g. "https://www.testufo.com/chase#background=C0E0FF"), I will also need to "share" a selected WCG color between Safari and Chrome (with automatic clipping whenever a specific test is shared containing color values outside a target computer's browser support, and the ability to display a warning that a color was clipped). So I will need to encode data (probably as comma separated CIE XYZ values for sharings' sake between display-p3 browsers and rec2020-pq browsers, still making a final decision). And still be able to load them into the color.js color picker. It would be nice to colorpicker color values outside the users' system ability (as long as I can highlight whether it's inside/outside the current systems' color gamut). But I am also OK if the color picker is unable to select a color outside the current systems' colorspace, but need to be easily be able to load a different systems' color picker value and correctly automatically clip (while also warning the recipient users loading the shared URL, that the color had to be clipped). So I need a unified normalized transport like pulling generic CIE values as an interim before converting to local colorpicker format like display-p3 or rec2100-pq

Help?

Crissov commented 1 year ago

No helpful answer here, just someone wondering what’s the deal with the -pq suffix?

https://w3c.github.io/csswg-drafts/css-color-4/#predefined-rec2020

facelessuser commented 1 year ago

@Crissov It's not just the suffix, the entire name is different from Rec. 2020. Notice the number is different (rec2100). This is an HDR color space that transforms the SDR Rec 2020 color space. There are two such color spaces defined under Rec. 2100: https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-E.pdf.

The spec defines two HDR color spaces, one that uses "Perceptual Quantization" (PQ) and the other that uses "Hybrid Log Gamma" (HLG). Because of this, the prefixes are needed to distinguish which Rec. 2100 color space you are talking about. Check out the documentation to learn more.

mdrejhon commented 1 year ago

No helpful answer here, just someone wondering what’s the deal with the -pq suffix?

Theres "rec2100-pq" and "rec2100-hlg".

TestUFO HDR is currently going for "rec2100-pq".

facelessuser commented 1 year ago

It seems just doing this in CodePen works. I'm not sure if all packaged releases register it by default, and if not, I'm not sure how to register unregistered plugins as the documentation doesn't explain it well.

import Color from "https://colorjs.io/dist/color.js";
console.log(new Color('red').to('rec2100pq'));

One thing to note is that the ID uses no hypen before pq, but the CSS ID used for CSS strings does. It's a bit confusing.

mdrejhon commented 1 year ago

Excellent catch on this hyphen-free inconsistency! That'a a bleep worthy moment, from fruitless coding and research attempts.

This somewhat tripped me up, figuring out whether I could insert/pull rec2100 values from color.js with a conversion step, since HDR in browsers is just so brand 'flippin new.

Let me give that a try and see how much I can "workaround it" to my requirements.

Since this just landed only recently (Canary 108+, not even Beta 108+ and only behind "Experimental Features" flag), documentation will need to be improved (everywhere, not just here) due to Chrome Canary's support for rec2100-pq with the hyphen....

Not to mention that Safari and Chrome went different directions in supported HDR colorspace framebuffer formats. Not even a commonalty of one HDR framebuffer format I can use on both. Whoopee.

@LeaVerou et al -- might be a good idea to modify color.js to add the hyphen, to align with what the gorillas are doing (Google and Chrome). Or make it hyphen-agnostic for legacy compatibility too.

facelessuser commented 1 year ago

Yeah, in case it wasn't clear to anyone, color.js does support the namerec2100-pq with a hyphen, but only for CSS input/output. The color space ID uses no hyphens.

> const { default: Color } = require("colorjs.io");
undefined
> let color = new Color('red').to('rec2100pq')
undefined
> color.toString()
'color(rec2100-pq 0.5325 0.327 0.2201)'
> let color2 = new Color(color.toString())
undefined
> color2.toString()
'color(rec2100-pq 0.5325 0.327 0.2201)'

I know this has tripped me up multiple times This exists with other spaces as well, like Display P3. You just have to remember that the ID may not always match the CSS ID.

> new Color('display-p3', [1, 0, 0])
Uncaught TypeError: No color space found with id = "display-p3"
    at Function.get (/Users/facelessuser/Code/github/color.js/dist/color.cjs:610:11)
    at new Color (/Users/facelessuser/Code/github/color.js/dist/color.cjs:3991:28)
> new Color('p3', [1, 0, 0]).toString()
'color(display-p3 1 0 0)'
mdrejhon commented 1 year ago

Thanks.

Renaming this github as a discussion for any refinements needed / documentation needed, in order to sync better to Chrome in future. Now that we better know early hints of Google's HDR intent.

mdrejhon commented 1 year ago

I think I am now able to use color.js as part of TestUFO HDR. Keep tuned.

About the color sharing solution

As long as I pull generic WCG data (e.g. CIE xyz's), I can forgo the final destination-system gamut until actually loaded by the user loading a shared URL, given color.js supports both Safari's "display-p3" and Chrome's "rec2100-pq". So I think I might have solved the color-sharing problem -- and I can at least detect if a shared color is out-of-browser-supported-gamut by various means.

(Outside of display-supported is a different problem altogether, but I'm more concerned about outside-of-browser-framebuffer-supported which is something I DO have more control over, e.g. Chrome user sharing a color out-of-gamut on Safari -- and at least displaying an alert to this effect).

I might run into other blockers, but I think I went past the major one. I will follow up with my experience using rec2100-pq into this, as time passes.

Also please excuse my terminology etiquette (e.g. the nuances of "HDR" versus "WCG" terminologies). If I make an error, please feel free to correct my terminology. I am still relatively new to HDR programming

svgeesus commented 1 year ago

The name rec2100-pq is from the CSS Color HDR unofficial draft, and is also used in the HDR Canvas proposal

svgeesus commented 1 year ago

Closing the loop, color.js has had rec2100-pq and rec2100-hlg for a while now. They are listed in Supported Color Spaces