OpenColorIO 色彩管理系统学习笔记

OpenColorIO 色彩管理系统学习笔记

什么是 OpenColorIO (OCIO)

OpenColorIO (OCIO) 是一个完整的色彩管理解决方案,主要面向电影制作,尤其侧重于视觉效果 (VFX) 和计算机动画。它有助于执行现代计算机图形学中高保真色彩成像所需的管理方法。

核心概念

OCIO 的色彩科学知识完全来自于其对 OCIO 配置文件中所定义变换的执行。这些变换可以:

  • 由最终用户在自定义的 OCIO 配置文件中定义
  • 继承自公开可用的配置文件(如 ACES)

通过在本地环境中指定所需的 config.ocio 配置文件,所有兼容 OCIO 的应用程序和软件库都将能够识别您定义的色彩变换”宇宙”,并指导图像数据从一个定义的 OCIO.ColorSpace(色彩空间)转换到另一个色彩空间。

OCIO 架构

配置 (Configs)

配置是最高层级,代表了当前色彩”宇宙”的全部。配置被序列化为 .ocio 文件,在运行时读取,通常用于”只读”上下文。

示例配置:

  • ACES - 电影艺术与科学学院的标准化色彩工作流程
  • spi-vfx - 索尼影像工作室的一些 VFX 项目(如蜘蛛侠等)
  • aces_1.0.3 - ACES 1.0.3 稳定版本
  • aces_2.0.0+ - ACES 2.0 配置(内置在 OCIO 2.5+ 中)

注意: OpenColorIO-Configs 仓库已于 2025 年 9 月被归档为只读状态,建议使用 OCIO 内置的 ACES 配置或从其他来源获取。

色彩空间 (ColorSpaces)

ColorSpace 通常对应于:

  • 输入图像状态
  • 输出图像状态
  • 用于内部处理的图像状态

色彩空间示例(来自 ACES 配置):

  • aces - HDR, 场景线性
  • adx10 - 类似对数的密度编码空间
  • slogf35 - 索尼 F35 slog 相机编码
  • rrt_srgb - 烘焙的显示变换,适用于 sRGB 显示
  • rrt_p3dci - 烘焙的显示变换,适用于 DCI-P3 显示

变换 (Transforms)

ColorSpaces 包含一个有序的变换列表,这些变换定义了转换到配置的”参考 (reference)”空间和从参考空间转换过来的方法。

Transforms 类型:

OCIO 1.x / 2.x 通用类型:

  • FileTransform - 基于文件的变换(1D LUT, 3D LUT, CLF/CTF 文件, 矩阵文件等)
  • GroupTransform - 包含一个有序的变换列表
  • LookTransform - 应用创意外观的色彩变换
  • CDLTransform - ASC CDL(Color Decision List)
  • MatrixTransform - 矩阵变换
  • LogTransform - 对数/反对数变换
  • ExposureTransform - 曝光调整(以档为单位)

OCIO 2.0+ 新增类型:

  • BuiltinTransform - 内置变换,无需外部文件(ACES 2.0 配置大量使用)
  • ViewTransform - 显示/视图变换
  • NamedTransform - 独立的色彩变换,不绑定到特定色彩空间
  • ColorSpaceTransform - 色彩空间转换
  • AllocationTransform - 范围分配变换
  • GradingPrimaryTransform - 一级调色(亮度、对比度、饱和度)

处理器 (Processors)

一个 processor 对应一个”烘焙”的色彩转换。在查询处理器时指定两个参数:

  • 来自的色彩空间 (colorspace_section)
  • 前往的色彩空间 (colorspace_section)

OCIO 2.x 主要变化:

  • 新的配置文件格式(.ocio v2)
  • 新增 ViewTransform 和 DisplayView 色彩空间类型
  • 新增 BuiltinTransform,无需外部文件即可使用常用变换
  • 内置 ACES 2.0 配置支持
  • 改进的 GPU 代码生成和性能优化

代码示例(OCIO 1.x API):

注意: 以下示例使用 OCIO 1.x API。OCIO 2.0+ 有 API 变化,但保持向后兼容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;

try
{
// 获取全局 OpenColorIO 配置
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

// 获取处理器
OCIO::ConstProcessorRcPtr processor = config->getProcessor("adx10", "aces");
OCIO::ConstCPUProcessorRcPtr cpu = processor->getDefaultCPUProcessor();

// 将图像包装在轻量级的 ImageDescription 中
OCIO::PackedImageDesc img(imageData, w, h, 4);

// 应用色彩变换(原地)
cpu->apply(img);
}
catch(OCIO::Exception & exception)
{
std::cerr << "OpenColorIO Error: " << exception.what() << std::endl;
}

ACES 1.0.3 色彩空间详解

ACES 颜色空间

色彩空间 描述
ACES2065-1 核心工作空间与交换空间(AP0 原色,线性,用于归档)
ACEScc 影像编辑空间,纯对数编码(AP1 原色)
ACEScct 色彩校正转换空间,pseudo-log 编码(AP1 原色,黑场附近线性)
ACESproxy 代理工作空间,整数编码
ACEScg 场景线性空间,用于渲染(AP1 原色)

ACEScc vs ACEScct: 两者都使用 AP1 原色,但 ACEScc 是纯对数编码,适合传统调色流程;ACEScct 是 pseudo-log 编码,在黑场附近保持线性,更接近相机原生响应。

输出颜色空间

色彩空间 说明
sRGB 标准显示器
sRGB (D60 sim.) D60 模拟的 sRGB
Rec.709 HD 电视标准
Rec.2020 UHD 电视标准
Rec.2020 ST2048 (1000 nits) HDR 1000 尼特
DCDM 数字电影发行母版
P3-D60 DCI-P3 色域,D60 白点
P3-D60 ST2048 (1000/2000/4000 nits) HDR 色域,多亮度级别

输入色彩空间

输入色彩空间覆盖不同摄像机厂商、色域范围、传递函数及相机参数设置:

命名规则:

  • 厂商 '格式 - 色域' - 完整转换方案

    • 例:ARRI 'V3 LogC (EI160) - Wide Gamut'
    • 例:RED 'REDlogFilm - DRAGONcolor2'
    • 例:佳能 'Canon-Log - DCI-P3 Daylight'
  • Linear - 色域 - 仅色域转换,不应用传递函数

  • Curve - 曲线 - 仅应用传递函数,不执行色域转换

支持的厂商:

  • ARRI (LogC 系列)
  • RED (REDlogFilm, REDgamma)
  • 佳能 (C-Log)
  • 松下 (V-Log/V-Gamut)
  • 索尼 (S-Log)
  • GoPro(实验性)

ADX 颜色空间

ADX (Academy Density Exchange) 空间专用于胶片扫描与印片流程:

  • ADX10 - 10 位胶片扫描
  • ADX16 - 16 位胶片扫描

转换方案基于 ACES CTL 转换标准生成。

功能角色空间 (Roles)

OCIO 角色功能用于将抽象的色彩空间名称映射到具体实现:

角色 指向色彩空间 用途
color_picking Output - Rec.709 颜色选择
color_timing ACEScc 色彩校正
compositing_log ADX10 合成对数
data Raw 数据通道
default ACES2065-1 默认空间
matte_paint ACEScc 遮罩绘制
reference Raw 参考空间
scene_linear ACEScg 场景线性
texture_paint Raw 纹理绘制
compositing_linear ACEScg 合成线性
rendering ACEScg 渲染

显示设备与视图

默认配置包含一个名为”ACES”的显示设备,该设备包含以下视图:

视图名称 色彩空间
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

索尼影视工作室 (SPI) 色彩管线实践

文件命名约定

所有磁盘上的图像,其文件名中都包含一个表示色彩空间信息的子字符串。所有加载、写入或查看图像的应用程序都遵守此约定。

重要:

  • 文件扩展名和元数据在色彩处理中被忽略
  • 文件格式扩展名并不暗示色彩空间

示例:

文件名 色彩空间
colorimage_lnf.exr lnf (线性浮点)
dataimage_ncf.exr ncf (非色彩)
plate_lg10.dpx lg10 (对数 10 位)
texture_dt8.tif dt8 (漫反射纹理 8 位)

常见文件格式

用途 格式
渲染输出 exr
渲染输入(Mipmap 纹理) exr, tif (txtif)
摄影底片(扫描) dpx
合成输出 dpx, exr
现场参考 NEF, CR2 等相机原始格式
绘制纹理 psd, tif
输出代理 jpg

渲染管线

渲染和着色发生在场景线性 (scene-linear) 浮点空间中:

  • ln - 场景线性(通用)
  • lnh - 16 位半浮点场景线性
  • lnf - 32 位全浮点场景线性

规则:

  1. 所有图像输入应在渲染前转换为 ln
    • 通常在纹理发布时完成
  2. 渲染器输出始终是浮点格式
  3. 色彩输出通常存储为 lnh (16 位半浮点)
  4. 数据输出(法线、深度数据等)存储为 ncf (“非色彩”数据,32 位全浮点)
  5. 从不使用有损压缩

纹理绘制/遮罩绘制

纹理绘制流程:

  1. 原始纹理文件名包含色彩空间信息
  2. 在生成 Mipmap 之前应用色彩处理(线性化)
    • 这是为了确保渲染中的能量守恒
    • 如果使用相反的处理顺序,纹理值的表观强度会随着物体靠近或远离相机而变化

纹理类型分类:

纹理类型 色彩空间标记 说明
数据纹理(凹凸、不透明度、混合贴图) nc (non-color) + 位深 例:skin_opacity_nc8.tif
漫反射纹理 dt (diffuse texture) dt8 色彩空间设计使得线性化后值不会超过 1.0
环境贴图(自发光) vd (video) 线性化后可能产生远高于 1.0 的高光信息

位深提升:

  • 即使原始绘制纹理仅为 8 位,Mipmap 纹理也将存储为 16 位浮点图像
  • 线性纹理需要更大的存储空间

工具:

  • OpenImageIO 的 maketx(链接到 OpenColorIO)
  • 代码可在公共的 OIIO 仓库中找到

合成管线

大多数合成操作发生在场景线性 lnf 色彩空间中:

  1. 输入阶段

    • 所有图像输入在加载时被线性化为 lnf
    • 定制的输入节点使此处理过程方便
    • 渲染元素(已存储为线性)不需要处理
    • 摄影底片根据来源类型线性化(lg10 用于胶片扫描,gn10 用于 Genesis 等)
  2. 输出阶段

    • 所有输出图像在写入时从 lnf 进行去线性化
    • 定制的输出节点使此过程方便
  3. 对数数据操作

    • 某些处理操作需要对数 (log) 数据
    • 底片调整大小、抠像、去颗粒等
    • 每个项目会指定一个适合此操作的色彩空间
    • 艺术家无需跟踪哪个色彩空间合适使用
    • OCIOLogConvert 节点始终用于此目的
      • 在 OCIO 配置文件中,这是使用 ‘compositing_log’ 角色指定的

色彩管理最佳实践

环境变量

  • $OCIO - 环境变量在”setshot”过程中设置,然后才启动其他应用程序
  • 艺术家不允许在不使用新 shell + setshot 的情况下跨不同项目工作

色彩配置

  • 色彩配置是针对特定项目的
  • 虽然色彩空间列表可以是项目特定的,但会尽可能保持相似的命名
  • 即使两个项目中的色彩空间不完全相同,如果它们用途相似,也会使用相同的名称

示例: 将 10 位扫描胶片负片标记为 lg10。即使两个不同的项目使用不同的采集胶片库存,并依赖不同的线性化曲线,它们都标记为 lg10。

跨项目资产传输

无法明确保证跨项目复制的图像资产能在色彩正确的方式下传输。

示例: 在胶片扫描示例中,不同项目上处理的扫描线性化版本可能不匹配。

但在实践中,这并不是一个严重问题 - 方便复制的色彩空间(如纹理资产)在项目配置文件中的定义恰好相似。

LUT 生成和使用

默认分辨率

  • 3D LUT:65x65x65
  • 1D LUT:4096

OCIO 内部 LUT

  • OCIO 内部使用的 LUT 可从该仓库获取
  • 用于内部色彩处理

预生成 LUT

位于 baked 目录的 LUT 可在 OCIO 外部使用。

LUT 命名规则:

1
[输出转换名称] 对应 [输入色彩空间名称].[扩展名]

例:sRGB (D60模拟) 对应 ACEScc.icc

支持的应用格式:

扩展名 应用
.3dl Autodesk Flame, Autodesk Lustre
.lut SideFX Houdini
.csp Autodesk Maya
.icc Adobe Photoshop

OpenColorIO 内部处理架构

操作 (Op) 抽象

为什么不依赖变换自身执行像素处理?

  • FileTransform 代表了广泛的图像处理操作
  • 例如:Houdini LUT 格式在单个文件中可能包含一个对数转换、一个 1D LUT 和一个 3D LUT
  • 创建轻量级的处理操作 (ops) 会简单得多

Op 的接口:

1
virtual void apply(float * rgbaBuffer, long numPixels)

给定一个打包的浮点数组和指定的像素数量,处理它们。

Op 类型示例:

  • Lut1DOp
  • Lut3DOp
  • MtxOffsetOp
  • LogOp

优化流程

  1. 变换 (Transform) 将自己转换为一个 Op 列表
  2. Op 列表会被优化(与相邻操作适当折叠等)
  3. 这非常有利于优化,因为合成器通常有复杂、分支的图像处理操作树

CPU 代码路径

  1. 主操作列表被优化并存储在处理器内部
  2. 图像中的一小块像素被格式化为一个连续的 RGBA 块
  3. 对每个 Op,原地调用 op->apply

块大小: 针对计算(SSE)简单性和性能进行了优化,通常与图像扫描线大小相似

GPU 代码路径

主操作列表被划分为 3 个有序列表:

  1. gpu-preops - 可以在着色器代码中解析处理的操作
  2. gpu-postops - 可以在着色器代码中解析处理的操作
  3. gpu-latticeops - 无法用着色器代码支持,烘焙到 3D LUT 中

分配优化:

  • 在 gpu-preops 和 gpu-latticeops 之间分析操作流元数据
  • 确定适当的分配以最小化钳位、量化等
  • 通过在预处理操作的末尾插入前向分配和在网格操作的开头插入反向分配来解决

构建和安装

依赖项

macOS 构建命令

1
2
3
4
5
6
7
8
# 安装 OpenColorIO(当前 Homebrew 方式)
brew install opencolorio

# 安装 OpenImageIO
brew install openimageio

# 安装 CTL(ACES 转换所需)
brew install ctl

注意: 以下为历史命令(已过时),仅供参考:

  • brew tap homebrew/science — 该 tap 已于 2023 年废弃
  • brew install --with-python — Homebrew 2.0+ 已移除编译选项
  • ociolutimage 工具在 OCIO 2.x 中仍可用,但构建方式已简化

获取 ACES CTL 源码

注意: ACES 项目已迁移至新的组织仓库。

官方 ACES 仓库:

历史版本(仅供参考):

1
2
# ACES 1.0.3 历史版本(旧仓库)
git clone --branch v1.0.3 https://github.com/ampas/aces-dev.git

Python 配置生成

可通过以下 Python 包生成配置:

1
cd aces_1.0.3/python

支持用户自定义的功能:

  • 一维 LUT 与三维 LUT 的分辨率设置
  • 自定义 Look 的集成
  • OCIO 显示设备与视图列表的两种生成模式
  • 整形函数选择:Log2 或杜比 PQ

UE5 中的 OCIO 使用注意事项

已知问题

UE5.3-5.4 版本存在一些 OpenColorIO 相关问题:

  1. “OCIO Invalid” 水印错误 — 使用 ACES OpenColorIO 配置时,Composure 输出可能显示此错误
  2. 视口颜色差异 — UE5.3 项目在 UE5.4 中打开时,视口颜色可能存在差异
  3. 材质编辑器显示问题 — 部分用户报告在 sRGB 显示器下,编码为 Linear、色彩空间为 ACEScg 的 HDR 贴图可能显示不正确

建议: 遇到问题时,请查阅 Epic 官方论坛的最新讨论,或考虑升级到更新版本的 UE5。

色彩空间设置建议

在 UE 中进行色彩管理时:

  1. 设置工作色彩空间为 ACES AP1/ACEScg
  2. 加载 OCIO 配置文件
  3. 在 OCIO 中添加色彩空间:
    • Lit
    • OCIO Display
    • 选择 OCIO Asset
    • 从 ACEScg 到 Rec.709 - ARRI ALF2 或 ARRI Reveal

术语表

术语 英文 说明
变换 Transform 改变 RGB(A) 数据的函数(例如,将图像从场景线性变换到 sRGB)
参考空间 Reference space 连接色彩空间的空间
色彩空间 Colorspace 一个有意义的空间,可以与参考空间相互转换
显示设备 Display 虚拟或物理显示设备(例如,一个 sRGB 显示设备)
视图 View 在显示设备上查看参考空间的一个有意义的视图
角色 Role 抽象的命名色彩空间
外观 Look 应用创意外观的色彩变换

参考资料

官方文档

经典文档

  • Jeremy Selan 的《Cinematic Color》文档
  • 索尼影视图像工作室 (Sony Pictures Imageworks) 色彩管线文档
  • SPI-VFX 配置文档

历史参考(已归档)

  • OpenColorIO-Configs 仓库(已于 2025 年 9 月归档)