Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing an interchange mechanism between configs #927

Closed
doug-walker opened this issue Feb 4, 2020 · 9 comments
Closed

Providing an interchange mechanism between configs #927

doug-walker opened this issue Feb 4, 2020 · 9 comments

Comments

@doug-walker
Copy link
Collaborator

BACKGROUND

An OCIO config defines its own self-contained universe of color spaces with no explicit connection to other configs or other forms of color management. It has been said that this is perhaps simultaneously both its best and worst feature. ;-)

It is great in the sense that the config author defines every color space and how they connect to each other. There are no unknowns and everything is under control.

However there are cases where it would be extremely useful (or even essential) to be able to convert from a color space in one config to either a color space in another config, or to color spaces as they may exist in other applications/systems. The lack of this possibility with current configs is a major blocker to using OCIO in a number of workflows today.

Some examples:

  1. Many studios create image and CG assets that their artists would like to reuse between shows/projects. These assets may be tagged as being in specific color spaces that were defined in the config for that project. Often a new project will have its own config, which may not be fortunate enough to define all the color spaces needed to interpret these older assets.
  2. New standards such as USD and MaterialX allow work to be broken down into pieces that may then be assembled or incorporated by reference into larger works. Currently, there is no way to bring in a component that uses a color space from a separate config that does not also exist in the main config.
  3. Assets (images, CG, materials, etc.) may be tagged as being in a color space that may not be associated with any specific config. For example they may use ACES color spaces, ITU color spaces, or color spaces associated with a given vendor (ARRI, RED, Sony, etc.). Applications may sometimes need to work with these assets in a way that interoperates with assets associated with the currently loaded config even if that config does not provide a color space for it.
  4. It is currently non-trivial for an application to determine whether a color space in one config is actually the same as a color space in another config.

PROPOSAL

The proposal is to use the existing role mechanism to refer to one or more standard well-known and precisely defined color spaces. If two configs both define a common "interchange" role, a conversion from color space A to color space B may proceed by using the first config to go from CS A to the interchange space and then using the second config to convert from the interchange space to CS B.

The most well-defined standard scene-referred color space today is ACES2065-1, which is defined in SMPTE standard ST2065-1. The proposal is to allow this to be used as an interchange color space. The proposed name of the role is: "aces_interchange".

Other interchange color spaces could be defined over time, if needed.

A new getProcessor method will be added to the Config class that would take the source and destination configs and color spaces and return a processor that is able to perform the requested conversion. (Note that once a Processor has been built, it is essentially just a sequence of ops that is independent of any config.)

To allow use of this feature, the authors of the two configs would both need to add the aces_interchange role to their configs. If the config already defines an ACES2065-1 ColorSpace, then it is simply a matter of pointing the new role to that ColorSpace (whatever it is named).

If the config does not already define the space, then it would mean adding an ACES2065-1 ColorSpace and providing a transform to or from the config's reference space. Given the existence of the widely used open source ACES config, hopefully this will not be much of a burden on config authors. Note that if a color space does need to be added, the config author is free to use any name and even to put that name in the inactive_colorspaces list to hide it from application menus (it may still be used in a role).

Note that this feature is optional for config authors. If both configs don't contain the new role, then the new cross-config getProcessor method will throw. (In that case, we are no worse off than we are today.) However, if the ability to convert between configs is essential to an application, there is nothing to prevent such applications from requiring the interchange role be present in order to allow use of a given config.

@michdolan
Copy link
Collaborator

michdolan commented Feb 4, 2020

🎉
Yes, awesome. This will be incredibly useful!

My only comment: Is there a reason why the interchange state couldn't be any role or color space which is defined in the two configs? I agree that ACES2065-1 is a logical choice for this, but it would be great to utilize existing configs that have other common roles/spaces already. As long as the user understands it is their responsibility to make sure both definitions mean the same thing, is there a technical barrier preventing that?

@KevinJW
Copy link
Contributor

KevinJW commented Feb 4, 2020

I agree with the principle, but I'm not convinced by the role name, though I have not come up with a better one, the prefix of 'aces' being a little too generic. ACES being a wide range of things including a number of colour spaces.

I'd say if it describes how to map the config reference space into ST2065-1 then th name should contain that, but ST2065-1_interchange, or ST2065-1_mapping (my best so far) are not much better.

@doug-walker
Copy link
Collaborator Author

doug-walker commented Feb 5, 2020

Michael, you raise an interesting point. As you point out, we cannot simply rely on existing roles as a mechanism for interchange since, e.g. scene_linear in one config will typically be a different space than scene_linear in a another config and I don't know how applications would be able to detect cases where they may happen to be the same. It seems like the user would need to provide other information, but it's not clear whether it should be a pair of spaces or something else. One of the main goals with our proposal is to keep it as simple as possible. By requiring this new role be present, it means that there is no extra info that needs to be provided.

Note that if the role is present, it does allow applications to detect spaces that are identical. For example, if a user has an asset tagged as being color space A in config A, an application could search config B to find a matching space by iterating through all the spaces in config B and calling this new API to get a processor. If isNoOp() is true on the processor, it means the spaces match.

If the role is missing, an application could do as you suggest and ask the user for a pair of color spaces from the two configs that match and then it could basically do the same steps we do in this PR. There is nothing missing from the public API today to block an app from doing this. We could add another function for this as a convenience but we need to decide whether apps would want to do this enough to warrant it. The main concern being that it would take a quite knowledgeable user to provide the correct pair of color spaces and not cause unintended problems. Are others as worried as I am about potential havoc? For example, sRGB or another pair of display-referred spaces would clearly not be ideal. Also Raw or other data spaces would not give the expected results.

But please propose specific function signatures you'd like to see and we will be happy to add them if the group would like them.

Kevin, yes I am also sensitive to the fact that "aces" is not a precise identification of ACES2065-1. I was also trying to think of other names, but didn't come up with anything. My feeling is that this role should not be exposed to end-users. And for config authors, well hopefully they will consult the documentation before trying to use this feature.

@michdolan
Copy link
Collaborator

That's a good point about the pre-designated role reducing the need for user input. I'm not opposed to having that be the standard behavior, but I do think it would be useful to have another function to handle custom cases. I was thinking more about the studio pipeline use case than that of a DCC.

An ACES linear space (ACES2065-1 or ACEScg) would be a common intermediary here, but there are odd cases where something unconventional is needed (between a legacy non-ACES project and a new ACES project for example). Defining the common color space or role in these cases is more likely being done in a pipeline configuration by a color scientist than by a user in a DCC.

But yes, in the DCC UX case, I could see how having to select a common role would be confusing to someone who is potentially using a config they know little about the internals of. I would propose adding these functions is addition to what Bernard has in #922 (not stuck on my suggested param name):

    //!cpp:function::
    static ConstProcessorRcPtr GetProcessor(const ConstConfigRcPtr & srcConfig,
                                            const char * srcName,
                                            const char * srcInterchangeName,
                                            const ConstConfigRcPtr & dstConfig,
                                            const char * dstName,
                                            const char * dstInterchangeName);

    //!cpp:function::
    static ConstProcessorRcPtr GetProcessor(const ConstContextRcPtr & srcContext, 
                                            const ConstConfigRcPtr & srcConfig,
                                            const char * srcName,
                                            const char * srcInterchangeName,
                                            const ConstContextRcPtr & dstContext,
                                            const ConstConfigRcPtr & dstConfig,
                                            const char * dstName,
                                            const char * dstInterchangeName);

@KelSolaar
Copy link
Contributor

Great proposal, I like it!

I'm fine with aces_interchange. Technically exchanging ACES data should be done as per the book, so people should not be surprised that it is ACES2065-1 under the hood?

Cheers,

Thomas

@BernardLefebvre
Copy link
Contributor

Working on it

@zachlewis
Copy link
Collaborator

So, just spitballing here, but... is there a place of some kind of config inheritance / merging / overriding mechanism? I.e., if one OCIO config is dropped somewhere within another's search path...?

I think that could be a really succinct and powerful way of providing levels of indirection not easily articulated in a single config (although @KevinJW and @dbr have proposed some really interesting ideas), and it could be an interesting way of coordinating department- or application-specific workflows or policies.

One example might be providing texturing / lookdev with an apparently show-agnostic (or shot-agnostic) config (i.e., to prevent 'baking in' a look to an asset's texture), while inheriting a parent config's role for texture publishing or cg rendering.

Another example might be neutral-grading-type workflow (or similar), where lighting or lookdev are working on top of plates with a certain grade pre-applied, implicitly 'baking in' a grade to the render which must be inverted at some point downstream, depending on how compositing is working. Lighting and lookdev could inherit the config used by compositing, and override or alter the colorspace used for reading plates with an additional transform applying a given shot's neutral grade; and likewise, the lighting config could ignore a filename rule used by compositing that points renders coming from CG to a colorspace that "unbakes" the neutral grade in a read node. Although thinking about that now, I imagine that inverse-neutral grade transform would only get applied to the rgb beauty layer if applied in a nuke read node.... god I hope this paragraph makes sense.

Anyway, just food for thought. Nothing I described above necessarily requires hierarchical config inheritance / overriding, I suppose. It's not clear to me whether or not this would actually add or reduce complexity overall. I think in some cases, it could help reduce friction for developers integrating OCIO by allowing pipeline designers to dictate the mechanics of interchange by strategically populating the search path with configs as desired. On the other hand, this wouldn't at all help when all a user wants to do is take an external config and interactively 'import' colorspaces into the working config as desired, or selectively merge / append one config with colorspaces of another (with the results explicitly serialized).

Is this whole idea out-of-scope for this thread? Is it worth the headache of thinking about / implementing? Is it even possible? Is it even desired? Some food for thought.

@zachlewis
Copy link
Collaborator

zachlewis commented Apr 8, 2020

You know what? Scratch what I said above.
Not only does it not have anything to do with the actual proposal, but even if it were technically possible to support, (re)defining actual colorspace definitions dynamically with config snippets distributed across the search path hierarchy would be... kind of a nightmare in production. This would create many non-intuitive, problematic scenarios and unwanted surprises, and undermine many of the recent OCIO-2 design decisions that serve to localize and clarify intended pipeline behavior.

So... all in all, what I was suggesting before is an objectively terrible idea. D-. Hard pass. They can't all be gems :)

Now, what could be useful is a means to redefine file rules or roles contextually; but this isn't the thread for that

Incidentally, I'd be cool with an "aces_interchange" role. IIRC, in the OCIO-2 proposal from many moons ago, someone suggested a "cie_xyz_d65_interchange" role for display-referred colorspaces; I think it would be quite nice too.

@doug-walker
Copy link
Collaborator Author

Zach, yes, the two new roles are aces_interchange and cie_xyz_d65_interchange, but there is an API that allows other roles to be used. This issue has now been implemented in PR #922 and #957.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants