ACES 2.0 CAM DRT Development

I’ve had some success with my previous vague musings about limiting the gamut compressor to the spectral locus, and uploaded an experimental v037 that demonstrates some of these ideas.

Up until now, the gamut compressor (The part of the system that does the final compression down to the target display gamut (not to be confused with pekka’s chroma compressor) has always pulled from a proportion of the target gamut.

For example, if it’s set to 1.2, it reaches out to a poin in JMh space 1.2x the M limit of the target gamut at that position. This has worked pretty well, but always concerned me a little bit, as different target gamuts reached out to different points in the input space, and some sides of the target gamut have differing distances to what can be thought of as plausible input values.

This image shows the reach of the gamut compressor in the proportional mode:

The image below shows the locus limit sweeping up in J space, forming what I’ve been sort of referring to as the locus hull. This is pretty sketchy terminnology, but I’m not sure what else to call it at the moment.

From that hull, I’m sampling a set of values at a fixes J of 100, and reshuffling them so they’re evening spaced as 360 samples of h, and then declaring that as a fixed list in the blink code as LocusLimitMTable

Note: becasue this is prebaked externally, any changes to the model parameters will invalidate the location of the locus in JMh, so really this needs to be brought into the main blink init step.

This value is then scaled down with J, and a power of 0.86. which seemed to be an reasonable inital approximation of the curve we saw in last weeks meeting. (This needs improvement, but it’s a start)

Then, when we call the getCompressionFuncParams function, rather than getting a fixed value above a below the cusp, we now get the ratio difference between the surface of our target gamut, and the locus hull at that specifc J and h combination.

This shows it in locus mode:

And some others angles.


I’ve also been tinkering with a simpler chroma compress mode, just to make this exercise a bit cleaner, as the existing one in v035 pushes some values outside the locus hull during the tonemapping/chroma compression stage. So currently the SimpleCompressMode just applies a very basic M = M * ( tonemappedJ / origJ)
Looking at the results, I can see why @priikone needed to add some additional complexity to keep less saturated values in a good place. But so far I’ve been mostly just looking at extreme (but plausible) values as my input.

Also, please note, this is all a bit experimental, I’m almost certain I’ve made some errors in here. Just not sure where yet.

Image below is sRGB encoded

2 Likes