HDR, WCG and Oklab support
I recently used pally to demonstrate some of the fun things the RetroTINK-4K is doing, where it takes some of the out-of-spec values produced by the NES and maps them into BT.2020+PQ to show them in HDR. To demonstrate that, I had to remove a few lines within pally that dealt with clipping, print the RGB triplets out, and then write some custom python using colour-science and OpenImageIO to generate the colours and frames in wide colour gamut and high dynamic range.
Article is here:
- https://www.retrorgb.com/hdr-and-the-naughty-nes-a-technical-deep-dive.html
Videos showing the results are here (you will need a HDR capable app/browser/computer/phone/TV to see them properly):
- https://www.youtube.com/watch?v=2o7duWqB1QQ
- https://www.youtube.com/watch?v=8i2owtfK9qA
If you're interested, I'd like to try to contribute some extra features to pally, including:
-
Changing some of the early clipping behaviour. The python colour-science modules are fine with RGB values outside of the 0.0-1.0 range, and don't need to be clipped so early in the process (this can be done right at the very end). The default RGB channel clipping also has negative effects on hue changes, which leads me to the next two items.
-
Adding Oklab (more specifically Oklch) scaling. The default clipping in RGB colourspace results in huge changes. The included darken/desaturate scaling options are a better option, however Oklab/Oklch do a better job again at maintaining perceptual uniformity when manipulating colours than darken's RGB clipping or desat's YUV scaling (and OKlab/Oklch are supported by python colour-science). From what I can tell, the included darken/desat modes also appear to only change individual colours that are out of spec, and does so uniquely per colour, which then leads to a relative brightness change compared to the rest of the palette. An option to find the furthest out-of-spec colour and then scale all colours by that ratio (so they all maintain relative brightness differences to each other) might be nice. I'd like to add 4 new options all up using Oklch - oklch-darken-all, oklch-darken-affected, oklch-desat-all and oklch-desat-affected. More on Oklab / Oklch here:
- https://bottosson.github.io/posts/oklab/
- https://en.wikipedia.org/wiki/Oklab_color_space
- Add BT.2020 / Display-P3 output support, including HDR EOTFs. From what I can tell, the early clipping and calculations impact the final output, so even specifying these colourspaces (either via colour.RGB_COLORSPACES or manually with xy co-ords) ends up with values that don't extend into their gamuts. The resulting output image file is always sRGB SDR, and EOTFs appear limited to gamma power law functions only. I can potentially look at outputting images via PNG version 3, JPEG-XL, AVIF, and perhaps even JPG with UltraHDR gain maps, and EOTFs like SMPTE-2084/PQ and HLG (maybe via PIL/Pillow if it supports these, maybe using OpenImageIO if not). None of this helps with .pal format NES palettes though, which are always assumed to be 8bit SDR. But I'm hoping emulator authors can potentially utilise these features in future projects as HDR displays continue to become more common.
Keen to hear your thoughts, or if I've gotten any of my base assumptions wrong. I also need to experiment a bit with Oklab/Oklch to see if a hybrid darken+desat can be done instead of just forcing one of two options.