OCIO 随想与颜色拾取噩梦
引言
本页原本是 ACES 章节 的一部分,但由于内容过于具体,我认为将其作为一篇独立的文章更有意义。请注意,本文尚未根据我关于 ACES 的最新发现进行更新,请谨慎参考。谢谢!
截至今日(2025 年 6 月 8 日),我认为这篇文章已经过时。目前,我建议艺术家在“线性”工作色域中拾取颜色,而不是通过反向视图变换。后者太容易造成混淆。
ACES 实现
ACES、OCIO 与 CTL
如今,大多数色彩管线都是通过 OCIO 设置的,这很棒,因为它与许多软件兼容:Maya、Guerilla、Nuke、Mari、Rv……但使用 OCIOv1 和 LUT 有一个缺点:你会损失精度。这篇文章 和 这里 对此解释得非常清楚。
CTF 效果更好的原因是,它更像是 ACES CTL 代码的“精确数学”实现,而不是烘焙成基于 LUT 的表示。
来自 Doug Walker,ACES 导师。
离散与连续变换
这里发生了什么?我的同事 Christophe Verspieren 给了我答案。他向我展示了 OCIO 烘焙的 LUT 所涉及的 连续与离散 概念。这其实很容易理解。看看 这个网站 的这张图片:

015_ACES_0390_continuous_discrete_FHD
当我们从场景参考转换到显示参考时,意味着要覆盖一个高动态范围(ACES 处理大约 15 档的动态范围)。离散变换实际上覆盖了巨大的区域。
我们不会将动态范围分割成相等的区域,而是更倾向于以牺牲高光细节为代价,详细分割最常见的值。因此,显示色调映射(ODT)通过增加曝光度,使得这些错误的色度变得非常明显。
此外,即使变换在 OCIO 中是数学定义的,但它在 GPU 上运行而不是在 CPU 上运行,这导致了公式的离散化:显卡实际上创建了一个 LUT!
真的,这些问题没完没了……
颜色插值间隙
此外,这些(离散化产生的)间隙是通过线性方式填充的,这不一定是最自然的方式。即使我们改变色域,我们仍然在 RGB 空间中工作,并且线性插值是在从 A 到 B 的直线上完成的。有时,在 Lab 色彩空间中管理颜色插值会更好。
并非所有数学公式在 OCIO 1.1.1 中都可用,只有 OCIO v2 才能准确表示 ACES 所需的计算。
总结一下:
- 在每个切片之间,我们进行线性插值。
- 在非常大的区域中,这些插值缺乏精度。
- 这导致由于离散化,在高光区域出现色度错误。
这在视觉上如何体现?让我们看一些极端饱和度的渲染图,来比较不同的解决方案。

015_ACES_0400_maya_arnold_ACES_configs_comparison
(第 2/4 段)
由于 Arnold 的默认设置,这些渲染中的基础颜色权重为 0.8。
Nuke 中的 CTL 节点
这有多重要?我们应该坚持使用 OCIO 还是研究这个 CTL 实现?我想我读过的关于这个话题的最佳答案(再次!)来自 Alex Fry:
对于正常曝光的图像,尤其是来自实拍摄像机的图像,你不太可能看到与 OCIO 配置渲染不同的值,但对于包含极端强度和饱和度的 CG 图像,你会看到更令人愉悦的滚降和去饱和效果。
2016 年 12 月,Alex Fry 就已经理解了这么多东西……
所以看起来 CTL 特别值得使用,尤其是如果你在处理饱和度高、色彩鲜艳的动画电影时!Alex Fry 非常慷慨地与我们分享了这个 Pure Nuke ACES RRT & ODT。Jed Smith 也做了一个 ACES 输出变换的 Nuke 实现。
请注意,CTL 基本上是一门已死的语言。它没有得到适当的维护或更新,因为它是一个相当深的兔子洞。
这是我所知的 关于 CTL 的最后一个讨论串。你可以像这样在 Windows 上尝试它。
这些 Nuke 节点与纯 CTL 实现 100% 匹配,但速度更快。请注意,这些节点处理的是 ACES2065-1 素材。 由于我们使用 ACEScg 渲染,你需要在连接素材之前使用“OCIOColorSpace”节点转换你的素材。
你也可以查看 Alex Fry 演示中的 不同示例。不过我不知道这些图像是用 CTL 还是 OCIO 生成的。甚至是使用 FilmLight 的 Baselight…… 有了 OCIOv2,ACES OCIO 配置应该不会再出现任何差异了。
ACES OCIO 配置的发布说明可以在这里找到。
渲染引擎中的 ACES
大多数渲染引擎都集成了 OCIO,这让我们可以使用 ACES。Autodesk 甚至推出了 Maya 中 ACES 的 CTL 集成。但可能听起来令人惊讶,OCIO/ACES 的集成有不同的层次。对于大多数渲染引擎,基于光谱的计算仍然使用 sRGB/Rec.709 原色进行,例如:
- 开尔文温度(用于灯光、黑体辐射和相机白平衡)。
- 物理太阳和天空(或 Skylight)。
- 头发着色器中的黑色素(例如,参见这个 Arnold 发布说明)。
例如,在大多数渲染引擎中,Skylight 是一个转换为 sRGB/Rec.709 原色的光谱表示。我在这里引用 V-Ray 的例子:
V-Ray 默认使用 sRGB 原色,但这实际上只在你使用任何处理光谱的 V-Ray 功能时才相关——比如灯光温度、相机白平衡作为温度、物理太阳和天空。[…] 通常,V-Ray 将所有颜色视为浮点值的三元组;在大多数情况下,V-Ray 并不真正关心这三个数字的实际含义。然而,V-Ray 中的一些计算是基于光谱的;这些光谱到浮点颜色三元组的转换假设这三个数字代表特定的东西——某种预定义的内部渲染器色彩空间中的颜色。这意味着当从开尔文温度转换为 RGB 颜色时,V-Ray 必须知道那个内部渲染器色彩空间是什么。
来自 2016 年的这篇帖子。
我很确定开发者们会在某个时候赶上。否则,你可以简单地使用一个从 sRGB 到 ACEScg 的 3×3 变换来转换。但确实,这最后的实现步骤在大多数 DCC 软件中都缺失了。
修改 ACES OCIO 配置
我曾一度认为 ACES OCIO 配置应该按原样使用。完全不是!ACESCentral 上有一个讨论串解释得非常清楚:
通过编辑标准 ACES 配置文件来制作自定义配置是非常常见的做法。[…] 不仅如此,而且是推荐的!ACES 配置的目标之一始终是作为人们根据自己需求进行定制的起点。
Nick Shaw 和 Thomas Mansencal。
最简单的方法是在文本编辑器(如 notepad)中编辑“config.ocio”文件。你应该备份原始配置文件,然后根据你的需求和规范进行简单的编辑。以下是我个人的偏好:
| ACES 1.2 OCIO 配置 | 自定义 ACES OCIO 配置 | |
|---|---|---|
| color_picking | Output – sRGB | lin_srgb |
| color_timing | ACES – ACEScc | acescct |
| compositing_linear | ACES – ACEScg | acescg |
| compositing_log | Input – ADX – ADX10 | acescct |
| data | Utility – Raw | raw |
| default | ACES – ACES2065-1 | lin_ap0 |
| matte_paint | Utility – sRGB – Texture | acescct |
| reference | Utility – Raw | raw |
| rendering | ACES – ACEScg | acescg |
| scene_linear | ACES – ACEScg | acescg |
| texture_paint | ACES – ACEScc | lin_srgb |
| active views | [sRGB, DCDM, DCDM P3D60 Limited, DCDM P3D65 Limited, P3-D60, P3-D65 ST2084 1000 nits, P3-D65 ST2084 2000 nits, P3-D65 ST2084 4000 nits, P3-DCI D60 simulation, P3-DCI D65 simulation, P3D65, P3D65 D60 simulation, P3D65 Rec.709 Limited, P3D65 ST2084 108 nits, Rec.2020, Rec.2020 P3D65 Limited, Rec.2020 Rec.709 Limited, Rec.2020 HLG 1000 nits, Rec.2020 ST2084 1000 nits, Rec.2020 ST2084 2000 nits, Rec.2020 ST2084 4000 nits, Rec.709, Rec.709 D60 sim., sRGB D60 sim., Raw, Log] | [sRGB, Raw, Log] |
修改 ACES OCIO 配置的原因
以下是我做出这些选择的一些解释:
- 我使用别名而不是色彩空间的名称。我觉得它们更短,也很有用。
- color_picking 角色仅限于 sRGB 色域,以避免输出变换带来的任何色域裁剪。据我所知,这个功能可能只在 Autodesk Maya 中有效。
- color_timing 和 compositing_log 角色都使用 acescct。这对于饱和度或锐化等操作很有用。
- matte_paint 角色使用 acescct 是由于 Photoshop 的一个变通方法。
- texture_paint 角色使用 lin_srgb,因为我所有的输入/纹理都具有线性传递函数(按约定)。
- 我还限制了活动视图的数量,以缩短下拉菜单(如 Nuke 的查看器)。
反向输出变换工作流
保留徽标和图形
这个话题在 ACEScentral 论坛上已经被讨论过很多很多很多很多很多很多很多很多次。我们如何将互联网上的图像外观保留到 ACES 工作流中?ODT 可以用作 IDT 来实现这一点。 这个过程简称为反向 LUT。
(第 3/4 段)
使用 RRT/ODT 导入图像,只是告诉 ACES 的一种方式:***这张图像,无论它来自哪里,都是我的最终结果,我想把它转换回我的工作空间。***不幸的是,RRT/ODT 并非完全可逆。所以实际发生的情况是(几乎但不完全是)一个透明的往返过程:
- IDT:输出 – sRGB -> ACEScg
- 工作/渲染空间:ACEScg
- ODT:ACEScg -> 输出-sRGB
友情提醒:你绝对不应该使用这种技术将纹理加载到着色器中。 这在 ACEScentral 论坛 上已经被解释过多次了。
恒定颜色
我最常被问到的问题之一是关于资产转换:我们应该如何处理在 线性 – sRGB 中创建的资产,以便将它们转换为 ACEScg?
这是我最近不得不面对的一个例子。假设你正在制作一部电影,其中有一个穿着红色的著名角色。通常,客户会对这个红色值非常挑剔。 它必须匹配!

015_ACES_0470_manual_conversion_workflow
这个工作流程之所以有效,是因为 Nuke 和 Guerilla 在 ACEScg 中进行颜色选择。
我之所以为恒定颜色编写这个教程,是因为我能够检查转换后的值没有破坏能量守恒。而这正是你永远不应该对纹理这样做的原因。
色指定
在我们的下一个例子中,我使用了“反向 ODT 技术”。挑战在于将 Photoshop 中绘制的船只概念图的相同颜色,保持到 ACEScg 渲染中。我知道对于许多工作室来说,忠于色指定和概念图至关重要。

015_ACES_0600_playmobil_peah_boat_concept_FHD
这个工作流程之所以有效,是因为 Nuke 和 Guerilla 在 ACEScg 中进行颜色选择。
我完全接受这个事实,即这个概念图包含一些光照信息。因此,在一个地方或另一个地方拾取颜色可能会变得主观。
因此,在 Nuke 中使用了一个大的拾取区域。
这个过程有一些限制:
- 首先,如果你在 ACES 中工作,你应该只在 ACES 环境中进行颜色拾取。
- 它在处理非常饱和和极端的值,尤其是黄色值时,会有些困难。 你最终可能会得到一些负值。
- 如果你正在拾取反照率值,你必须极其小心,确保该值在 PBR 范围内。
- 它不适合调色和动态图形,尤其是对于 SDR 图像,正如这篇文章中所解释的那样。
现在我们可以更深入地了解 Color Picking 角色。默认情况下,在 ACES 1.2 OCIO 配置中,Color Picking 角色设置为 Output – sRGB,以匹配默认的输出变换。这就是为什么 Color Picking 角色与反向 ODT 工作流程是“上下文相关”的。
Color Picking 角色
不同的实现方式
当谈到 Color Picking 角色时,首先要知道的是,并非所有软件在这个功能上都是平等的。当开发者在软件中实现 OCIO 时,他/她可以选择将功能集成到某个程度。让我们以 Guerilla 和 Maya 为例:
(第 4/4 段)
- Guerilla 中的 Color Picking 角色仅驱动颜色选择器的色相板(用于显示)。
- Maya 中的 Color Picking 角色驱动整个颜色选择过程。
我花了六个月才理解 Maya 中的 Color Picking 角色。但我想我终于弄明白了。首先,最重要的问题是:Color Picking 角色是做什么用的? 根据 OCIO 文档:
color_picking– 颜色选择 UI 中的颜色可以在此色彩空间中显示,同时在不同的工作空间(例如scene_linear或texture_paint)中选择颜色。这基本上就是 Guerilla 实现的方式。
但 Maya 对 Color Picking 角色有不同的用法。它实际上使用此角色在着色器或灯光中选择任何 RGB 颜色。在这种语境下,Color Picking 也可以被称为 Color Selection。
RGB 三元组本身没有太大意义。你需要一个上下文来正确解释它们。Maya 让你选择这个上下文,而 Guerilla 或 Nuke 则不行。
这就是为什么根据你使用的 DCC 软件,在处理 Color Picking 或 Color Selection 时必须格外小心。
如果你的 ODT 与 Output – sRGB 不同,我建议你修改 OCIO 配置文件中的 color_picking 角色,使其与你使用的 ODT 匹配。
你的 ODT 和颜色拾取角色应该是相同的,至少在 Guerilla Render 中是这样。
Maya 中的颜色拾取
请注意,在本节中我将重点讨论 Maya,因为它对 color_picking 角色的集成方式相当独特。
在为 Maya 选择 Color Picking 角色时,我见过三种不同的理念:
| 优点 | 缺点 | |
| Output – sRGB | 颜色选择是显示参考的。它“对艺术家友好”。 | 你不知道用于渲染的确切值是什么(除非你不断检查 通道编辑器)。这可能会破坏你场景的 PBR。 |
| Utility – Linear – sRGB | “传统”模式。艺术家可以选择他们习惯的颜色。 | 你在颜色选择中无法利用广色域。 |
| ACES – ACEScg | 你确切知道渲染时使用的值,并且可以达到非常饱和的值(如激光)。 | 你可以访问到疯狂饱和的值,这不适合用于反照率,最终可能会破坏能量守恒(并导致裁剪!)。 |
如果你在 Maya 中使用 (1, 1, 1) 且 Color Picking 角色设置为 Output – sRGB,那么在你的渲染中实际使用的值是 (18.91, 18.91, 18.91)。如果这被设置在 Base Color 中,那就大错特错了!

015_ACES_0660_color_picking_maya_FHD
确实,当你使用“Output – sRGB”时,你永远无法真正确定渲染时使用的是哪种颜色。这就是为什么一些工作室将他们的 Color Picking 角色设置为 ACEScg,以便了解渲染引擎使用的值。
老实说,我不能说一种系统比另一种更好。你只需要清楚自己在做什么。 如果你对这个特定话题感兴趣,我建议阅读 ACESCentral 上的这三个帖子。
ACEScg 中的颜色拾取
如果你使用 ACEScg 作为 Color Picking 角色,你应该意识到这一点:没有非发射性表面具有如此饱和的颜色。 只有激光(一种发射源)才能达到 BT.2020 原色。
这个特别的例子确实让我把事情弄得更清楚了。当你学习色彩科学时,有时可能会迷失在抽象的东西中。了解这一点在某种程度上让所有这些概念变得更具体、更真实。
如果你想在 ACEScg 中进行 Color Selection,只需编辑 OCIO 配置并修改 color_picking 角色:
roles:
color_picking: ACES - ACEScg
如果你在写实环境中工作,所有这些都与你相关。如果你在制作卡通片……嗯,这也与你相关!有些制片人就是喜欢最夸张的饱和度。但大多数卡通电影都希望其外观具有可信度。 所以我的建议是,以写实的方式进行你的外观开发,之后你仍然能够通过调色来提升饱和度。
当然,所有这些仅适用于 PBR 卡通电影。
结论
我们在本文中主要讨论了三个主题:
- OCIO 和精度问题:这很可能在 OCIO v2 中得到修复,即使它尚未在所有软件中实现(是的,我就是在说你 Rv!)。
- 渲染引擎中的 ACES:我不建议开发者在他们的软件中硬编码色彩空间。这应该基于 OCIO。
- 颜色拾取和反向 LUT:我们已经看到这是一个非常令人困惑的话题(希望现在稍微好一点),这主要有两个原因。首先,OCIO 在其文档中缺乏指导;其次,软件开发者实现得不好。
在最新的 ACES 配置中,关于角色有很多争论。希望在不久的将来,我们可以邀请开发者们统一他们的实现。否则,角色将变得几乎毫无用处!也许有一天梦想会成真……