This post is about trying to find a better alternative for the current compress mode in CAM DRT. My intention at first was to compare 3-4 different compression techniques and maybe find a better alternative, but deeper I got into this, more confused I got about how the current compress mode works.
This all started as I wanted to understand why blue behaves so strangely in the Rec.709 transform, why there isn’t highly saturated blue at higher exposures at all (it’s pale blue or white), and why the blues in image like the Blue Bar doesn’t match the HDR version of the rendering (not hue or saturation). Other transforms doesn’t seem to have the same issue. This led me to the compress mode. But, trying just different compression algorithms didn’t really solve the issue.
Why compress mode?
The simplified reason for the compress mode is that the CAM’s perceptual space (let’s call it LMS space) doesn’t deal with negative values well, so chromaticities that are far out there, like they are in some extreme images because of IDTs, or with noise, will lead to skews or artifacting in the final picture. We deal with this problem by compressing the LMS space.
Here’s an extreme example of what may happen without compress mode:
Compress mode enabled:
Following image shows hue lines in chromaticity space through the DRT (input is the Dominant Wavelength ramp):
With those straighter lines the assumption is that the model now behaves better… but, does it?
Current compress mode
The current compress mode compresses the linear LMS values before the model applies non-linearity, then uncompresses the LMS values, and then the model derives the perceptual components J, M and h. Same compression and uncompression happens on the way back to RGB from JMh. This is what produces those straighter lines in the second diagram above.
But, it is this uncompression that confuses me. Why are we choosing to uncompress and likely go back to negative values? I could understand it perhaps if the intention was to return back to the original scene chromaticities. But instead the intention is to produce entirely new set of display chromaticities. Perhaps it would be better to not do the uncompression and derive the perceptual components from saner values.
Alternative compress mode
I’ve tried two alternatives. One that only compresses and doesn’t uncompress at all. The other compresses in XYZ-to-JMh and only uncompresses in JMh-to-XYZ. The results are practically identical in forward direction, but perhaps unsurprisingly, the second one inverts better. The second one is what rest of this post is about.
I’m treating this as a gamut compression, it just happens to be done in the LMS space. The idea is to reduce the negative values, then stay with those compressed values throughout the transform, and come out of the JMh space with hopefully better display values.
In all of the following examples, I am using the stock CAM16 primaries with the new compress mode. The stock CAM16 primaries actually work quite well, so I decided not to use custom ones. But we know from the past that the blue from this model can be very dark so adjustment to the primaries will be in order. However, I chose not to do that for this experiment to keep things simpler.
The compression algorithm itself is also different. The one that is currently used in the DRT, I found to compress too much in this use case, so I switched it to the ACES GC algorithm so that I can better control how much to compress. All the results are with that algorithm.
Here is the same diagram of the Dominant Wavelengths with the new compression. The lines aren’t as straight as in the current compress mode, but that is because I am not compressing as much. The lines would become straighter if compression is increased:
New mode is first image, old mode is second image. Both versions are v034.
In the Blue Bar, the blue hue is now a close appearance match for Rec.2100 hue and the saturation is a reasonable match:
This image is now a very close match to Rec.2100, which is just brighter version of this:
This image is now a closer match to Rec.2100, which is mainly brighter and more intense version of this:
The blue is clearly darker with the CAM16 stock primaries. On the other hand, this matches Rec.2100 rendering very well (the CAM16 stock primaries darken the blue in Rec.2100 also):
In testing I have found that red matches Rec.2100 red a bit better, including in these images:
Inverse is clearly better with the new compress mode. Following images show the difference to original linear cube (CMSTestPattern, exposed up by 11 stops to see the differences). NOTE: hard clamping, soft clamping and cusp smoothing has been disabled to see the differences from the compress mode mainly. Darker image is better inverse.
New compress mode, difference:
Old compress mode, difference:
A prototype version of v034 with this compress mode is available for testing in my repo. It’s named
I think the results are an improvement and so far I have not found any real issues with this approach. I think this needs to be discussed further and I am certainly looking for comments on this test. The blue, I think, is too dark with stock CAM16 primaries so it should be adjusted. I included only extreme images here, but normal images have no real differences between the modes. The differences that are there are coming from changing to use the stock CAM16 primaries, which brings darker blue as the main difference.