OpenColorIO Color Management System - Study Notes
What Is OpenColorIO (OCIO)
OpenColorIO (OCIO) is a complete color management solution aimed primarily at film production, with a particular focus on visual effects (VFX) and computer animation. It helps implement the management methods required for high-fidelity color imaging in modern computer graphics.
Core Concepts
OCIO’s color science knowledge comes entirely from its execution of the transforms defined in an OCIO config file. These transforms can be:
- Defined by the end user in a custom OCIO config file
- Inherited from publicly available configs (such as ACES)
By specifying the desired config.ocio file in your local environment, all OCIO-compatible applications and software libraries will recognize the color transform “universe” you’ve defined, and guide image data from one defined OCIO.ColorSpace to another.
OCIO Architecture
Configs
A config is the top-level entity, representing the entirety of the current color “universe.” Configs are serialized to .ocio files, read at runtime, and are typically used in a “read-only” context.
Example configs:
- ACES - The Academy of Motion Picture Arts and Sciences standardized color workflow
- spi-vfx - Some VFX projects from Sony Pictures Imageworks (e.g., Spider-Man)
- aces_1.0.3 - ACES 1.0.3 stable release
- aces_2.0.0+ - ACES 2.0 config (built into OCIO 2.5+)
Note: The OpenColorIO-Configs repository was archived as read-only in September 2025. It’s recommended to use the ACES config built into OCIO, or obtain configs from other sources.
ColorSpaces
A ColorSpace typically corresponds to:
- An input image state
- An output image state
- An image state used for internal processing
ColorSpace examples (from the ACES config):
aces- HDR, scene-linearadx10- Log-like density encoding spaceslogf35- Sony F35 slog camera encodingrrt_srgb- Baked display transform for sRGB displaysrrt_p3dci- Baked display transform for DCI-P3 displays
Transforms
ColorSpaces contain an ordered list of transforms that define how to convert to and from the config’s “reference” space.
Transform types:
OCIO 1.x / 2.x common types:
- FileTransform - File-based transforms (1D LUT, 3D LUT, CLF/CTF files, matrix files, etc.)
- GroupTransform - Contains an ordered list of transforms
- LookTransform - Color transform for applying creative looks
- CDLTransform - ASC CDL (Color Decision List)
- MatrixTransform - Matrix transform
- LogTransform - Log/anti-log transform
- ExposureTransform - Exposure adjustment (in stops)
New types added in OCIO 2.0+:
- BuiltinTransform - Built-in transforms that require no external files (used extensively in the ACES 2.0 config)
- ViewTransform - Display/view transforms
- NamedTransform - A standalone color transform not bound to a specific color space
- ColorSpaceTransform - Color space conversion
- AllocationTransform - Range allocation transform
- GradingPrimaryTransform - Primary grading (brightness, contrast, saturation)
Processors
A processor represents one “baked” color conversion. When querying a processor, you specify two parameters:
- The source color space (colorspace_section)
- The destination color space (colorspace_section)
Major changes in OCIO 2.x:
- New config file format (
.ociov2)- New ViewTransform and DisplayView color space types
- New BuiltinTransform — use common transforms without external files
- Built-in ACES 2.0 config support
- Improved GPU code generation and performance optimizations
Code example (OCIO 1.x API):
Note: The following example uses the OCIO 1.x API. OCIO 2.0+ has API changes but maintains backward compatibility.
1 |
|
ACES 1.0.3 Color Spaces - A Detailed Look
ACES Color Spaces
| Color Space | Description |
|---|---|
| ACES2065-1 | Core working and exchange space (AP0 primaries, linear, used for archiving) |
| ACEScc | Image editing space, pure log encoding (AP1 primaries) |
| ACEScct | Color correction transfer space, pseudo-log encoding (AP1 primaries, linear near black) |
| ACESproxy | Proxy working space, integer encoded |
| ACEScg | Scene-linear space for rendering (AP1 primaries) |
ACEScc vs ACEScct: Both use AP1 primaries, but ACEScc is pure log encoding suited for traditional grading workflows; ACEScct is pseudo-log encoded with a linear segment near black, more closely resembling native camera response.
Output Color Spaces
| Color Space | Notes |
|---|---|
| sRGB | Standard monitor |
| sRGB (D60 sim.) | D60-simulated sRGB |
| Rec.709 | HD television standard |
| Rec.2020 | UHD television standard |
| Rec.2020 ST2048 (1000 nits) | HDR at 1000 nits |
| DCDM | Digital Cinema Distribution Master |
| P3-D60 | DCI-P3 gamut, D60 white point |
| P3-D60 ST2048 (1000/2000/4000 nits) | HDR gamut, multiple brightness levels |
Input Color Spaces
Input color spaces cover different camera manufacturers, gamut ranges, transfer functions, and camera parameter settings:
Naming conventions:
Manufacturer 'Format - Gamut'- Full conversion scheme- Example:
ARRI 'V3 LogC (EI160) - Wide Gamut' - Example:
RED 'REDlogFilm - DRAGONcolor2' - Example:
Canon 'Canon-Log - DCI-P3 Daylight'
- Example:
Linear - Gamut- Gamut conversion only, no transfer function appliedCurve - CurveName- Transfer function only, no gamut conversion
Supported manufacturers:
- ARRI (LogC series)
- RED (REDlogFilm, REDgamma)
- Canon (C-Log)
- Panasonic (V-Log/V-Gamut)
- Sony (S-Log)
- GoPro (experimental)
ADX Color Spaces
ADX (Academy Density Exchange) spaces are specifically for film scanning and printing workflows:
- ADX10 - 10-bit film scan
- ADX16 - 16-bit film scan
Conversion schemes are generated based on the ACES CTL transform standard.
Functional Role Spaces (Roles)
OCIO roles map abstract color space names to concrete implementations:
| Role | Points To | Purpose |
|---|---|---|
| color_picking | Output - Rec.709 | Color picking |
| color_timing | ACEScc | Color correction |
| compositing_log | ADX10 | Compositing log |
| data | Raw | Data channels |
| default | ACES2065-1 | Default space |
| matte_paint | ACEScc | Matte painting |
| reference | Raw | Reference space |
| scene_linear | ACEScg | Scene-linear |
| texture_paint | Raw | Texture painting |
| compositing_linear | ACEScg | Compositing linear |
| rendering | ACEScg | Rendering |
Display Devices and Views
The default config contains a display device called “ACES” with the following views:
| View Name | Color Space |
|---|---|
| sRGB | sRGB |
| sRGB D60 sim. | sRGB (D60 sim.) |
| DCDM | DCDM |
| DCDM P3 gamut clip | DCDM (P3 gamut clip) |
| P3-D60 | P3-D60 |
| P3-D60 PQ 1000/2000/4000 nits | P3-D60 PQ (1000/2000/4000 nits) |
| P3-DCI | P3-DCI |
| Rec.2020 | Rec.2020 |
| Rec.2020 ST2048 1000 nits | Rec.2020 ST2048 (1000 nits) |
| Rec.709 | Rec.709 |
| Rec.709 D60 sim. | Rec.709 (D60 sim.) |
| Raw | Raw |
| Log | ACEScc |
Sony Pictures Imageworks (SPI) Color Pipeline in Practice
File Naming Conventions
Every image on disk has a substring in its filename that encodes color space information. All applications that load, write, or display images respect this convention.
Important:
- File extensions and metadata are ignored for color processing purposes
- The file format extension does not imply a color space
Examples:
| Filename | Color Space |
|---|---|
| colorimage_lnf.exr | lnf (linear float) |
| dataimage_ncf.exr | ncf (non-color float) |
| plate_lg10.dpx | lg10 (log 10-bit) |
| texture_dt8.tif | dt8 (diffuse texture 8-bit) |
Common File Formats
| Purpose | Format |
|---|---|
| Render output | exr |
| Render input (mipmap textures) | exr, tif (txtif) |
| Film negative (scanned) | dpx |
| Composite output | dpx, exr |
| On-set reference | NEF, CR2, and other camera raw formats |
| Painted textures | psd, tif |
| Output proxies | jpg |
Rendering Pipeline
Rendering and shading happen in scene-linear floating-point space:
- ln - Scene-linear (generic)
- lnh - 16-bit half-float scene-linear
- lnf - 32-bit full-float scene-linear
Rules:
- All image inputs should be converted to ln before rendering
- This is typically done at texture publish time
- Renderer output is always in floating-point format
- Color output is typically stored as lnh (16-bit half-float)
- Data output (normals, depth data, etc.) is stored as ncf (“non-color” data, 32-bit full-float)
- Lossy compression is never used
Texture Painting / Matte Painting
Texture painting workflow:
- Original texture filenames include color space information
- Color processing (linearization) is applied before mipmap generation
- This ensures energy conservation in the renderer
- If you process in the opposite order, the apparent intensity of texture values changes as objects move closer to or farther from the camera
Texture type classification:
| Texture Type | Color Space Tag | Notes |
|---|---|---|
| Data textures (bump, opacity, blend maps) | nc (non-color) + bit depth | e.g., skin_opacity_nc8.tif |
| Diffuse textures | dt (diffuse texture) | The dt8 color space is designed so values don’t exceed 1.0 after linearization |
| Environment maps (emissive) | vd (video) | May produce highlight values well above 1.0 after linearization |
Bit depth promotion:
- Even if the original painted texture is only 8-bit, mipmap textures are stored as 16-bit floating-point images
- Linear textures require more storage space
Tools:
- OpenImageIO’s
maketx(linked to OpenColorIO) - Source code available in the public OIIO repository
Compositing Pipeline
Most compositing operations happen in scene-linear lnf color space:
Input stage
- All image inputs are linearized to lnf on load
- Custom input nodes make this process convenient
- Rendered elements (already stored as linear) require no processing
- Film negatives are linearized based on source type (lg10 for film scans, gn10 for Genesis, etc.)
Output stage
- All output images are de-linearized from lnf on write
- Custom output nodes make this process convenient
Log data operations
- Certain processing operations require log data
- Film resize, keying, degrain, etc.
- Each project specifies a color space suitable for this
- Artists don’t need to track which color space is appropriate
- The OCIOLogConvert node is always used for this purpose
- In the OCIO config, this is specified using the ‘compositing_log’ role
Color Management Best Practices
Environment Variables
$OCIO- The environment variable is set during the “setshot” process before launching other applications- Artists are not allowed to work across different projects without using a new shell + setshot
Color Configs
- Color configs are project-specific
- While the list of color spaces may be project-specific, naming is kept as consistent as possible across projects
- Even if two projects don’t use exactly the same color spaces, they use the same names if the spaces serve similar purposes
Example: 10-bit scanned film negatives are labeled lg10. Even if two different projects use different capture film stocks and rely on different linearization curves, both are labeled lg10.
Cross-Project Asset Transfer
There is no explicit guarantee that image assets copied across projects will transfer in a color-correct manner.
Example: In the film scan example, linearized versions of scans processed on different projects may not match.
In practice, this isn’t a serious problem — color spaces that are convenient to copy (such as texture assets) happen to be defined similarly across project configs.
LUT Generation and Usage
Default Resolutions
- 3D LUT: 65x65x65
- 1D LUT: 4096
OCIO Internal LUTs
- LUTs used internally by OCIO are available from the repository
- Used for internal color processing
Pre-generated LUTs
LUTs located in the baked directory can be used outside of OCIO.
LUT naming convention:
1 | [Output transform name] for [Input color space name].[extension] |
Example: sRGB (D60 sim.) for ACEScc.icc
Supported application formats:
| Extension | Application |
|---|---|
| .3dl | Autodesk Flame, Autodesk Lustre |
| .lut | SideFX Houdini |
| .csp | Autodesk Maya |
| .icc | Adobe Photoshop |
OpenColorIO Internal Processing Architecture
Op Abstraction
Why not rely on transforms to perform pixel processing directly?
- FileTransform represents a wide range of image processing operations
- For example: A Houdini LUT format may include a log transform, a 1D LUT, and a 3D LUT all within a single file
- Creating lightweight processing operations (ops) is much simpler
Op interface:
1 | virtual void apply(float * rgbaBuffer, long numPixels) |
Given a packed float array and a specified pixel count, process them.
Op type examples:
- Lut1DOp
- Lut3DOp
- MtxOffsetOp
- LogOp
Optimization Flow
- A Transform converts itself into a list of Ops
- The Op list is optimized (folded with adjacent operations as appropriate, etc.)
- This is highly beneficial for optimization, since compositors typically have complex, branching image processing operation trees
CPU Code Path
- The main Op list is optimized and stored inside the processor
- A small tile of pixels from the image is formatted into a contiguous RGBA block
op->applyis called in-place for each Op
Tile size: Optimized for compute (SSE) simplicity and performance, typically similar in size to an image scanline
GPU Code Path
The main Op list is divided into 3 ordered lists:
- gpu-preops - Operations that can be resolved in shader code
- gpu-postops - Operations that can be resolved in shader code
- gpu-latticeops - Cannot be supported by shader code; baked into a 3D LUT
Allocation optimization:
- Op stream metadata is analyzed between gpu-preops and gpu-latticeops
- An appropriate allocation is determined to minimize clamping, quantization, etc.
- Resolved by inserting a forward allocation at the end of the preops and a reverse allocation at the start of the lattice ops
Building and Installing
Dependencies
- OpenImageIO - http://openimageio.org
- OpenColorIO - http://opencolorio.org
- CTL - https://github.com/ampas/CTL
macOS Build Commands
1 | # Install OpenColorIO (current Homebrew method) |
Note: The following are historical commands (now outdated) included for reference only:
brew tap homebrew/science— this tap was deprecated in 2023brew install --with-python— compile options were removed in Homebrew 2.0+- The
ociolutimagetool is still available in OCIO 2.x, but the build process has been simplified
Getting ACES CTL Source
Note: The ACES project has migrated to a new organization repository.
Official ACES repositories:
- ACES Central repository: https://github.com/aces-aswf/aces
- OpenColorIO ACES Config: https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES
- CTL runtime: https://github.com/ampas/ctl
Historical versions (for reference only):
1 | # ACES 1.0.3 historical version (old repository) |
Python Config Generation
Configs can be generated via the following Python package:
1 | cd aces_1.0.3/python |
User-customizable features:
- 1D LUT and 3D LUT resolution settings
- Custom Look integration
- Two generation modes for the OCIO display device and view list
- Shaper function selection: Log2 or Dolby PQ
Notes on Using OCIO in UE5
Known Issues
UE5.3–5.4 has some known OpenColorIO-related issues:
- “OCIO Invalid” watermark error — When using the ACES OpenColorIO config, Composure output may display this error
- Viewport color discrepancies — UE5.3 projects opened in UE5.4 may exhibit viewport color differences
- Material Editor display issues — Some users report that HDR textures encoded as Linear with ACEScg color space may display incorrectly on sRGB monitors
Recommendation: When you encounter issues, check the latest discussions on the Epic official forums, or consider upgrading to a newer version of UE5.
Color Space Setup Recommendations
When doing color management in UE:
- Set the working color space to ACES AP1/ACEScg
- Load the OCIO config file
- Add color spaces in OCIO:
- Lit
- OCIO Display
- Select the OCIO Asset
- From ACEScg to Rec.709 - ARRI ALF2 or ARRI Reveal
Glossary
| Term | Notes |
|---|---|
| Transform | A function that changes RGB(A) data (e.g., converting an image from scene-linear to sRGB) |
| Reference space | The connecting space between color spaces |
| Colorspace | A meaningful space that can be converted to and from the reference space |
| Display | A virtual or physical display device (e.g., an sRGB display) |
| View | A meaningful view of the reference space on a display device |
| Role | An abstractly named color space |
| Look | A color transform that applies a creative look |
References
Official Documentation
- OpenColorIO official docs: https://opencolorio.readthedocs.io
- ACES Central official repository: https://github.com/aces-aswf/aces
- OpenColorIO-Config-ACES: https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES
- OpenColorIO GitHub: https://github.com/AcademySoftwareFoundation/OpenColorIO
Classic Documents
- Jeremy Selan’s “Cinematic Color” document
- Sony Pictures Imageworks color pipeline documentation
- SPI-VFX Config Documentation
Historical References (Archived)
- OpenColorIO-Configs repository (archived September 2025)