Config syntax¶
OpenColorIO is primarily controlled by a central configuration file,
usually named config.ocio
. This page will only describe how to
syntactically write this OCIO config - e.g. what transforms are
available, or what sections are optional.
This page alone will not help you to write a useful config file! See the Configurations section for examples of complete, practical configs, and discussion of how they fit within a facilities workflow.
Please note that you should use the OCIO Python or C++ API to generate the config.ocio file rather than writing the YAML by hand in a text editor. However, if you do ever modify YAML by hand rather than via the API, you should run ociocheck on it to ensure that the syntax is correct.
YAML basics¶
This config file is a YAML document, so it is important to have some basic knowledge of this format.
The Wikipedia article on YAML has a good overview.
OCIO configs typically use a small subset of YAML, so looking at existing configs is probably the quickest way to familiarise yourself (just remember the indentation is important!).
Checking for errors¶
Use the ociocheck
command line tool to validate your config. It
will inform you of YAML-syntax errors, but more importantly it
performs various OCIO-specific validations. There are also validate
methods on the Config class in the C++ and Python APIs, (although
they do not do the role checking that ociocheck does).
For more information, see the overview of ociocheck
Config sections¶
An OCIO config has the following sections:
Config header – The header contains the version and LUT search path.
Environment – The environment defines the context variables used in the config.
Roles – The roles define which color spaces should be used for common tasks.
File & Viewing rules – These rules define sensible defaults that help applications provide a better user experience.
Displays & Views – This section defines how color spaces should be viewed.
Looks – Looks are transforms used to adjust colors, such as to apply a creative effect.
Colorspaces – This section defines the scene-referred color space encodings available within the config.
Display Colorspaces – This section defines the display-referred color space encodings available within the config.
Named Transforms – Named Transforms are a way to provide transforms that do not have a fixed relationship to a specific reference space, such as a utility curve.
A collection of Available transforms is provided for use in the various sections of the config file.
Config header¶
ocio_profile_version
¶
Required.
By convention, the profile starts with ocio_profile_version
.
This is a string, specifying which version of the OCIO config syntax is used.
The currently supported version strings are 1
and 2
.
ocio_profile_version: 2
description
¶
Optional. A brief description of the configuration.
description: This is the OCIO config for show: foo.
name
¶
Optional. A unique name for the config. Future versions of OCIO might use this as a sort of “namespace” for the color spaces defined in the rest of the config.
name: studio-config-v1.0.0_aces-v1.3_ocio-v2.1
search_path
¶
Optional. Default is an empty search path.
search_path
is a colon-separated list of directories. Each
directory is checked in order to locate a file (e.g. a LUT).
This works is very similar to how the UNIX $PATH
env-var works for
executables.
A common directory structure for a config is:
config.ocio
luts/
lg10_to_lnf.spi1d
lg10_to_p3.3dl
For this, we would set search_path
as follows:
search_path: "luts"
In a color space definition, we might have a FileTransform which refers
to the LUT lg10_to_lnf.spi1d
. It will look in the luts
directory, relative to the config.ocio
file’s location.
Paths can be relative (to the directory containing config.ocio
),
or absolute (e.g. /mnt/path/to/my/luts
)
Multiple paths can be specified, including a mix of relative and
absolute paths. Each path is separated with a colon :
search_path: "/mnt/path/to/my/luts:luts"
Paths may also be written on separate lines (this is more Windows friendly):
search_path:
- luts1
- luts2
Finally, paths can reference OCIO’s context variables:
search_path: "/shots/show/$SHOT/cc/data:luts"
This allows for some clever setups, for example per-shot LUT’s with fallbacks to a default. For more information, see the examples in Looks Example
family_separator
¶
Optional. Defines the character used to split color space family strings into hierarchical menus. It may only be a single character. If no separator is defined, the Menu Helpers API will not generate hierarchical menus.
family_separator: /
inactive_colorspaces
¶
Optional. Identify a list of color spaces that should not be used. These spaces
may stay in the config and will still work in ColorSpaceTransforms, but they will
not be added to application menus. This will be overridden by the environment
variable OCIO_INACTIVE_COLORSPACES
.
inactive_colorspaces: [ do_not_use_this_colorspace, prev_version_colorspace ]
luma
¶
Deprecated. Optional. Default is the Rec.709 primaries specified by the ASC:
luma: [0.2126, 0.7152, 0.0722]
These are the luminance coefficients, which can be used by OCIO-supporting applications when adjusting saturation (e.g. in an image-viewer when displaying a single channel)
Note
While the API method is not yet officially deprecated, luma
is
a legacy option from Imageworks’ internal, closed-source
predecessor to OCIO.
The luma
value is not respected anywhere within the OCIO
library. Also very few (if any) applications supporting OCIO will
respect the value either.
Environment¶
environment
¶
Optional. The envrionment section declares all of the context variables used in the configuration.
environment:
SEQ: default_sequence
SHOT: $SHOT
It is highly recommended that config authors using context variables include the environment section for the following reasons:
It provides performance benefits to applications
It will make the config easier to read and maintain
It allows defining default values
It improves the validation that may be performed on a config
This config uses two context variables: SEQ and SHOT. SEQ has a default value of default_sequence. This is the value that will be used if the environment does not contain the SEQ variable and the context variable is not otherwise defined. The SHOT variable does not have a default and hence the use of the syntax shown.
The environment must be self-contained and may not refer to any other variables.
For instance, in the example above it would not be legal to have SHOT: $FOO
since FOO is not one of the declared variables.
Every context variable used in the config must be declared since no other environment variables will be loaded into the context. In studios that use a large number of environment variables, this may provide a performance benefit for applications.
Roles¶
roles
¶
Required.
A “role” is an alternate name to a color space, which can be used by applications to perform task-specific color transforms without requiring the user to select a color space by name.
For example, the Nuke node OCIOLogConvert: instead of requiring the
user to select the appropriate log color space, the node performs a
transform between scene_linear
and compositing_log
, and the
OCIO config specifies the project-appropriate color spaces. This
simplifies life for artists, as they don’t have to remember which is
the correct log color space for the current project - the
OCIOLogConvert always does the correct thing.
A typical role definition looks like this, taken from the spi-vfx example configuration:
roles:
color_picking: cpf
color_timing: lg10
compositing_log: lgf
data: ncf
default: ncf
matte_paint: vd8
reference: lnf
scene_linear: lnf
texture_paint: dt16
All values in this example (such as cpf
, lg10
and ncf
)
refer to color spaces defined later the config, in the colorspaces
section.
Here is a description of the roles defined within OpenColorIO. Note that application developers may also define roles for config authors to use to control other types of tasks not listed below.
Warning
Unfortunately there is a fair amount of variation in how applications interpret OCIO roles. This section should be expanded to try and clarify the intended usage.
aces_interchange
- defines the color space in the config that implements the ACES2065-1 color space defined in SMPTE ST2065-1. This role is used to convert scene-referred color spaces between different configs that both define this role.cie_xyz_d65_interchange
- defines the color space in the config that implements standard CIE XYZ colorimetry, adapted to a D65 white. This role is used to convert display-referred color spaces between different configs that both define this role.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
ortexture_paint
).color_timing
- color space used for applying color corrections, e.g. user-specified grade within an image viewer (if the application uses theDisplayTransform::setDisplayCC
API method)compositing_log
- a log color space used for certain processing operations (plate resizing, pulling keys, degrain, etc). Used by the OCIOLogConvert Nuke node.data
- used when writing data outputs such as normals, depth data, and other “non color” data. The color space in this role should typically havedata: true
specified, so no color transforms are applied.default
- whenstrictparsing: false
, this color space is used as a fallback.matte_paint
- color space which matte-paintings are created in (for more information, see the guide on baking ICC profiles for Photoshop, and spi-vfx).reference
- the color space against which the other color spaces are defined.
Note
The reference role has sometimes been misinterpreted as being the space in which “reference art” is stored in.
scene_linear
- the scene-referred linear-to-light color space, often the same as the reference space (see:ref:faq-terminology).texture_paint
- similar tomatte_paint
but for painting textures for 3D objects (see the description of texture painting in SPI’s pipeline).
File & Viewing rules¶
file_rules
¶
Warning
Either the file_rules section or the default role are Required for configs of version 2 or higher.
Use the File Rules to assign a default color space to files based on their path.
Here is example showing the various types of rules that may be defined:
file_rules:
- !<Rule> {name: LogC, extension: "*", pattern: "*LogC*", colorspace: ARRI LogC}
- !<Rule> {name: OpenEXR, extension: "exr", pattern: "*", colorspace: ACEScg}
- !<Rule> {name: TIFF, regex: ".*\\.TIF?F", colorspace: sRGB}
- !<Rule> {name: ColorSpaceNamePathSearch}
- !<Rule> {name: Default, colorspace: default}
The File Rules are a set of mappings that are evaluated from the top down. The first rule to match is what determines which ColorSpace is returned.
There are four types of rules available. Each rule type has a name key that may be used by applications to refer to that rule. Name values must be unique. The other keys depend on the rule type.
1. Basic Rules – This is the basic rule type that uses Unix glob style pattern matching and is thus very easy to use. It contains the keys:
name
: Name of the rule.pattern
: Glob pattern to be used for the main part of the name/path. This is case-sensitive. It must be in double-quotes. Set it to “*” if you only want the rule to consider the extension.extension
: Glob pattern or string to be used for the file extension. Note that if glob tokens are not used, the extension will be used in a non-case-sensitive way by default. For example the simple string “exr” would match “exr” and “EXR”. If you only want to match “exr”, use the glob pattern “[e][x][r]”. It must be in double-quotes. Set it to “*” if you only want the rule to consider the pattern.colorspace
: ColorSpace name to be returned.
2. RegEx Rules – This is similar to the basic rule but allows additional capabilities for power-users. It contains the keys:
name
: Name of the rule.regex
: Regular expression to be evaluated. It must be in double-quotes.colorspace
: ColorSpace name to be returned.
Note that a backslash character in a RegEx expression needs to be doubled up as \\
(as shown in the example above for the TIFF rule) to make it through the Yaml parsing.
3. OCIO v1 style Rule – This rule allows the use of the OCIO v1 style, where the string is searched for ColorSpace names from the config. This rule may occur 0 or 1 times in the list. The position in the list prioritizes it with respect to the other rules. It has the key:
name
: Must beColorSpaceNamePathSearch
.
4. Default Rule – The file_rules section must always end with this rule. If no prior rules match, this rule specifies the ColorSpace applications will use. It has the keys:
name
: must beDefault
.colorspace
: ColorSpace name to be returned.
Note: OCIO v1 defined a default
role intended to specify a default color space
when reading files. However, given the confusion over the usage of this role, the
Default file rule is now the preferred way to indicate this mapping. However, if
the file_rules section is not present in the config, the new API will try to use
the default role in place of the Default Rule. If both are present, the Default
Rule takes precedence. If both the file_rules section and the default role are
missing, an exception will be thrown when loading the config.
Note that the strictparsing token does not affect the behavior of the File Rules
API. In other words, evaluating the rules will always result in a ColorSpace being
available to an application. However, the API also allows the application to know
which rule was the matching one. So apps that want to work in “strict” mode should
first check if strictparsing is true and if so check to see if the matching rule
was the Default Rule. If so, it could then notify the user and take whatever action
is appropriate. (As an alternative to checking which rule number was matched, the
API call filepathOnlyMatchesDefaultRule
may be used instead.)
Roles may be used rather than ColorSpace names in the rules.
It is also legal for rules to have additional key:value pairs where the value may be an arbitrary string. The API provides access to getting/setting these additional pairs and will preserve them on a Config read/write. These may be used to define application-specific behavior.
Note to developers: The older parseColorSpaceFromString
API call is now deprecated
and should be replaced with getColorSpaceFromFilepath
.
strictparsing
¶
Optional. Valid values are true
and false
. Default is true
(assuming a config is present):
strictparsing: true
Warning
This attribute is from OCIO v1. In OCIO v2, the FileRules system was
introduced and so the strictparsing
attribute is less relevant now.
The parseColorSpaceFromString
API call is now deprecated and the
proper way to obtain this information is getColorSpaceFromFilepath
.
The FileRules always return a default color space but the API
filepathOnlyMatchesDefaultRule
may be used by applications that
want to take some special action if strictparsing
is true.
OCIO v1 provided a mechanism for applications to extract the colorspace
from a filename (the parseColorSpaceFromString
API method).
So for a file like example_render_v001_lnf.0001.exr
it will
determine the colorspace lnf
(it being the right-most substring
containing a colorspace name).
However, if the colorspace cannot be determined and strictparsing:
true
, it will return an empty string.
If the colorspace cannot be determined and strictparsing: false
,
the default role will be used. This allows unhandled images to operate
in “non-color managed” mode.
Application authors should note: when no config is present (e.g. via
$OCIO
), the default internal profile specifies
strictparsing=false
, and the default color space role is
raw
. This means that ANY string passed to OCIO will be parsed as
the default raw
. This is nice because in the absence of a config,
the behavior from your application perspective is that the library
essentially falls back to “non-color managed”.
viewing_rules
¶
Optional.
Use the Viewing Rules to assign default views to color spaces.
The Viewing Rules allow config authors to help applications provide a better user experience by specifying the views appropriate to use for a given color space. For example, applications may use the default view when making thumbnail images for its user interface. Likewise, an application could select the default view the first time it displays an image in a viewport.
Here is an example:
viewing_rules:
- !<Rule> {name: video-spaces, colorspaces: [sRGB, Rec709]}
- !<Rule> {name: data-spaces, colorspaces: [alpha, normals]}
displays:
sRGB:
- !<View> {name: Video, view_transform: colorimetry, display_colorspace: sRGB, rule: video-spaces}
- !<View> {name: Raw, colorspace: nc10, rule: data-spaces}
This is helpful for situations where a given view is intended for use with just a few specific color spaces. However in other situations, it would be helpful to be able to define rules to be used with a broader set of color spaces.
Color spaces may now have an “encoding” attribute to allow grouping color spaces into groups such as “scene-linear”, “log”, “sdr-video”, and “data”. The Viewing Rules makes it possible to define a rule based on the encoding attribute of a color space rather than a set of named color spaces. For example:
viewing_rules:
- !<Rule> {name: scene-linear-or-log, encodings: [scene-linear, log]}
displays:
sRGB:
- !<View> {name: ACES, view_transform: ACES-sdr-video, display_colorspace: sRGB, rule: scene-linear-or-log}
The colorspaces and encodings attributes may contain a single value or a list of values. It is illegal for a rule to define both a list of colorspaces and encodings simultaneously.
Also, similar to the file_rules, it is allowed for a rule to define a set of custom key/value pairs like this:
- !<Rule> { name: scene-linear-rule, encodings: scene-linear, custom: {key1: value1, key2: value2} }
The key names and values are arbitrary strings. This may be useful to control application-specific behavior.
A Viewing Rule may contain the following keys:
name
: The name of the rule (must be unique).encodings
: The color space encodings used by the rule (may be a list).colorspaces
: The color space names used by the rule (may be a list).custom
: A set of arbitrary key/value string pairs.
The API allows applications to request the list of views for a given color space. This uses the viewing rules to filter the views for the given display based on the color space name and encoding. Views that do not have a rules attribute are always returned (so if no rules are present, the results are the same as the unfiltered API call).
Note that the active_views may be used to remove views that are not appropriate for a given user or workstation. If the active_views list is non-empty, any views that are not in that list will not appear in the results provided to the application (regardless of whether the view appears in a rule).
Furthermore, active_views will continue to sort (that is, determine the index order) the list of views in all of the API calls.
The first allowed view for a color space is the default.
Displays & Views¶
displays
¶
Required.
This section defines all the display devices which will be used. For example you might have a sRGB display device for artist workstations, a DCIP3 display device for the screening room projector.
Each display device has a number of “views”. These views provide different ways to display the image on the selected display device. Examples of common views are:
“Film” to emulate the final projected result on the current display
“Log” to send log-space pixel values directly to the display, resulting in a “lifted” image useful for checking black-levels.
“Raw” when assigned a colorspace with
raw: yes
set will show the unaltered image, useful for tech-checking images
An example of the displays
section from the spi-vfx config:
displays:
DCIP3:
- !<View> {name: Film, colorspace: p3dci8}
- !<View> {name: Log, colorspace: lg10}
- !<View> {name: Raw, colorspace: nc10}
sRGB:
- !<View> {name: Film, colorspace: srgb8}
- !<View> {name: Log, colorspace: lg10}
- !<View> {name: Raw, colorspace: nc10}
- !<View> {name: Film, colorspace: srgb8}
All the colorspaces (p3dci8
, srgb8
etc) refer to colorspaces
defined later in the config.
Unless the active_displays
and active_views
sections are
defined, the first display and first view will be the default.
A view may be defined as a transform directly from the scene-referred reference space to the display, as illustrated above. Alternatively a view may be defined using the combination of a View Transform and a Display Color Space. In this case, the View Transform converts from the scene-referred reference space to the display-referred reference space and then the Display Color Space is used to convert from the display-referred reference space to the display. Here is an example:
displays:
DCIP3:
- !<View> {name: Film, view_transform: FilmView, display_colorspace: DCIP3}
view_transforms:
- !<ViewTransform>
name: FilmView
from_reference: <omitted for brevity>
display_colorspaces:
- !<ColorSpace>
name: DCIP3
from_display_reference: <omitted for brevity>
The keys allowed with a View are:
name
: A name for the View.colorspace
: The color space whose transform will be used to convert from the reference space to the display.view_transform
: The transform used to convert from either the scene-referred reference to the display-referred reference space or as a transform to be applied in the display-referred reference.display_colorspace
: The display color space that is used to convert from the display-referred reference space to the display.looks
: One or more Look Transforms to be applied. The string may use the ‘+’ character to apply a look in the forward direction and the ‘-’ character to apply in reverse. See Looksrule
: The viewing rule to be used with this View. See viewing_rulesdescription
: A description string for this View.
Note that a View may use either the colorspace key or it may use both the view_transform and dispay_colorspace keys. No other combinations are allowed.
view_transforms
¶
Optional. Defines transforms to convert between the OCIO reference spaces.
An OCIO config may contain two Reference spaces: one scene-referred and the other display-referred. The View Transforms are mappings between these reference spaces. There are a variety of terms used in the industry for these mappings. In ISO 22028-1 and in ACES, they are called “color-rendering transforms” and in the ITU standards for HDR television (such as ITU-R BT.2100 and BT.2390) they are called an “Opto-optical Transfer Function” or OOTF.
It is also possible to specify a View Transform for adjusting display-referred reference space values. In other words, it may convert from the display-referred reference space back to itself. This is useful for describing transforms used for HDR to SDR video conversion, or vice versa.
A View Transform may use the following keys:
name
: A name for the ViewTransform.description
: A description of the ViewTransform.family
: A family string (similar to ColorSpace).categories
: The categories used for menu filtering (similar to ColorSpace).from_scene_reference
: The transform from the scene-referred reference space to the display-referred reference space.to_scene_reference
: The transform from the display-referred reference space to the scene-referred reference space.from_display_reference
: The transform from the display-referred reference space to the display-referred reference space.to_display_reference
: The inverse of the from_display_reference transform.
default_view_transform
¶
Optional. Defines the default view transform.
The default view transform is the view transform that is used if a ColorSpaceTransform needs to convert between a scene-referred and display-referred colorspace. If this key is missing, the first view transform in the config is used.
default_view_transform: un-tone-mapped
active_displays
¶
Optional. Default is for all displays to be visible, and to respect
order of items in displays
section.
You can choose what display devices to make visible in UI’s, and change the order in which they appear.
Given the example displays
block in the previous section - to make
the sRGB device appear first:
active_displays: [sRGB, DCIP3]
To display only the DCIP3
device, simply remove sRGB
:
active_displays: [DCIP3]
The value can be overridden by the OCIO_ACTIVE_DISPLAYS
env-var. This allows you to make the sRGB
the only active display,
like so:
active_displays: [sRGB]
Then on a review machine with a DCI P3 projector, set the following
environment variable, making DCIP3
the only visible display
device:
export OCIO_ACTIVE_DISPLAYS="DCIP3"
Or specify multiple active displays, by separating each with a colon:
export OCIO_ACTIVE_DISPLAYS="DCIP3:sRGB"
active_views
¶
Optional. Default is for all views to be visible, and to respect order of the views under the display.
Works identically to active_displays
, but controls which views are
visible.
Overridden by the OCIO_ACTIVE_VIEWS
env-var:
export OCIO_ACTIVE_VIEWS="Film:Log:Raw"
virtual_display
¶
Optional. A virtual display may be defined to allow OCIO to instantiate new displays from ICC profiles.
The syntax is similar to a conventional display. It may incorporate both views and shared views. There may only be one virtual display in a config.
When OCIO instantiates a display from an ICC monitor profile it will create
a display colorspace which is used with any views that have the display_colorspace
set to <USE_DISPLAY_NAME>
.
So in this example, if the application asks OCIO to instantiate a display from an ICC profile, the user would then see a second display, in addition to “sRGB”, named after the ICC profile. The views available for that new display are taken from the virtual display.
displays:
sRGB:
- !<View> {name: ACES, view_transform: ACES-sdr-video,
display_colorspace: <USE_DISPLAY_NAME>}
- !<View> {name: Log, colorspace: lg10}
- !<Views> [ Raw ]
virtual_display:
- !<View> {name: ACES, view_transform: ACES-sdr-video,
display_colorspace: <USE_DISPLAY_NAME>}
- !<View> {name: Log, colorspace: lg10}
- !<Views> [ Raw ]
Looks¶
looks
¶
Optional.
This section defines a list of “looks”. A look is a color transform defined similarly to a colorspace, with a few important differences.
For example, a look could be defined for a “first pass DI beauty grade”, which is used to view shots with a rough approximation of the final grade.
When the look is defined in the config, you must specify a name, the color transform, and the colorspace in which the grade is performed (the “process space”). You can optionally specify an inverse transform for when the look transform is not trivially invertable (e.g. it applies a 3D LUT)
When an application applies a look, OCIO ensures the grade is applied in the correct colorspace (by converting from the input colorspace to the process space, applies the look’s transform, and converts the image to the output colorspace)
Here is a simple looks:
section, which defines two looks:
looks:
- !<Look>
name: beauty
process_space: lnf
transform: !<CDLTransform> {slope: [1, 2, 1]}
- !<Look>
name: neutral
process_space: lg10
transform: !<FileTransform> {src: 'neutral-${SHOT}-${SEQ}.csp', interpolation: linear }
inverse_transform: !<FileTransform> {src: 'neutral-${SHOT}-${SEQ}-reverse.csp', interpolation: linear }
Here, the “beauty” look applies a simple, static ASC CDL grade, making
the image very green (for some artistic reason!). The beauty look is
applied in the scene-linear lnf
colorspace (this colorspace is
defined elsewhere in the config.
Next is a definition for a “neutral” look, which applies a shot-specific CSP LUT, dynamically finding the correct LUT based on the SEQ and SHOT context variables.
For example if SEQ=ab
and SHOT=1234
, this look will search for
a LUT named neutral-ab-1234.csp
in locations specified in
search_path
.
The process_space
here is lg10
. This means when the look is
applied, OCIO will perform the following steps:
Transform the image from it’s current colorspace to the
lg10
process spaceApply apply the FileTransform (which applies the grade LUT)
Transform the graded image from the process space to the output colorspace
The “beauty” look specifies the optional inverse_transform
,
because in this example the neutral CSP files contain a 3D LUT. For
many transforms, OCIO will automatically calculate the inverse
transform (as with the “beauty” look), however with a 3D LUT the
inverse transform needs to be defined.
If the look was applied in reverse, and inverse_transform
as not
specified, then OCIO would give a helpful error message. This is
commonly done for non-invertable looks
As in colorspace definitions, the transform can be specified as a
series of transforms using the GroupTransform
, for example:
looks:
- !<Look>
name: beauty
process_space: lnf
transform: !<GroupTransform>
children:
- !<CDLTransform> {slope: [1, 2, 1]}
- !<FileTransform> {src: beauty.spi1d, interpolation: nearest}
Colorspaces¶
colorspaces
¶
Required.
This section is a list of the scene-referred colorspaces in the config. A colorspace may be referred to elsewhere within the config (including other colorspace definitions), and are used within OCIO-supporting applications.
A colorspace may use the following keys:
to_scene_reference
and from_scene_reference
¶
These keys specify the transforms that define the relationship between the colorspace and the scene-referred reference space.
Note: In OCIO v1, the keys to_reference
and from_reference
were
used (since there was only one reference space). These are still supported
as synonyms.
Here is a example of a very simple colorspaces
section, modified
from the spi-vfx example config:
colorspaces:
- !<ColorSpace>
name: lnf
bitdepth: 32f
description: |
lnf : linear show space
- !<ColorSpace>
name: lg16
bitdepth: 16ui
description: |
lg16 : conversion from film log
to_scene_reference: !<FileTransform> {src: lg16_to_lnf.spi1d, interpolation: nearest}
First the lnf
colorspace (short for linear float) is used as our
reference colorspace. The name can be anything, but the idea of a
reference colorspace is an important convention within OCIO: all
other colorspaces are defined as transforms either to or from this
colorspace.
The lg16
colorspace is a 16-bit log colorspace (see
spi-vfx for an explanation of this colorspace). It has a
name, a bit-depth and a description.
The lg16
colorspace is defined as a transform from lg16
to the
reference colorspace (lnf
). That transform is to apply the LUT
lg16_to_lnf.spi1d
. This LUT has an input of lg16
integers and
outputs linear 32-bit float values
Since the 1D LUT is automatically invertable by OCIO, we can use this
colorspace both to convert lg16
images to lnf
, and lnf
images to lg16
Importantly, because of the reference colorspace concept, we can
convert images from lg16
to the reference colorspace, and then on
to any other colorspace.
Here is another example colorspace, which is defined using
from_scene_reference
.
- !<ColorSpace>
name: srgb8
bitdepth: 8ui
description: |
srgb8 :rgb display space for the srgb standard.
from_scene_reference: !<FileTransform> {src: srgb8.spi3d, interpolation: linear}
We use from_scene_reference
here because we have a LUT which transforms
from the reference colorspace (lnf
in this example) to sRGB.
In this case srgb8.spi3d
is a complex 3D LUT which cannot be
inverted, so it is considered a “display only” colorspace. If we did have a second 3D LUT to apply the inverse transform, we can specify both to_scene_reference
and from_scene_reference
- !<ColorSpace>
name: srgb8
bitdepth: 8ui
description: |
srgb8 :rgb display space for the srgb standard.
from_scene_reference: !<FileTransform> {src: lnf_to_srgb8.spi3d, interpolation: linear}
to_scene_reference: !<FileTransform> {src: srgb8_to_lnf.spi3d, interpolation: linear}
Using multiple transforms¶
The previous example colorspaces all used a single transform each, however it is often useful to use multiple transforms to define a colorspace.
- !<ColorSpace>
name: srgb8
bitdepth: 8ui
description: |
srgb8 :rgb display space for the srgb standard.
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: lnf, dst: lg16}
- !<FileTransform> {src: lg16_to_srgb8.spi3d, interpolation: linear}
Here to get from the reference colorspace, we first use the
ColorSpaceTransform
to convert from lnf
to lg16
, then
apply our 3D LUT on the log-encoded images.
This primarily demonstrates the meta-transform GroupTransform
: a
transform which simply composes two or more transforms together into
one. Anything that accepts a transform like FileTransform
or
CDLTransform
will also accept a GroupTransform
It is also worth noting the ColorSpaceTransform
, which transforms
between lnf
and lg16
colorspaces (which are defined within the
current config).
Example transform steps¶
This section explains how OCIO internally applies all the transforms. It can be skipped over if you understand how the reference colorspace works.
colorspaces:
- !<ColorSpace>
name: lnf
bitdepth: 32f
description: |
lnf : linear show space
- !<ColorSpace>
name: lg16
bitdepth: 16ui
description: |
lg16 : conversion from film log
to_scene_reference: !<FileTransform> {src: lg16.spi1d, interpolation: nearest}
- !<ColorSpace>
name: srgb8
bitdepth: 8ui
description: |
srgb8 :rgb display space for the srgb standard.
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: lnf, dst: lg16}
- !<FileTransform> {src: lg16_to_srgb8.spi3d, interpolation: linear}
To explain how this all ties together to display an image, say we have
an image in the lnf
colorspace (e.g. a linear EXR) and wish to
convert it to srgb8
- the transform steps are:
ColorSpaceTransform
is applied, converting from lnf to lg16The
FileTransform
is applied, converting from lg16 to srgb8.
A more complex example: we have an image in the lg16
colorspace,
and convert to srgb8
(using the lg16 definition from earlier, or
the spi-vfx config):
First OCIO converts from lg16 to the reference space, using the transform defined in lg16’s to_scene_reference:
FileTransform
applies the lg16.spi1d
With the image now in the reference space, srgb8’s transform is applied:
ColorSpaceTransform to transform from lnf to lg16
FileTransform applies the
lg16_to_srgb8.spi3d
LUT.
Note
OCIO has an transform optimizer which removes redundant steps, and combines similar transforms into one operation.
In the previous example, the complete transform chain would be “lg16 -> lnf, lnf -> lg16, lg16 -> srgb8”. However the optimizer will reduce this to “lg16 -> srgb”.
encoding
¶
Optional. Specify how color space values are numerically encoded.
It is very helpful for applications to be able to know the basic type of encoding of a color space. For example, it is well known that the performance of various types of image processing algorithms varies based on the type of encoding. Applying a spatial filter to a scene-linear image gives a different subjective result than if applied to the same image encoded in a log color space. Likewise certain algorithms such as keying or tracking may assume that the color encoding is roughly perceptually uniform and thus may have difficulties with scene-linear images.
The allowed values and definitions are:
scene-linear
– A scene-referred encoding where the numeric
representation is proportional to scene luminance. Examples: ACES2065-1, ACEScg.
display-linear
– A display-referred encoding where the numeric
representation is proportional to display luminance. Example: CIE XYZ values
measured off of a display or projection screen.
log
– A scene-referred encoding where the numeric representation is roughly
proportional to the logarithm of scene-luminance (often with some divergence
in the shadows as with most camera log encodings). Examples: ACEScct, ACEScc,
ARRI LogC, Sony S-Log3/S-Gamut3.
sdr-video
– A display-referred encoding where the numeric representation is
proportional to an SDR video signal. Examples: Rec.709/Rec.1886 video, sRGB.
hdr-video
– A display-referred encoding where the numeric representation is
proportional to an HDR video signal. Examples: Rec.2100/PQ or Rec.2100/HLG.
data
– A non-color channel. Note that typically such a color space would
also have the isdata attribute set to true. Examples: alpha, normals, Z-depth.
bitdepth
¶
Optional. Default: 32f
Specify an appropriate bit-depth for the colorspace, and applications can use this to automatically output images in the correct bit-depth.
Valid options are:
8ui
10ui
12ui
14ui
16ui
32ui
16f
32f
The number is in bits. ui
stands for unsigned integer. f
stands for floating point.
Example:
- !<ColorSpace>
name: srgb8
bitdepth: 8ui
from_scene_reference: [...]
isdata
¶
Optional. Default: false. Boolean.
The isdata
key on a colorspace informs OCIO that this colorspace
is used for non-color data channels, such as the “normals” output of a
a multipass 3D render.
Here is example “non-color” colorspace from the spi-vfx config:
- !<ColorSpace>
name: ncf
family: nc
equalitygroup:
bitdepth: 32f
description: |
ncf :nc,Non-color used to store non-color data such as depth or surface normals
isdata: true
allocation: uniform
equalitygroup
¶
Optional.
If two colorspaces are in the “equality group”, transforms between them are considered non-operations.
You might have multiple colorspaces which are identical, but operate at different bit-depths.
For example, see the lg10
and lg16
colorspaces in the
spi-vfx config. If loading a lg10
image and
converting to lg16
, no transform is required. This is of course
faster, but may cause an unexpected increase in precision (e.g. it skip
potential clamping caused by a LUT)
- !<ColorSpace>
name: lg16
equalitygroup: lg
bitdepth: 16ui
to_scene_reference: !<FileTransform> {src: lg16.spi1d, interpolation: nearest}
- !<ColorSpace>
name: lg10
equalitygroup: lg
bitdepth: 10ui
to_scene_reference: !<FileTransform> {src: lg10.spi1d, interpolation: nearest}
- Do not put different colorspaces in the same equality group. For
logical grouping of “similar” colorspaces, use the
family
option.
family
¶
Optional.
Allows for logical grouping of colorspaces within a UI.
For example, a series of “log” colorspaces could be put in one
“family”. Within a UI like the Nuke OCIOColorSpace
node, these
will be grouped together.
The Menu Helpers API allows applications to build hierarchical menus
for color spaces based on the family
key. The family_separator
key of the config is used to define the character used to separate the
family string into tokens.
family_separator: /
color_spaces:
- !<ColorSpace>
name: ACME_log4
family: Log/Cameras/ACME
equalitygroup: ACME_log4
[...]
- !<ColorSpace>
name: ACEScct
family: Log/ACES
equalitygroup: ACEScct
[...]
- !<ColorSpace>
name: Rec.709
family: Video/Broadcast/SDR
equalitygroup: Rec.709
[...]
Unlike equalitygroup
, the family
has no impact on image
processing.
aliases
¶
Optional.
The aliases key is used to define alternate names for the colorspace. For example, it may be useful to define a shorter version of the name that is easier to include in texture path names. Or it may be necessary to define an older version of the name for the color space for backwards compatibility.
aliases: [shortName, obsoleteName]
allocation
and allocationvars
¶
Optional.
These two options were used in OCIO v1 when transforms were applied on the GPU. However, the new GPU renderer in OCIO v2 does not need these.
However, they may still be used to automatically generate a “shaper LUT” when baking LUT’s unless one is explicitly specified (not all output formats utilise this)
For a detailed description, see How to Configure ColorSpace Allocation
Example of a “0-1” colorspace
allocation: uniform
allocationvars: [0.0, 1.0]
allocation: lg2
allocationvars: [-15, 6]
description
¶
Optional.
A human-readable description of the colorspace.
The YAML syntax allows for either single-line descriptions:
- !<ColorSpace>
name: kodaklog
[...]
description: A concise description of the kodaklog colorspace.
Or multiple-lines:
- !<ColorSpace>
name: kodaklog
[...]
description:
This is a multi-line description of the kodaklog colorspace,
to demonstrate the YAML syntax for doing so.
Here is the second line. The first one will be unwrapped into
a single line, as will this one.
It’s common to use literal |
block syntax to preserve all newlines:
- !<ColorSpace>
name: kodaklog
[...]
description: |
This is one line.
This is the second.
Display Colorspaces¶
display_colorspaces
¶
Optional.
This section is a list of all the display-referred colorspaces in the config. A display colorspace is very similar to a colorspace except its transforms go from or to the display-referred reference space rather than the scene-referred reference space.
A display colorspace may use all the same keys as a colorspace except
it uses to_display_reference
and from_display_reference
rather
than to_scene_reference
and from_scene_reference
to specify
its transforms.
display_colorspaces:
- !<ColorSpace>
name: sRGB
family:
description: |
sRGB monitor (piecewise EOTF)
isdata: false
categories: [ file-io ]
encoding: sdr-video
from_display_reference: !<GroupTransform>
children:
- !<BuiltinTransform> {style: "DISPLAY - CIE-XYZ-D65_to_sRGB"}
- !<RangeTransform> {min_in_value: 0., min_out_value: 0., max_in_value: 1., max_out_value: 1.}
Available transforms¶
AllocationTransform
¶
Transforms from reference space to the range specified by the
vars:
Keys:
allocation
vars
direction
BuiltInTransform
¶
Builds one of a known set of transforms, on demand
Keys:
style
direction
CDLTransform
¶
Applies an ASC CDL compliant grade
Keys:
slope
offset
power
sat
style
name
direction
ColorSpaceTransform
¶
Transforms from src
colorspace to dst
colorspace.
Keys:
src
dst
data_bypass
direction
DisplayViewTransform
¶
Applies a View from one of the displays.
Keys:
src
display
view
looks_bypass
data_bypass
direction
ExponentTransform
¶
Raises pixel values to a given power (often referred to as “gamma”)
!<ExponentTransform> {value: [1.8, 1.8, 1.8, 1]}
Keys:
value
style
name
direction
ExponentWithLinearTransform
¶
Applies a power but with a linear section near black. May be used to implement sRGB, CIE L*, and the Rec.709 camera OETF (not the display!).
Keys:
gamma
offset
style
name
direction
ExposureContrastTransform
¶
Applies an exposure, contrast, or gamma adjustment. Uses dynamic properties for optimal live adjustments (e.g., in viewports).
!<ExposureContrastTransform> {style: linear, exposure: -1.5,
contrast: 0.5, gamma: 1.1, pivot: 0.18}
Keys:
exposure
contrast
pivot
gamma
style
log_exposure_step
log_midway_gray
name
direction
FileTransform
¶
Applies a lookup table (LUT)
Keys:
src
cccid
cdl_style
interpolation
direction
FixedFunctionTransform
¶
Applies one of a set of fixed, special purpose, mathematical operators.
Keys:
style
params
name
direction
GradingPrimaryTransform
¶
Applies primary color correction.
Keys:
style
brightness
contrast
pivot
offset
exposure
lift
gamma
gain
saturation
clamp
name
direction
GradingRGBCurveTransform
¶
Applies a spline-based curve.
Keys:
style
red
green
blue
master
lintolog_bypass
name
direction
GradingToneTransform
¶
Applies an adjustment to various tonal ranges.
Keys:
style
blacks
shadows
midtones
highlights
whites
s_contrast
name
direction
GroupTransform
¶
Combines multiple transforms into one.
colorspaces:
- !<ColorSpace>
name: adx10
[...]
to_reference: !<GroupTransform>
children:
- !<FileTransform> {src: adx_adx10_to_cdd.spimtx}
- !<FileTransform> {src: adx_cdd_to_cid.spimtx}
A group transform is accepted anywhere a “regular” transform is.
Keys:
children
name
direction
LogAffineTransform
¶
Applies a logarithm as well as a scale and offset on both the linear and log sides. May be used to implement Cineon or Pivoted (Josh Pines) style lin-to-log transforms.
Keys:
base
lin_side_offset
lin_side_slope
log_side_offset
log_side_slope
name
direction
LogCameraTransform
¶
Similar to LogAffineTransform but also allows a linear section near black. May be used to implement the ACEScct non-linearity as well as many camera vendor lin-to-log transforms.
Keys:
base
lin_side_offset
lin_side_slope
log_side_offset
log_side_slope
lin_side_break
linear_slope
name
direction
LogTransform
¶
Applies a mathematical logarithm with a given base to the pixel values.
Keys:
base
name
direction
LookTransform
¶
Applies a named look
Keys:
src
dst
looks
direction
MatrixTransform
¶
Applies a matrix transform to the pixel values
Keys:
matrix
offset
name
direction
RangeTransform
¶
Applies an affine transform (scale & offset) and clamps values to min/max bounds.
Keys:
min_in_value
max_in_value
min_out_value
max_out_value
style
name
direction
Note
If a min_in_value is present, then min_out_value must also be present and the result is clamped at the low end. Similarly, if max_in_value is present, then max_out_value must also be present and the result is clamped at the high end.
Named Transforms¶
Sometimes it is helpful to include one or more transforms in a config that are essentially
stand-alone transforms that do not have a fixed relationship to a reference space or a
process space. An example would be a “utility curve” transform where the intent is to
simply apply a LUT1D without any conversion to a reference space. In these cases, a
named_transforms
section may be added to the config with one or more named transforms.
Note that named transforms do not show up in color space menus by default, so the application developer must implement support to make them available to users.
This feature may be used to emulate older methods of color management that ignored the RGB primaries and simply applied one-dimensional transformations. However, config authors are encouraged to implement transforms as normal OCIO color spaces wherever possible.
Named transforms support the keys:
name
aliases
description
family
categories
encoding
transform
inverse_transform
named_transforms:
- !<NamedTransform>
name: Utility Curve -- Cineon Log to Lin
transform: !<FileTransform> {src: logtolin_curve.spi1d}
Looks Example¶
Warning
This section is from OCIO v1 and has not been updated yet.
A “look” is a named color transform, intended to modify the look of an image in a “creative” manner (as opposed to a colorspace definition which tends to be technically/mathematically defined). An OCIO look typically exists as a flexible addendum to a defined viewing transform.
Examples of looks may be a neutral grade, to be applied to film scans prior to VFX work, or a per-shot DI grade decided on by the director, to be applied just before the viewing transform.
Looks are defined similarly to colorspaces, you specify a name and a transform (possibly a GroupTransform containing several other transforms), and optionally an inverse transform.
Where looks differ from colorspace definitions are in how they are applied. With a look, you also specify the “process space” - the colorspace in which the transform is applied.
Example configuration¶
Step 1: Setup a Look
A look is a top-level OCIO configuration object. Conceptually, it’s a named transform which gets applied in a specific color space. All of the changes below to the .ocio configs can be done manually by editing the text, or using the Python API.
Example look definition in a OCIO config:
looks:
- !<Look>
name: di
process_space: rclg16
transform: !<FileTransform> {src: look_di.cc, interpolation: linear}
Example Python API call:
look = OCIO.Look(name='di', processSpace='rclg16')
t = OCIO.FileTransform('look_di.cc', interpolation=OCIO.INTERP_LINEAR)
look.setTransform(t)
config.addLook(look)
The src file can be any LUT type that OCIO supports (in this case, it’s a
file that contains the <ColorCorrection>
element from a CDL file.) You
could also specify a .3dl, etc.
Once you define a look in your configuration, you’ll see that the
OCIOLookTransform
node in Nuke will provide the named option. In
this example, the ‘DI’ look conceptually represents a look that will
be applied in DI. Other look names we often used are ‘onset’,
‘editorial’, etc. The process_space
specifies that the transform
should be applied in that space. In this example, if you provide
linear input to the OCIOLookTransform
node, the pixels will be
converted to rclg16
before applying the look_di.cc
file-transform.
Step 2: Update the Display to use a look.
You can specify an optional ‘looks’ tag in the View tag, which will apply the specified look(s). This lets application in the viewer provide options which use the looks.
Example YAML config:
displays:
DLP:
- !<View> {name: Raw, colorspace: nc10}
- !<View> {name: Log, colorspace: rclg10}
- !<View> {name: Film, colorspace: p3dci16}
- !<View> {name: Film DI, colorspace: p3dci16, looks: di}
sRGB:
- !<View> {name: Raw, colorspace: nc10}
- !<View> {name: Log, colorspace: rclg10}
- !<View> {name: Film, colorspace: srgb10}
- !<View> {name: Film DI, colorspace: srgb10, looks: di}
Example Python API call:
for name,colorspace,look in [ ['Raw','nc10',''], ['Log','rclg10',''],
['Film','p3dci16',''], ['Film DI','p3dci16','di'] ]:
config.addDisplay('DLP',name,colorspace,look)
for name,colorspace,look in [ ['Raw','nc10',''], ['Log','rclg10',''],
['Film','srgb10',''], ['Film DI','srgb10','di'] ]:
config.addDisplay('sRGB',name,colorspace,look)
Option for advanced users: The looks tag is actually a comma-delimited list supporting +/- modifiers. So if you you wanted to specify a View that undoes DI, and then adds Onset, you could do “-di,+onset”.
Step 3: Get per-shot looks supported.
In the top example, look_di.cc, being a relative path location, will check each location in the config’s search_path. The first file that’s found will be used.
So if your config contains:
search_path: luts
… then only the ‘luts’ subdir relative to the OCIO config will be checked.
However if you specify:
search_path: /shots/show/$SHOT/cc/data:luts
…the directory ‘/shots/show/$SHOT/cc/data/’ will be evaluated first, and only if not found will the ‘luts’ directory be checked.
env-vars, absolute, and relative paths can be used both in the config’s
search_path
, as well as the View’s src specification.
Example:
- !<Look>
name: di
process_space: rclg16
transform: !<FileTransform> {src: looks/$SHOT_di/current/look_$SHOT_di.cc, interpolation: linear}
Note that if the per-shot lut is not found, you can control whether a fallback LUT succeeds based on if it’s in the main location. You can also use this for multiple levels (show, shot, etc).
Advanced option: If some shots use .cc files, and some use 3d-luts currently there’s no simple way to handle this. What we’d recommend as a work around is to label all of your files with the same extension (such as .cc), and then rely on OCIO’s resilience to misnamed lut files to just load them anyways. Caveat: this only works in 1.0.1+ (commit sha-1: 6da3411ced)
Advanced option: In the Nuke OCIO nodes, you often want to preview
looks ‘across shots’ (often for reference, same-as, etc). You can
override the env-vars in each node, using the ‘Context’ menu. For
example, if you know that $SHOT is being used, in the context key1 you
should specify ‘SHOT’, and the in value1 specify the shot to use (such
as dev.lookdev). You can also use expressions, to say parse a shot
name out of [metadata "input/filename"]
Advanced option: If you are writing your own OCIO integration code,
getProcessor
will fail if the per-shot lut is not found, and you
may want to distinguish this error from other OCIO errors. For this
reason, we provide OCIO::ExceptionMissingFile, which can be explicitly
caught (this can then handled using
OCIO::DisplayTransform::setLooksOverride()
). I’d expect image
flipbook applications to use this approach.
Contexts Example¶
Warning
This section is from OCIO v1 and has not been updated yet.
OCIO’s allows different LUT’s or grades to be applied based on the current context.
These contexts are usually based on environment variables, but also allows on-the-fly context switching in applications that operate on multiple shots (such as playback tools)
Typically these would be used as part of the display transform, to apply shot-specific looks (such as a CDL color correction, or a 1D grade LUT)
A contrived example¶
The simplest way to explain this feature is with examples. Say we have
two shots, ab-123
and sf-432
, and each shot requires a
different LUT to view. The current shot name is stored in the
environment variable SHOT.
In the OCIO config, you can use this SHOT environment variable to
construct the LUT’s path/filename. This path can be absolute (e.g
/example/path/${SHOT}.spi1d
), or relative to any directory on the
OCIO search path, which includes the resource path (e.g
${SHOT}.spi1d
)
This is a simplified example, to demonstrate the context feature. Typically this “contextual LUT” would be used in conjunction with other LUT’s (e.g before a scene-linear to log transform, followed by a 3D film emulation LUT), this will be covered in Per-shot grades
So, we have our empty OCIO config in ~/showcfg
, and our two LUTs
in ~/showcfg/luts
which are named af-123.spi1d
and
sf-432.spi1d
:
~/showcfg/
config.ocio
luts/
af-123.spi1d
sf-432.spi1d
In the config, we first specify the config version, and the resource
path (usually this is relative to the directory containing
config.ocio
, although can be an absolute path):
ocio_profile_version: 1
resource_path: luts
Next, we define a colorspace that transforms from the show reference space to the display colorspace:
colorspaces:
- !<ColorSpace>
name: srgb8
family: srgb
bitdepth: 8ui
from_reference: !<FileTransform> {src: ${SHOT}.spi1d}
Then add a display alias for this transform:
displays:
- !<Display> {device: sRGB, name: "Shot LUT", colorspace: srgb8}
Finally, we point the OCIO env-variable to the config, set the SHOT env-variable to the shot being worked on, and launch Nuke (or any other OCIO-enabled application):
export OCIO=~/showcfg/config.ocio
export SHOT=af-123
nuke
In Nuke, we create an OCIODisplay node, select our “sRGB” device with
the “Shot LUT” transform, and this will apply the af-123.spi1d
LUT.
Per-shot grades¶
Similarly to LUTs, we use a .cc
file (an XML file containing a
single ASC CDL <ColorCorrection>
), or a .ccc
file (an XML file
containing multiple ASC CDL color corrections, each with a unique ID)
The .cc
file is applied identically to a regular LUT files, using
a FileTransform
. For example, if we have af-123.cc
in the
luts/
directory:
<ColorCorrection id="mygrade">
<SOPNode>
<Slope>2 1 1</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
We wish to apply this grade on the scene-linear image, then transform
into log and apply a 3D print emulation LUT. Since this requires
multiple transforms, instead of using a single FileTransform
, we
use a GroupTransform
(which is is just a collection of other
transforms):
colorspaces:
- !<ColorSpace>
name: lnh
family: ln
bitdepth: 16f:
isdata: false
- !<ColorSpace>
name: lg10
family: lg
bitdepth: 10ui
isdata: false
to_reference: !<FileTransform> {src: lg10.spi1d, interpolation: nearest}
- !<ColorSpace>
name: srgb8
family: srgb
bitdepth: 8ui
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: ${SHOT}.cc}
- !<ColorSpaceTransform> {src: lnh, dst: lg10}
- !<FileTransform> {src: film_emulation.spi3d, interpolation: linear}
A .ccc file is a collection of <ColorCorrection>
’s. The only
difference is when defining the FileTransform
, you must specify
the cccdid
key, which you can also construct using the context’s
environment variables. This means we could create a grades.ccc
file containing the grade for all our shots:
<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
<ColorCorrection id="af-123">
<SOPNode>
<Slope>2 1 1</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
<ColorCorrection id="mygrade">
<SOPNode>
<Slope>0.9 0.7 0.9</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
</ColorCorrectionCollection>
And the colorspace definition to utilise this:
- !<ColorSpace>
name: srgb8
family: srgb
bitdepth: 8ui
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: grades.ccc, cccid: ${SHOT}}
- !<ColorSpaceTransform> {src: lnh, dst: lg10}
- !<FileTransform> {src: film_emulation.spi3d, interpolation: linear}
A complete example¶
Warning
This is incomplete, the lnh_graded space is likely wrong
The context feature can be used to accommodate complex grading pipelines. In this example, we have a “neutral grade” for each shot, to neutralise color casts and exposure variations, keeping plates consistent throughout a sequence.
To view a shot, we reverse this neutral grade, apply a “beauty grade”, then apply the display transform (the usual lin-to-log and a film emulation LUT)
We will use the same two example shots from before, af-123 (which is in the af sequence) and sg-432 (in the sg sequence). Imagine we have many shots in each sequence, so we wish to put the grades for each sequence in a separate file.
Using the same directory structure as above, in ~/showcfg/luts
we
first create two grade files, grades_af.ccc
:
<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
<ColorCorrection id="af/af-123/neutral">
<SOPNode>
<Slope>2 1 1</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
<ColorCorrection id="af/af-123/beauty">
<SOPNode>
<Slope>1.5 1.2 0.9</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>0.8</Saturation>
</SatNode>
</ColorCorrection>
<!-- More ColorCorrection's... -->
</ColorCorrectionCollection>
And grades_sg.ccc
:
<ColorCorrectionCollection xmlns="urn:ASC:CDL:v1.2">
<ColorCorrection id="sg/sg-432/neutral">
<SOPNode>
<Slope>0.9 0.7 0.9</Slope>
<Offset>0 0 0</Offset>
<Power>1 1 1</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
<ColorCorrection id="sg/sg-432/beauty">
<SOPNode>
<Slope>1.1 0.9 0.8</Slope>
<Offset>0 0 0</Offset>
<Power>1.2 0.9 1.5</Power>
</SOPNode>
<SatNode>
<Saturation>1</Saturation>
</SatNode>
</ColorCorrection>
<!-- More ColorCorrection's.. -->
</ColorCorrectionCollection>
Next, we create the config.ocio
file, containing a colorspace to
define several colorspaces:
lnh
, the scene-linear, 16-bit half-float space in which compositing will happenlg10
, the 10-bit log space in which material will be received (e.g in .dpx format)srgb8
, the display colorspace, for viewing the neutrally graded footage on an sRGB displaysrgb8graded
, another display colorspace, for viewing the final “beauty grade”
ocio_profile_version: 1
# The directory relative to the location of this config
resource_path: "luts"
roles:
scene_linear: lnh
compositing_log: lgf
displays:
# Reference to display transform, without reversing the working grade
- !<Display> {device: sRGB, name: Film1D, colorspace: srgb8}
# Reference to display, reversing the working grade, and applying
# the beauty grade
- !<Display> {device: sRGB, name: Film1DGraded, colorspace: srgb8graded}
colorspaces:
# The source space, containing a log to scene-linear LUT
- !<ColorSpace>
name: lg10
family: lg
bitdepth: 10ui
isdata: false
to_reference: !<FileTransform> {src: lg10.spi1d, interpolation: nearest}
# Our scene-linear space (reference space)
- !<ColorSpace>
name: lnh
family: ln
bitdepth: 16f
isdata: false
# Neutrally graded scene-linear
- !<ColorSpace>
name: lnh_graded
family: ln
bitdepth: 16f
isdata: false
to_reference: !<FileTransform> {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/neutral"}
# The display colorspace - how to get from scene-linear to sRGB
- !<ColorSpace>
name: srgb8
family: srgb
bitdepth: 8ui
isdata: false
from_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: lnh, dst: lg10}
- !<FileTransform> {src: lg_to_srgb.spi3d, interpolation: linear}
# Display color, with neutral grade reversed, and beauty grade applied
- !<ColorSpace>
name: srgb8graded
family: srgb
bitdepth: 8ui
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/neutral", direction: inverse}
- !<FileTransform> {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/beauty", direction: forward}
- !<ColorSpaceTransform> {src: lnh, dst: srgb8}
How to Configure ColorSpace Allocation¶
The allocation / allocation vars were utilized using during GPU 3dlut / shader text generation in OCIO v1. However in OCIO v2, the GPU renderer does not need to bake color transforms and the allocation vars are not utilized unless an application requests the legacy GPU shader. However, the allocation vars are still utilized by the ociobakelut command-line utility.
If, in the course of baking, a 3D lut is required, the “allocation / allocation vars” direct how OCIO should sample the colorspace, with the intent being to maintain maximum fidelity and minimize clamping.
Currently support allocations / variables:
- ALLOCATION_UNIFORM::
2 vars: [min, max]
- ALLOCATION_LG2::
2 vars: [lg2min, lg2max] 3 vars: [lg2min, lg2max, linear_offset]
So say you have an srgb image (such as an 8-bit tif), where you know the data ranges between 0.0 - 1.0 (after converting to float). If you wanted to apply a 3d lut to this data, there is no danger in sampling that space uniformly and clamping data outside (0,1). So for this colorspace we would tag it:
allocation: uniform
allocationvars: [0.0, 1.0]
These are the defaults, so the tagging could also be skipped.
But what if you were actually first processing the data, where occasionally small undershoot and overshoot values were encountered? If you wanted OCIO to preserve this overshoot / undershoot pixel information, you would do so by modifying the allocation vars.
allocation: uniform
allocationvars: [-0.125, 1.125]
This would mean that any image data originally within [-0.125, 1.125] will be preserved during GPU processing. (Protip: Data outside this range may actually be preserved in some circumstances - such as if a 3d lut is not needed - but it’s not required to be preserved).
So why not leave this at huge values (such as [-1000.0, 1000.0]) all the time? Well, there’s a cost to supporting this larger dynamic range, and that cost is reduced precision within the 3D luts sample space. So in general you’re best served by using sensible allocations (the smallest you can get away with, but no smaller).
Now in the case of high-dynamic range color spaces (such as float linear), a uniform sampling is not sufficient because the max value we need to preserve is so high.
Say you were using a 32x32x32 3d lookup table (a common size). Middle gray is at 0.18, and specular values are very much above that. Say the max value we wanted to preserve in our coding space is 256.0, each 3d lut lattice coordinates would represent 8.0 units of linear light! That means the vast majority of the perceptually significant portions of the space wouldn’t be sampled at all!
unform allocation from 0-256: 0 8.0 16.0 … 240.0 256.0
So another allocation is defined, lg2
- !<ColorSpace>
name: linear
description: |
Scene-linear, high dynamic range. Used for rendering and compositing.
allocation: lg2
allocationvars: [-8, 8]
In this case, we’re saying that the appropriate ways to sample the 3d lut are logarithmically, from 2^-8 stops to 2^8 stops.
Sample locations: 2^-8: 0.0039 2^-7: 0.0078 2^-6: 0.0156 … 2^0: 1.0 … 2^6: 64.0 2^7: 128.0 2^8: 256.0
Which gives us a much better perceptual sampling of the space.
The one downside of this approach is that it can’t represent 0.0, which is why we optionally allow a 3d allocation var, a black point offset. If you need to preserve 0.0 values, and you have a high dynamic range space, you can specify a small offset.
Example:
allocation: lg2
allocationvars: [-8, 8, 0.00390625]
The [-15.0, 6.0] values in spi-vfx come from the fact that all of the linearizations provided in that profile span the region from 2^-15 stops, to 2^6 stops. One could probably change that black point to a higher number (such as -8), but if you raised it too much you would start seeing black values be clipped. Conversely, on the high end one could raise it a bit but if you raised it too far the precision would suffer around gray, and if you lowered it further you’d start to see highlight clipping.