Preserving the look of sRGB graphics

I will be pedantic but it will be unchanged in the limit of the inversion capabilities of the system, i.e. the red modifier is not fully invertible.


Yes, that’s it Nick. Again you’re right.

For a short moment I thought that could even help with my Cinem4D Problem discussed in another thread. But when passing through the inverses everything above 1 get clipped of course. As we are now coming from a display referred file. Even if that EXR file has values above 1 they get clipped this way. Which is correct.

So perfect solution for my asked problem. Would really be great if that would be included in opencolorio, So I could avoid that detour through resolve when compositing with displayreferred footage in Aftereffects.

Thanks again, Nick.


Ha! I did wonder about qualifying my answer.

While the transform is not completely invertible, because the pipeline passes the image back through the forward transform after inversion, the effect is for the total operation to be very close to transparent. If you pass a set of colour bars through this process, they will not hit the targets perfectly, and the PLUGE will be clamped off. But for normal images, the error is not visible.

Yeah! :slight_smile: That is why I tagged myself as pedantic :innocent:. I thought it would be important for the record to make that note on the invertibility. Speaking of which, difference of Ampas Goldens syntheticChart.01.exr and syntheticChart.01_from_InvRRT.exr:



1 Like

Agree with Peter, this would be particularly useful when adopting ACES in a commercials pipeline.

In lieu of official support in the OCIO config, does anyone have a recipe for applying the inverted RRT/ODT in Nuke?

You can do it with OCIO. Just use an OCIOColorSpace node, and choose Output - sRGB as the input colour space.

This screen grab shows how a small amount of the extremities of the RGB cube is clipped by the backwards/forwards transform, but frankly you are unlikely to want to have such extremely saturated colours in your original sRGB image.

Actually, looking at it further, yellows do get quite badly desaturated by this process. I will do some more detailed testing tomorrow.

Thanks Nick - that’s a great tip.

A few quick tests suggest it’s likely to be good enough for a majority of uses. Much better than eye ball counter grading.

I checked with OCIO in Aftereffects and that works, too. Strange - why do the output transforms work as input transforms? Probably I haven’t understood how OCIO works :slight_smile:

For my custom made test scene that I checked yesterday with Resolve that works well. But as Nick mentioned possible problems with yellows I took a packshot that has many bright yellow text in it. And that gets totally wrong. Much too dark yellows and even in the white parts there comes some dark pixels from the render that are not visible in sRGB. So like Ben said: Can be a big help, but obviously it cannot be really inverted without loss.

Some of the transformation can be inverted automatically by OCIO (MatrixTransform, 1D FileTransform ones, etc…), for others you can specify the inverse, which is the case for some of the OCIO ACES colourspaces thus they work bi-directionally.

I just wanted to let you know, that I had a mistake in my chain of transforms in Aftereffects. The inversion seems to work better than I thought before.

I can even preserve values over 1 if I put the inverse RRT/ODT as last step in the chain.

Great help on the way to a some day pure ACES workflow :slight_smile:


Just wondering if you found anything for this yellow desaturation issue ? Is there a dedicated discussion somewhere about that topic ?

I did some tests myself to understand more precisely how and where this happens, using InverseODTRec709 -> InverseRRT -> RRT -> ODTRec709 on image with saturated yellows, eg. from logos / titles (from what I recall the “Global desaturation (inverted)” in the InverseRRT can produce out of AP1 yellows that get lost by the clamp right after), but didn’t have the time to go any further.

From what I understand the RRT/ODT Rec709 can’t produce yellow with maximum saturation in the first place so we cannot expect the Inverse process to preserve all that but maybe there is a way to have a more controlled desaturation ? Also I find it interesting that this is mostly visible only for yellows.

I’ll upload a kit for Affinity in a bit that solves this issue to some extend. I’ve successfully used it to convert a few sequences to something usable. Then put them into Compressor to get ProRes conversions that matched the colours in Nuke. It’s not a 100% solution for everything. But what I’ve used it on worked for me.

Doing a bit of documentation writing right now.

EDIT: It’ll have to wait. Somehow I managed to break the Library and thanks to Sandboxing I can’t find what to delete so it can start over again.

I’ve uploaded a sparse version of it (due to binary leakage) here with a few notes how to install and how to use it.

1 Like

I’ve recently done tests with a variety of ‘target device gamuts’ such as Rec709/1886, P3 DCI, P3 D60, Rec 2020 etc. I’ve plotted out the boundaries and there are certainly limits imposed by the RRT/ODT combinations which restrict which colours can be reproduced, when starting from the ACES AP1 (or AP0) “gamut” (not really a gamut per se). As one would expect the wider the target gamut the greater the range of colours that cannot be created (the more the RRT/ODT limits).

This is kind of a natural outcome of the ACES image rendering and is something I’m hoping will be looked at in the next revision of ACES.

My desire was to facilitate device dependent image manipulation such as graphics insertion/maximising the available output gamut for creative freedom.




I would like to ask a question related to this. When rendering textured CG elements I can obviously convert the textures to ACES with the “Utility - sRGB - Texture” however they come out a bit ‘darker’ so I though we could use the inverse display transform be it Output - sRGB or rec.709. This however produces overbrights for sRGB values about about 0.81, great for mattes but not so great albedo textures.

So, has anyone any pointers on texturing workflows that preserve the appearance of the source texture better than “Utility - sRGB - Texture” ? I’m also open to accepting that sRGB textures will just be darker.


Hi John,

There should be no surprises here, if you pass a texture in domain [0, 1] through the RRT + sRGB ODT you will approximately end up in range [0, 0.8].

The ACES system is meant to work with scene referred values as input, which means you need plausible reflectance values to feed your shaders. There are only very few things in the world that have close to 100% reflectance, e.g. Magnesium Oxide approximately 97.5%, Spectralon over 99%. Snow can reach 90% and is around 80% in Antartica.

So the question you need to ask yourself is what that texture represents, if it is meant to be lit and represent reflectance values, it simply can’t go over 100% and a practical limit is 90%.

Here is a chart with some examples values (RGB are the linear ones):

If you are doing physically based rendering, I think it is part of the game :slight_smile:

It is also possible to apply a rolloff after the inverse display transform but you will never get perfect result. Here is a function I use often for that kind of tasks:




Hi Thomas,

Certainly no surprises, it’s good to get some confirmation. We had used SPI’s anim config for a while and there was a transform there that was visually similar to the inverse of the viewing transform suitable for textures but moving to ACES I think we’ll go with “Utility - sRGB - Texture”as it is intended.

Thanks Thomas!


Since we use substance painter/Mari ,it is PBR already texture tool right?
For example , i set the basecolor to ‘‘Dry sand’’ RGB linear to 0.4, then i load the basecolor texture in maya and set the colorspace to “Utility - sRGB - Texture”, but it dark the basecolor texture again , make it lower than 0.4, does this break the PBR workflow? cause i already set plausible values to the basecolor but ACES make it darker .

THis is the main thing make me confuse about ACES “Utility - sRGB - Texture”
We now use “Output - sRGB” to preserver the value.

Karas, I just released two filters to deal with this within Substance Painter (and Designer).
“Output - sRGB” is the IDT to use for preserving the tonal range but as you noticed value 0.81 in source texture will be remapped to 1 and values above that (0.81-1.0) fully lost.
“Utility - sRGB - Texture” IDT will make everything darker unless you create your maps from scratch under a display referred view transform like “Output - sRGB”.
With the filters you have both ways while working in Substance Painter. For the “Output - sRGB” IDT I made sure that the inverse RRT fell right into PBR range.
Have a look here, in the next days I will properly make a full post in ACESCentral, so I can get some feedback.