From BlenderWiki

Jump to: navigation, search

Color Management

There were already couple of pages related on color management and OpenColorIO integration, like this. That documents are already out of date a bit.I n this article i would keep all the information about color management project going on in tomato branch in out SVN repository.

Internal color spaces

Depending on the image Blender stores it either in sRGB or linear space. This depends on whether the image is float or byte. In some rare cases Blender could use byte image format as linear, but that's an exception for few formats only.

When linear float image is displaying on the screen additional buffer is creating for this image. This is a byte buffer which is calculating from linear buffer using linear-to-sRGB conversion. This buffer is used only for display, none of other areas are using it.

Current Goals

When conversion from linear float to sRGB byte happens values outside of 0..1 range are being clamped. This makes image flat and eliminates all the dynamic ranges from original linear files.

One of current goals is to make displaying of float buffers on the display nice looking, avoiding clamping color ranges and making wider color ranges be displayed.

Another current goal is to make color grading pipeline working in actual display space with tone map applied.

Color Transformations

There're two transformations of color involved into color managed pipeline.

First transformation happens when float image is loading into Blender. This transformation is usually called input transformation.

Input transformation converts image from file color space into Blender's linear space, so image could be used in renderer, compositor, sequencer and so.

Colro transforms happening in Blender

Blender's internal linear color space is called working space

Second transformation happens when float image is displaying on the screen. This transformation is usually called display transformation

Display transformation converts image from working space into display space. Display space is defined by two properties: Display Device (which is usually sRGB display) and view. View is a meaningful view of working space on a Display (e.g a film emulation view on an sRGB display device).

Blender Pipeline

File Color space is a per-image property which could be changed manually. It's planned to support configurable default file color space for byte and float images which would match particular production.

Display Transform is a per-scene setting, which affects on any area which should deal with buffers in display space (i.e. by Image Editor when it draws image).

Renderer and Compositor are working in linear space which is Scene Linear space defined in configuration file.


Sequencer is always working in Display Space, so it behaves differently from other parts of a pipeline.

There two possible scenarios: using byte and float buffers in sequencer.

When byte buffer is used in sequencer it assumes that this buffer is already in Display Space and does not perform any additional color transformations:

Byte Buffers flow in Sequencer

When float buffers are used in sequencer, they're converting to Display Space before they're used in sequencer. This would nean that sequencer would output float buffer in non-linear space which is not always possible to convert back to linear. In our pipeline it's not needed -- we assumes that sequencer always saves files in display space, not linear space.

Float Buffers flow in Sequencer

OCIO Configuration

OpenColorIO library is used for color space conversion needs. Mainly OCIO was chosen because it allows to have unified color settings across all applications used in production pipeline.

Currently used configuration is based on ACES OCIO configuration, which was changed to match Blender's internals beings and current usecase of color management.

Scene's linear space was changed to rec709. This is because Blender's linear space is really close to this space and using it makes compositing renders into files correct. Technically speaking any linear space could be used as scene linear, it could only require some additional tweaks to colors on rendered scenes.

Additional view transformation from nuke-default and spi-vfx configuration were added. This introduces more freedom for artists to explore dynamic ranges from linear images.


To correctly determine the luminance weights for an RGB triplet, one must know the reference space primary lights. The resulting single value is an average of the three RGB channels based on the luminance, or Y, of each primary light.

Given that an artist or small studio may be using unique OCIO configurations, it is mandatory to use the OCIO configuration to determine the weights, as the reference space primaries may be unique.


  • Luminance refers to a weighted average for radiometrically linear values. Referred to as Y, from the XYZ primary position.
  • Luma refers to a weighted average luminance after a nonlinear transfer curve has been applied.

Both forms Y and Y' use precisely the same luminance coefficients, regardless as to whether the source image was nonlinear or linearized. The term difference results from the fact that some hacks concatenate the weights down to a single weight that combines both tone / transfer curve inversion and luminance coefficients into a single value. Given the complexities of color management in a color managed system however, hard coded values will break color management.

Linearizing, Transfer / Tone Curving

If a developer needs to linearize a value prior to determining the luminance weighting, they must use the appropriate OCIO implementation to linearize it to the reference space. This is because every RGB colorspace has a unique transfer curve, and as such, there is no method to use hard coded values. Do not use the hard coded functions in BLI_math_color.h, as they may not properly reflect the reference space.


The weights are always gleaned from the XYZ positions, in particular, the Y position, of the primaries for a given RGB colorspace.

For example, the matrix transformation for D65 sRGB / 709 (they share the same primaries) is:

           R          G          B
    X 0.4124564  0.3575761  0.1804375
    Y 0.2126729  0.7151522  0.0721750
    Z 0.0193339  0.1191920  0.9503041

The luma / luminance weights therefore are 0.2126729 R, 0.7151522 G, and 0.0721750 B. The coefficients sum to 1.0.

These weights are kept within the OpenColorIO configuration file:

luma: [Y.RED, Y.GREEN, Y.BLUE]