Overview
This guide aims to provide developers with a solid foundation in color science concepts and practical implementation details on the treatment of color within OpenUSD both in scene data and via OpenUSD's interfaces. This guide will navigate the complexities of color and is of interest to developers integrating OpenUSD into an existing renderer, building tools for artists, or creating content procedurally.
Readers should familiarize themselves with fundamental color science concepts and terminology by reading the Color User's Guide in addition to this document.
OpenUSD Color Management Architecture
OpenUSD provides a rigorous and well defined system for managing scene-referred color spaces through its API schemas. By "scene-referred" we mean specifying the source color space for any authored color attribute or asset path identifying a texture or other external color-containing asset. The primary applied schemas are:
- UsdColorSpaceAPI: Allows specifying color space information on prims.
- UsdColorSpaceDefinitionAPI: A multiple-apply schema that enables definition of custom color spaces.
Key Concepts in USD Color Management
Color Space Inheritance
In OpenUSD, color spaces can be specified at any level in the scene hierarchy and are inherited by child prims. This hierarchical approach allows for:
- Setting a global color space at the root.
- Providing a color space for a subgraph of the scene.
- Specifying a color space for attributes on individual prims.
- Authoring the color on individual attributes.
Color Space Resolution
When determining the color space for a value, OpenUSD follows a specific resolution order:
- Check if the attribute has an explicitly assigned color space.
- Check if the attribute's prim has UsdColorSpaceAPI applied.
- Search up the hierarchy until a prim with UsdColorSpaceAPI is found.
- If no color space is found, an empty token is returned. If no color space is found, an empty token is returned. In this case, the color space must be assumed to be Linear Rec.709.
Programming With UsdColorSpaceAPI
Applying Color Space Information
The colorSpaceName attribute is a uniform value applied to a prim. To apply color space information to a prim:
VtValue(GfColorSpaceNames->LinearRec709));
A path value used to locate objects in layers or scenegraphs.
UsdColorSpaceAPI is an API schema that introduces a colorSpace property for authoring scene referred ...
USD_API UsdAttribute CreateColorSpaceNameAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
See GetColorSpaceNameAttr(), and also Create vs Get Property Methods for when to use Get vs Create.
static USD_API UsdColorSpaceAPI Apply(const UsdPrim &prim)
Applies this single-apply API schema to the given prim.
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
USD_API UsdPrim GetPrimAtPath(const SdfPath &path) const
Returns the prim at path on the same stage as this prim.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Querying Color Space Information
To determine the color space for an attribute:
Token for efficient comparison, assignment, and hashing of known strings.
Scenegraph object for authoring and retrieving numeric, string, and array valued data,...
static USD_API GfColorSpace ComputeColorSpace(const UsdAttribute &attribute, ColorSpaceCache *cache=nullptr)
Computes the color space for the given attribute on this prim, using the same algorithm as ComputeCol...
static USD_API TfToken ComputeColorSpaceName(const UsdAttribute &attribute, ColorSpaceCache *cache=nullptr)
Computes the color space name for the given attribute.
USD_API UsdAttribute GetAttribute(const TfToken &attrName) const
Return a UsdAttribute with the name attrName.
Performance Optimization With Caching
For performance-critical applications, OpenUSD provides a caching mechanism to accelerate large numbers of look ups:
This is a simple example of a color space cache implementation.
Defining Custom Color Spaces
OpenUSD allows defining custom color spaces using the UsdColorSpaceDefinitionAPI:
TfToken definitionName(
"customSpace");
GfVec2f whitePoint(0.3127, 0.3290);
float gamma = 1.0;
float linearBias = 0.0;
redChroma, greenChroma, blueChroma, whitePoint, gamma, linearBias);
Basic type for a vector of 2 float components.
UsdColorSpaceDefinitionAPI is an API schema for defining a custom color space.
USD_API UsdAttribute CreateNameAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
See GetNameAttr(), and also Create vs Get Property Methods for when to use Get vs Create.
USD_API void CreateColorSpaceAttrsWithChroma(const GfVec2f &redChroma, const GfVec2f &greenChroma, const GfVec2f &blueChroma, const GfVec2f &whitePoint, float gamma, float linearBias)
Creates the color space attributes with the given values.
static USD_API UsdColorSpaceDefinitionAPI Apply(const UsdPrim &prim, const TfToken &name)
Applies this multiple-apply API schema to the given prim along with the given instance name,...
Alternatively, you can define a color space from an RGB to XYZ transformation matrix:
float gamma = 1.0;
float linearBias = 0.0;
Stores a 3x3 matrix of float elements.
USD_API void CreateColorSpaceAttrsWithMatrix(const GfMatrix3f &rgbToXYZ, float gamma, float linearBias)
Create the color space attributes by deriving the color space from the given RGB to XYZ matrix and li...
Color Space Transformations
To convert colors between spaces, use the GfColorSpace class:
GfVec3f srcColor(1.0f, 0.5f, 0.0f);
std::vector<GfVec3f> colorArray = ;
srcSpace.
ConvertRGBSpan(targetSpace, colorArray.data(), colorArray.size());
GF_API void ConvertRGBSpan(const GfColorSpace &srcColorSpace, TfSpan< float > rgb) const
Convert in place a packed array of RGB values from one color space to "this" one.
GF_API GfColor Convert(const GfColorSpace &srcColorSpace, const GfVec3f &rgb) const
Convert a rgb triplet in a certain color space to "this" color space.
Basic type for a vector of 3 float components.
Best Practices for USD Color Management
Establish a Clear Color Management Policy
Define which color spaces your pipeline uses for:
- Texture inputs
- Material parameters
- Render outputs
Be Explicit About Color Spaces
Specify color spaces explicitly rather than relying on defaults.
A general best practice is to first ensure that the stage's root prim has the UsdColorSpaceAPI schema applied, and set the prim's color space to the studio/pipeline default (e.g. LinearRec2020).
Then, for textures or other color assets created outside the studio/pipeline using a different source color space, make sure to explicitly set the appropriate color space.
USD_API void SetColorSpace(const TfToken &colorSpace) const
Sets the color space of the attribute to colorSpace.
Perform Computations in Linear Space
Ensure all lighting calculations, blending, and compositing happen in linear color space. In most scenarios, the color space to be used for these computations would be specified in RenderSettings.renderingColorSpace.
Cache Color Space Lookups
For render loops or other performance-critical sections:
for (const auto& attr : attributes) {
}
Clear Cache When Scene Changes
If your application caches color space information, ensure the cache is invalidated when:
- Stage contents change
- Layer stacks are modified