I see that my screen is capable of both when I open them in Chrome.
I do not understand exactly why these are different things. I have been looking at other posts here and at google / gemini results but would appreciate some expert input here.
My understanding is P3 means wide gamut, so I get more hues to display, while hdr means brightness, so I can i can make the hues pop of the screen until my eyes burn.
If I think in terms of a color model like HSL, it’s easy to map wide gamut to the H and HDR to the L.
I know it’s a really complicated topic but if someone can point me to a good primer to understand the difference between the two and why it seems that I cannot have both at the same time (from looking at the two separate examples above).
I’d adjust the HSL analogy a little: wide gamut maps better to saturation than to hue. P3 primaries sit further out, so reds and greens that sRGB can’t reach become possible, while every hue already exists in sRGB. HDR is luminance above SDR white. The reason the two demos look exclusive is one line: webgl_test_wide_gamut sets renderer.outputColorSpace to DisplayP3ColorSpace, webgpu_hdr sets it to ExtendedSRGBColorSpace with a HalfFloat output, and a renderer has one output space. Also watch for a third meaning of HDR. In my own scenes I render into HalfFloat targets, so values above 1.0 exist, but ACES tone mapping squeezes them back into sRGB at the end. That’s HDR rendering, not HDR display.
Thanks! Does this mean I can set outputType: THREE.HalfFloatType on the renderer with outputColorSpace = DisplayP3ColorSpace and I will get both wide gamut and HDR display?
What should I do about the tone mapping to not squish everything back into sRGB?
Personally I avoid using the term “HDR” when describing the precision of render targets. Clearer to say “half float” or “float16” instead, because numerical precision is unrelated to the messy “luminance above SDR white” concept deployed in HDR images. But of course, it is true that you can’t push display values above 1.0 without also using a floating point format.
Does this mean I can set outputType: THREE.HalfFloatType on the renderer with outputColorSpace = DisplayP3ColorSpace and I will get both wide gamut and HDR display?
No, DisplayP3ColorSpace implies outputs in the [0,1] range. That combination just gives you higher precision color in a wide-gamut space, which is useful, but different than HDR. (And IMHO more useful than HDR).
three.js does not include tone mappers that target wide gamut or HDR color spaces today. If you’re doing lighting-based rendering then you really do need a tone mapper, so unless you’re comfortable trying to build your own or adapting an existing tone mapper, I might stick to sRGB output. Writing a tone mapper that targets a wide gamut color space is a reasonably well-defined problem to solve, and I’d encourage folks to try that! Writing a tone mapper that targets an HDR color space (or wide gamut and HDR) is not, we can’t predict the perceptual outcome reliably (other than burning eyes), so I’m less optimistic about that. I’m not a huge fan of HDR as a technology, honestly.
That said… if you don’t care about lighting-based rendering, and so are able to skip tone mapping, or you just want to play around with the technology and see what happens… you could try patching in a P3 equivalent of ExtendedSRGBColorSpace. This would require Chrome 155-156+, with support for srgb-linear and display-p3-linear.
EDIT: Though come to think of it… the new Chrome r155-156+ release might change how the webgpu_hdr example in three.js need to be implemented, I think we could do without the special “Extended” color spaces now…
Thanks so much! For now I don’t care about lighting-based rendering, so by the looks of it I should be able to play with the next release and the latest Chrome. Looking forward to it!