Implementation Questions - Invert IDTs and more

Hello everyone,
I’m working on an application that uses ACES 1.3 for color mangement. I’ve ported the codebase to WebGL and things are looking good for the most part but I need some help with a few things that I can’t seem to figure out on my own.

The working space of the app is ACEScct. This is how I get the input signal into ACEScct:

[ Input image ] -> [ IDT ] -> [ Reference Gamut Compress ] -> [ ACES_to_ACEScct ]

Now the color processing is happening in ACEScct… and finally this is how I get the graded image out to the target color space:

[ ACEScct_to_ACES ] -> [ RRT ] -> [ ODT ]

This seems to be doing mostly what I want but here’s what I can’t wrap my head around:

How can I get a perfect inverse of, for example, the sRGB IDT, so that when both the IDT and ODT are set to sRGB_100nits_dim, the image that is piped through these transformations remains visually unaltered, except for any transformations that are applied after the IDT and before the ODT.

In other words, what I want to happen when the IDT == ODT == sRGB is exactly what happens in Davinci Resolves ACES Transform Effect: Nothing. The image should remain visually unaltered.

In my implementation, however, I’m seeing a noticeable color shift that is introduced by the IDT/ODT round trip. You can test this by loading an image into the app and long-clicking (mouse down and hold) anywhere on the image to bypass all processing.

Is this due to the RRT not being perfectly invertible that I read about a few times? Do I have an entirely wrong idea of how IDTs and ODTs are supposed to work? I’m not currently using any of the RRTODT/InvRRTODT components of the framework, might this be the missing key?

Thank you so much for your time!

1 Like

Very nice app you have there!

You are right that the RRT is not 100% invertible. But this also applies to the single stage output transforms, as the RRT is still included in those.

It does look as though what you are seeing in your app is more than that though. The invertibility issues with the RRT are only visible for certain boundary colours which get clipped. The majority of colours in a “normal” image should pass unchanged through an inverse Output Transform IDT followed by the forward version of that Output Transform. I am seeing a slight change to all values with your round trip.


Thanks Nick, that should give me some clues on what I can exclude from my bug hunt. It kind of looks like a white point issue so maybe I’m using a wrong matrix somewhere in the pipeline… I’ll see what I can find and will certainly come back with a few more questions later! Thank you!

It turns out my webGL port of the sRGB and Rec709 IDTs were not correct: They were missing the inverse RRT after their respective inverse ODT. Problem solved. Thanks a ton to @cameronrad for pointing this out in a private chat!