0

OCIO customization

Several of us in the beta group have been discussing how to use OCIO in RV, and pitfalls we've run into. Alan suggested that others may find this info useful, so this is an unofficial forum thread to gather our thoughts together in one place.

OpenColorIO (OCIO) is a library developed at SPI and subsequently released as open source that centralizes color management. The OCIO website is a bit daunting to read through, and the file format isn't much clearer, but a simple way to think about OCIO is that it's a list of named color transformations that go to and from a reference space. This is sort of like how FedEx routes everything through a hub. In OCIO, the hub is the (usually linear) reference space. Once you've set up your transformations to and from the reference space, OCIO does all the work of generating LUTs on-the-fly that transform between your color spaces. Software that integrates OCIO can forgo using LUTs altogether by delegating all of the color details to OCIO.

How RV uses OCIO

RV has a single OCIO node type that can perform the role of "color" , "look", or "display". "color" is usually used in place of the usual RVLinearize node, "look" in place of the RVLookLUT node, and "display" in place of the "RVDisplayColor" node. Depending on the mode of the OCIO node, different properties are available. RV ships with a replacement source_setup package (ocio_source_setup) that allows you to switch back and forth between OCIO mode and RV-native mode in the RVLinearizePipelineGroup and RVDisplayColorGroup parts of the RV pipeline. It's as simple as disabling source_setup and enabling ocio_source_setup in the package manager.

Caveats

The linearize portion of this setup works great, but there are a few problems with the display portion. More and more, shows have per-sequence, or even per-shot LUTs or CDLs. And of course, supervisors want the option of viewing shots in the same color space in which they will be approved by the client. However, since displays are shared between sources in the default ocio_source_setup.py, it's not possible to use the Stack or Layout modes to compare different shots that have different display LUTs. Second, late in the beta period of 4.0.11 it was discovered that using the "display" mode of an OCIO node in place of the RVDisplayColor node causes the display to be blurred.

Solutions

Chris Mihaly at Disney hit on the idea of using an OCIO node in "display" mode in the RVLookPipelineGroup to solve both of these problems. We've also switched to this method, and are finding the side effect of per-source "display" color spaces so useful that we probably won't switch back to using the RVDisplayColor pipeline.

I've attached two modes, our modified ocio_source_setup.py and shotgun_ocio.py, another mode we use that sets context variables in ocio_context based on the source's sequence and shot (via Shotgun). ocio_source_setup.py is (I think) identical in behaviour to the official ocio_source_setup.py, except that it uses the RVLookPipelineGroup instead of the RVDisplayPiplineGroup for display. shotgun_ocio.py is pretty specific to our workflow, but others may find it useful as a starting point.




ocio_source_setup.py
shotgun_ocio.py
shotgun_fields_config_custom.mu
ocioconfig.py
rvocio_source_setup.py

9 comments

  • 0
    Avatar
    Chris Mihaly

    So as Mark mentioned, we switched to using the OCIOLook for our OCIO Display.  The original issue we hit was many of the display options that are not OCIO related were disabled (R, G, B A views, etc) and we needed to apply different OCIO configurations for multiple sources in a layout.  We then noticed that OCIODisplay was doing something to the image, so that was a surprise gain.

    1. We only use OCIO on EXRs only, so this basically enables OCIO if the source is an EXR and disables it otherwise. So, if any of the sources on the current frame are EXRs than we enable OCIO menus and disable the RV Linear to Display options.  If none are EXRs than we disable the OCIO menu options and enable the RV Linear to Display options
    2. This has the benefit that we can now use the R, G, B, A channel view modes which we really do use a lot.
    3.  Our EXRs are already in linear space, so we do not use the OCIOFile node pipeline
    4. We moved the OCIO options to the end of the View menu.  These options also looks at the  OCIO Look nodes.
    5. We put in a few context variables that we search for tonemaps for (we have basically a show tonemap that we use mostly, but occasionally a shot will need a slight tweak and we will put a tonemap in the shot area.  The EXR have attributes disney/d_show_name, disney/d_seq_name and disney/d_show_name.  We actually look for the parameters in the OCIO Config search path and look for properties in the EXR.
    6. We do handle the d_show_name specially.  If they are there, then we use the tonemap View/Look in the OCIO config, otherwise we default to the Gamma2.2 view/look.  Most of our exrs from shot renders will have that parameter and will need OCIO with tonemap.
    7. It got around the image distortion in OCIO Display, but we actually did this so we could apply a different tonemap on two EXR clips in one layout (via the search path) and we wanted the View options back.
    8. It also allowed us to have two sources with different OCIO config settings so they picked up different tonemaps.  

    This does have a few limitationl

    1. The output of the source pipeline is now in display space not linear.  That hasn't been an issue for us
    2. if your layout has a mix of EXRs and non EXR, you can only configure the OCIO EXR clips.  We generally do not do this, but is an issue.  
    3. We cannot set the display/view for each source if more than one source is in the current frame.   We don't believe this will be an issue, if it does, we could switch to a dialog that allowed per source setup.

    I also added a python utility wrapper we use around OCIOConfig which caches OCIO configurations and also provides a few helper methods.  This version does a few things (and there are definitely a few Disney studio specific workflows in it):

    Files attached at top in original post (rvocio_source_setup.py and ocioconfig.py)

  • 0
    Avatar
    Pierre Augeard

    Hello,

    Thank you for the in-depth explanations and source examples.

    Is there a way to apply a lut only described by a file path? Like the OCIOFileTransform nuke node. Or directly with RV nodes: commands.readLUT(path, node); set_int(node, "lut.active", 1); commands.updateLUT()

    It seems it could be achieved through an OCIO look. Unfortunately, I haven't found any example regarding the ocio.function = look mode. OCIOSourceSetupMode.useLookOCIO is defined but nowhere used. What should be put in the ocio_look.look property?

    Finally, rvocio_source_setup.py shows how to use the ocio_context component, but it's not present at all in the default  ocio_source_setup.py implementation. Is it mandatory? Something specific to Disney Studio?

    Thanks again,

    Pierre

  • 0
    Avatar
    Tobias Pfeiffer

    Hi Alan,
    thank you for responding that fast!
    Nuke f.e. is running pretty well with an "out of the box" OCIO config that specifies shot based LUTs/CDLs, but that's an easy task because you are usually dealing only with a single shot at a time inside of Nuke (and vRay, Mari, you name it...).
    RV, as you already know, has to tackle with the fact that you are likely to view different shots / plates / elements together - even wiping between them should be possible.

    The two main questions we have prior upgrading to RV4 are:

    •  Will we be able to load shot bases LUTs per source. Especially different sources per RV session!
    •  Will we be able to wipe/stack/compare them with different LUTs applied

    And of course, how much effort do we need to put into it to make it work.

    Right now our OCIO config (mainly for Nuke) depends on env vars for SEQ and SHOT to load the correct LUT. Simply changing these env vars at runtime (to change context) didn't work with the standard OCIO implementation of Nuke. Should be the same for RV4, right?
    That means we need a different approach for applying shot based LUTs in RV. Seems like extracting scene and shot from source paths should work best for us. Depending on metadata - like Disney does - is not preferred for us.

    We had a look at your ocio_source_setup.py and the Disney modified one, but are not sure where and how to implement the shot based LUTs handling.

    Maybe you can shine some light on it for us or point us to a resource that covers these apsects.

    Thank you again.
    Best,
    Tobias

     

  • 0
    Avatar
    Alan Trombla

    Hi Tobias,

    Nuke f.e. is running pretty well with an "out of the box" OCIO config
    that specifies shot based LUTs/CDLs, but that's an easy task because you
    are usually dealing only with a single shot at a time inside of Nuke
    (and vRay, Mari, you name it...).


    Right, RV should work the same way for a single shot.

    RV, as you already know, has to tackle with the fact that you are likely
    to view different shots / plates / elements together - even wiping
    between them should bed possible.


    Indeed!

    The two main questions we have prior upgrading to RV4 are:

    Will we be able to load shot bases LUTs per source. Especially different
    sources per RV session!

     

    Will we be able to wipe/stack/compare them with different LUTs applied


    Yes, and yes.  You just need to be sure that all the OCIO processing is "localized" to the SourceGroup.  OCIO nodes you insert into the SourceGroup will be "per-shot" but if you put an OCIO node into the DisplayGroup, it will (obviously?) apply to all loaded media.

    You might want to review the default RV graph structure here:

    http://www.tweaksoftware.com/static/documentation/rv/current/html/rv_reference.html#Chapter_2_Image_Processing_Graph

    And of course, how much effort do we need to put into it to make it work.


    Not much ?  It'll just depend on how complicated your setup is.  You guys have lots of python expertise, right ?  And some RV plugin experience ?   My guess is not much work.

    Right now our OCIO config (mainly for Nuke) depends on env vars for SEQ
    and SHOT to load the correct LUT. Simply changing these env vars at
    runtime (to change context) didn't work with the standard OCIO
    implementation of Nuke. Should be the same for RV4, right?


    Right, the "context" variables you see in the config file look like environment variables, but it's important to remember that they are not.  They are initialized from environment variables, but only once (I think).

    That means we need a different approach for applying shot based LUTs in
    RV. Seems like extracting scene and shot from source paths should work
    best for us.


    Some notes on this stuff:

    http://tweaksoftware.com/static/documentation/rv/current/html/opencolorio_integration.html

    As you see there, RV provides an alternate way to set/store OCIO "context" variables per OCIO node.  So assuming you can programmatically determine that working on a given shot (say in Nuke) you would normally have the $SHOT variable set to "shot12a", then when creating the appropriate OCIO nodes in your ocio_source_setup, you'd just create and set the string property "ocio_context.SHOT" to "shot12a" for that shot.

    Does that make sense ?

    Alan

    Alan Trombla
    http://twitter.com/tweakrv

  • 0
    Avatar
    Michael Wortmann

    Mark, would you mind sharing your shotgun_fields_config_custom.mu file ?

     

    Thanks,

     

    Michael

  • 0
    Avatar
    Michael Wortmann

    Great, much appreciated!

  • 0
    Avatar
    Mark Visser

    (For anyone looking for the file, it's up there attached to the main post).

  • 0
    Avatar
    Craig Allison

    Hey guys,

    First of all, just want to say thanks for all the work that's been put in here, these posts have really helped me get a good way along with my OCIO/RV integration.

     

    I'm just struggling with one thing, and that's the setting of ocio_context, I'm using ocio_source_setup to do some regex matching on the file path to create a dictionary : { 'SHOT' : 'abc100', 'SEQ' : 'abc', 'SHOW' : 'test' }, then I pass the context to useFileOcio, where setComponent( fileOCIO, 'ocio_context', context ) is fired.

     

    But when I switch on the lut, the {SHOT}, {SHOW} variables don't seem to be set anywhere... What am I missing?

     

    Thanks

     

    Craig

     

     

     

  • 0
    Avatar
    Craig Allison

    I've actually worked this out now, instead of adding the ocio_context component strings to the OCIOFile node, I switched them to the OCIOLook node and it works perfectly!

    Regards

    Craig

Please sign in to leave a comment.