OCIO ramblings and Color Picking nightmare

Introduction

This page used to be part of the ACES chapter but it is so specific that I thought it would make more sense to have it a separated article. Please take with a pinch of salt since it has not been updates with my latest ACES findings. Thanks !

ACES implementation

ACES, OCIO and CTL

Most color pipelines nowadays are set through OCIO which is great because of its compatibility with many softwares : Maya, Guerilla, Nuke, Mari, Rv… But there is one downside using OCIOv1 and LUTs : you loose precision. It is really well explained in this post and also here.

The reason the CTF works better is because it is more of an “exact math” implementation of the ACES CTL code rather than baking down into a LUT-based representation.

From Doug Walker, ACES mentor.

Discrete and Continuous transforms

What is happening here ? The answer has been given to me by my colleague, Christophe Verspieren. He has showed me the concept of Continuous and Discrete that is happening with the baked LUTS from OCIO. It is actually pretty easy to understand. Check this image from this site :

015_ACES_0390_continuous_discrete_FHD
Exit full screenEnter Full screen
 

When we go from Scene Referred to Display Referred, it implies to cover a high dynamic range (ACES deals with something like 15 stops). The discrete transform actually covers huge zones.

We do not split the dynamic range into equal zones as we prefer to split in detail most current values at the expense of highlights. Therefore the display tone mapping (ODT) makes these false chromaticities really visible by increasing the exposure.

Also even if the transformation is mathematically defined in OCIO, the fact that it runs on GPU rather than on CPU leads to a discretization of the formula : the graphic card actually creates a LUT !

Really these issues are endless…

Color interpolation gaps

Furthermore, these gaps (from the discretization) are filled linearly which is not necessarily the most natural way. Even if we change gamut, we still work in RGB and linear interpolations are done on a line going from A to B. Sometimes it would be better to manage color interpolation in the Lab colorspace.

Not every mathematical formula is available in OCIO 1.1.1, only OCIO v2 will allow to represent accurately the necessary calculation of ACES.

To sum it up :

  • Between each slice we have linear interpolations.
  • In very large areas these interpolations lack accuracy.
  • This results in errors of chromaticites in highlights due to the discretisation.

How does this translate visually ? Let’s have a look at some renders with extreme saturation to compare different solutions.

015_ACES_0400_maya_arnold_ACES_configs_comparison
015_ACES_0410_maya_arnold_ACES_configs_comparison
015_ACES_0420_maya_arnold_ACES_configs_comparison
015_ACES_0430_maya_arnold_ACES_configs_comparison
015_ACES_0440_maya_arnold_ACES_configs_comparison
015_ACES_0450_maya_arnold_ACES_configs_comparison
015_ACES_0460_maya_arnold_ACES_configs_comparison
Exit full screenEnter Full screen
previous arrow
next arrow
 

Because of Arnold default settings, the base color weight is at 0.8 in these renders.

CTL nodes in Nuke

How important is this ? Should we stick to OCIO or look into this CTL implementation ? I guess the best answer I have read on this topic comes (once again !) from Alex Fry :

With normally exposed images, especially from live action cameras, you’re unlikely to see any values that render differently to the OCIO config, but with CG images containing extreme intensity and saturation you will see more pleasing roll off and desaturation.

December 2016 and Alex Fry had already understood so much stuff…

So it looks like CTL would be worth using especially if you are working on saturated animated feature films ! Alex Fry was kind enough to share with us this Pure Nuke ACES RRT & ODT. Jed Smith has also done a Nuke implementation of the ACES Output Transforms.

Please be aware that CTL is pretty much a dead language. It has not been maintained nor updated properly, as it is quite a rabbit hole.

This is the last thread about CTL that I know of. You may try it on Windows like this.

These Nuke nodes have a 100% match to a pure CTL implementation but are way faster. Please note that these nodes work with ACES2065-1 footage. Since we render in ACEScg, you will need to convert your footage with an “OCIOColorSpace” node before plugging your footage.

You can also check different examples from Alex Fry’s presentation. I don’t know if these images were generated in CTL or OCIO though. Or even using FilmLight’s Baselight… With OCIOv2, the ACES OCIO config should not present any discrepancies anymore.

The release notes for the ACES OCIO configs are available here.

ACES in render engines

Most render engines have integrated OCIO which give us access to ACES. Autodesk has even come up with a CTL integration of ACES in Maya. But as surprising as it may sound, there are different levels of integration for OCIO/ACES. And for most render engines, calculations based on light spectra are still done with sRGB/Rec.709 primaries, such as :

  • Kelvin temperatures (for lights, black-body radiation and camera white balance).
  • Physical sun & sky (or Skylight).
  • Melanin in the Hair Shader (see this Arnold release note for instance).

For example, in most render engines, the Skylight is a spectral representation converted to sRGB/Rec.709 primaries. I am quoting here the example of V-Ray :

V-Ray uses sRGB primaries by default, but this is really only relevant if you use any V-Ray features that deal with spectra – like light temperature, camera white balance as temperature, physical sun and sky. […] Normally, V-Ray treats all colors as triplets of floating point values; for the most part V-Ray doesn’t really care what the three numbers actually mean. However some calculations in V-Ray are based on light spectra; the conversion of these spectra to floating-point color triplets assumes that the three numbers mean something specific – a color in some predefined internal renderer color space. This means that when converting from Kelvin temperature to RGB colors, V-Ray must know what that internal renderer color space is.

From this post in 2016.

I am pretty sure that developers will catch up at some point. Otherwise you may simply use a 3×3 transform from sRGB to ACEScg to convert. But it is true that this final implementation step is missing in most DCC softwares.

Modifying the ACES OCIO config

I have thought for quite some time that the ACES OCIO config should be used as it is. Not at all ! There is a thread on ACESCentral that explains it really well :

It’s very common practice to make a custom config by editing the standard ACES config in a text editor. […] Not only that but recommended ! One of the goals of the ACES config has always been to be a starting point for people to tailor it to their needs.

Nick Shaw and Thomas Mansencal.

The simplest approach is to edit the “config.ocio” file in a text editor, such as notepad. You should do a backup of the original config file, then do simple edits based on your needs and requirements. Here are my personal preferences :

ACES 1.2 OCIO ConfigCustom ACES OCIO Config
color_pickingOutput – sRGBlin_srgb
color_timingACES – ACESccacescct
compositing_linearACES – ACEScgacescg
compositing_logInput – ADX – ADX10acescct
dataUtility – Rawraw
defaultACES – ACES2065-1lin_ap0
matte_paintUtility – sRGB – Textureacescct
referenceUtility – Rawraw
renderingACES – ACEScgacescg
scene_linearACES – ACEScgacescg
texture_paintACES – ACEScclin_srgb
active views[sRGB, DCDM, DCDM P3D60 Limited, DCDM P3D65 Limited, P3-D60, P3-D65 ST2084 1000 nits, P3-D65 ST2084 2000 nits, P3-D65 ST2084 4000 nits, P3-DCI D60 simulation, P3-DCI D65 simulation, P3D65, P3D65 D60 simulation, P3D65 Rec.709 Limited, P3D65 ST2084 108 nits, Rec.2020, Rec.2020 P3D65 Limited, Rec.2020 Rec.709 Limited, Rec.2020 HLG 1000 nits, Rec.2020 ST2084 1000 nits, Rec.2020 ST2084 2000 nits, Rec.2020 ST2084 4000 nits, Rec.709, Rec.709 D60 sim., sRGB D60 sim., Raw, Log][sRGB, Raw, Log]

Reasons for modifying the ACES OCIO config

Here are a few explanations on my choices :

  • I use Aliases instead of the ColorSpace’s names. I find them shorter and quite useful.
  • The color_picking role is limited to the sRGB gamut, in order to avoid any gamut clipping from the Output Transform. As far as I know, this feature will only work in Autodesk Maya though.
  • The color_timing and compositing_log roles both use acescct. It can be useful for operations such as Saturation or Sharpen.
  • The matte_paint role is in acescct due to a Photoshop workaround.
  • The texture_paint role is in lin_srgb since all my inputs/textures have a linear transfer function (by convention).
  • I have also limited the number of active views to shorten the drop-down menus (like Nuke’s viewer).

Inverted Output transform Workflow

Preserving Logos and Graphics

This topic has been addressed many many many many many many many many times on the ACEScentral forum. How do we preserve the look of an image from internet into an ACES workflow ? The ODT can be used as an IDT to do so. This process is simply called Inverted LUT.

Importing an image using the RRT/ODT is just a way to tell ACES : this image, wherever it comes from, is my final result and I want to convert it back to my working space. Unfortunately the RRT/ODT is not perfectly invertible. So what happens is (almost but not quite) a transparent round trip :

  • IDT : Output – sRGB -> ACEScg
  • Working/Rendering space : ACEScg
  • ODT : ACEScg -> Output-sRGB

A friendly reminder : you should never ever use this technique to load a texture into a shader. It has been explained several times on the ACEScentral forum.

Constant color

One of the most frequent questions I have been asked is about converting asset : how should we deal with assets created in linear – sRGB to convert them to ACEScg ?

Here is an example I had to face recently. Let’s say you work on a movie with a famous character dressed in red. Generally, the client will be very picky about this red value. It has to match !

015_ACES_0470_manual_conversion_workflow
015_ACES_0480_manual_conversion_workflow
015_ACES_0490_manual_conversion_workflow
015_ACES_0500_manual_conversion_workflow
015_ACES_0510_manual_conversion_workflow
015_ACES_0520_manual_conversion_workflow
015_ACES_0530_manual_conversion_workflow
015_ACES_0540_manual_conversion_workflow
015_ACES_0550_manual_conversion_workflow
015_ACES_0560_odt_conversion_workflow
015_ACES_0570_manual_conversion_workflow
015_ACES_0580_manual_conversion_workflow
015_ACES_0590_manual_conversion_workflow
Exit full screenEnter Full screen
previous arrow
next arrow
 

This workflow works because Nuke and Guerilla color select in ACEScg.

I have written this tutorial for a constant color because I was able to check that the converted values did not break the energy conservation. And this is why you should never do it for a texture.

Color key

I have used the “inverted ODT technique” for our next example. The challenge was to maintain the same colors from a boat concept painted in Photoshop into an ACEScg render. I know that fidelity to color keys and concepts is critical for many studios.

015_ACES_0600_playmobil_peah_boat_concept_FHD
015_ACES_0610_playmobil_peah_boat_concept_FHD
015_ACES_0620_playmobil_peah_boat_concept_FHD
015_ACES_0630_playmobil_peah_boat_concept_FHD
015_ACES_0640_playmobil_peah_boat_concept_FHD
015_ACES_0650_playmobil_peah_boat_concept_FHD
Exit full screenEnter Full screen
previous arrow
next arrow
 

This workflow works because Nuke and Guerilla color select in ACEScg.

I totally accept the fact that this concept has some lighting information. So it can become arbitrary to pick a color in one place or an other.

Hence the use of a large picking zone in Nuke.

This process has a couple of limitations :

  • First if all, if you work in ACES, you should only color pick in an ACES environment.
  • It struggles a bit with very saturated and extreme values, especially the yellow ones. You could possibly end up with some negative values.
  • If you are color picking an albedo value, you should be extremely careful that this value is within the PBR range.
  • It is not suitable for grading and motion graphics, especially with SDR imagery as explained in this post.

We can now move to more in-depth information about the Color Picking role. By default, the Color Picking role is set to Output – sRGB in the ACES 1.2 OCIO config to match the default Output Transform. This is why the Color Picking role is “contextually related” to the inverted ODT workflow.

Color Picking role

Different implementations

When it comes to the Color Picking role, the first thing to know is that all softwares are not equals regarding this feature. When a developer implements OCIO in its software, he/she can choose to integrate things to a certain level. Let’s take Guerilla and Maya as an example :

  • The Color Picking role in Guerilla only drives the color picker hue board (for display).
  • The Color Picking role in Maya drives the whole color selection process.

It only took me six months to understand the Color Picking role in Maya. But I think I have finally cracked it. First things first : what is the Color Picking role for ? From the OCIO documentation :

color_picking – colors in a color-selection UI can be displayed in this space, while selecting colors in a different working space (e.g. scene_linear or texture_paint).

This is what Guerilla has implemented basically.

But Maya has a different use of the Color Picking role. It actually uses this role to select any RGB color in a shader or a light. In this context, Color Picking could also be called Color Selection.

RGB triplets by themselves do not make really sense. You need a context to interpret them correctly. Maya lets you choose the context, when Guerilla or Nuke do not.

This is why you have to be extra careful when it comes to Color Picking or Color Selection depending on the DCC software you use.

If your ODT is different from Output – sRGB, I suggest that you modify the color_picking role in the OCIO config file to match the ODT your are using.

Your ODT and color picking role should be the same, at least in Guerilla Render.

Color Picking in Maya

Please be aware that in this section I will focus on Maya, since its integration of the color_picking role is quite unique.

When it comes to choosing a Color Picking role for Maya, I have seen three different philosophies :

Pros Cons
Output – sRGBColor selection is display-referred. It is “artist-friendly”.You do not know what it is the exact value used for rendering (unless you constantly check the Channel Editor). This could break the PBR of your scene.
Utility – Linear – sRGB“Legacy” Mode. Artists may select colors they are used to.You do not take advantage of the wide gamut in the color selection.
ACES – ACEScgYou know exactly which value is used for rendering and can reach very saturated values (like a laser).You have access to crazy saturated values, unsuitable for albedo, that may eventually break energy conservation (and clip !).

If you use (1, 1, 1) with a Color Picking role set to Output – sRGB in Maya, you actually use a value of (18.91, 18.91, 18.91) in your render. And that is very wrong if it is set in the Base Color for example !

015_ACES_0660_color_picking_maya_FHD
015_ACES_0670_color_picking_maya_FHD
015_ACES_0680_color_picking_maya_FHD
Exit full screenEnter Full screen
previous arrow
next arrow
 

It is true that when you use “Output – sRGB”, you are never really sure of what color is being used during rendering. And this is why some studios have set their Color Picking role to ACEScg to know what values are used by the render engine.

I cannot honestly say that one system is better than the other. You just have to be aware of what you are doing. If you’re interested by this specific topic, I would suggest the read of these three threads on ACESCentral.

Color Picking in ACEScg

If you use ACEScg as a Color Picking role, you should be aware of this : there is no non-emissive surface that has such saturated colors. Only lasers (an emissive source) can reach BT.2020 primaries.

This particular example really made things clearer for me. When you study color science, you may sometimes get lost in abstract stuff. Knowing this made all of these concepts more grounded and more real in a way.

If you want to Color Select in ACEScg, you just need to edit the OCIO Config and modify the color_picking role :

roles:
  color_picking: ACES - ACEScg

If you are working in a realistic context, all of this concerns you. And if you are working in cartoon… Well it concerns you as well ! Some producers out there just like the most outrageous saturation. But most cartoon movies want to be believable in their look. So my advice is to do your look development in a realistic way and you will still be able to push saturation with a grade afterwards.

All of this only stands for a PBR cartoon movie of course.

Conclusion

We have mostly seen three topics in this article :

  • OCIO and precision issues : this should be most likely fixed with OCIO v2, even if it hasn’t been implemented in all softwares yet (yes, I am looking at you Rv !)
  • ACES in render engines : I would not recommend to developers hardcoding colorspaces in their softwares. This should be OCIO based.
  • Color Picking and Inverted LUTs : we have seen that this is a very confusing topic (hopefully a bit less now) and that is mainly for two reasons. First, lack of guidance from OCIO in their docs and second, poor implementation by the softwares’ developers.

In the latest ACES configs, there was lots of debates about roles. And hopefully in the near future we could invite developers to align their implementations. Because otherwise roles would become pretty much useless ! One may dream eventually…