GPU Gems 2 · Chapter 24. Using Lookup Tables to Accelerate Color Transformations
把复杂颜色操作烘焙进三维查找表,利用 GPU 三线性采样实时处理高分辨率图像,并处理 texel center、精度和 HDR 输入域。
学习目标
- 能解释 Using Lookup Tables to Accelerate Color Transformations 如何把任意平滑 RGB 映射烘焙进 3D texture,使运行时成本不随 operator chain 复杂度增长
- 能实现 1D/3D LUT、trilinear interpolation 与 dependent texture lookup,并推导小型 LUT 必需的 texel-center scale/offset
- 能调节 ColorLutLab 的 lattice size、exposure、saturation 和故障开关,判断插值误差、边缘夹紧、存储与 HDR 输入域的取舍
先把“实时调色”拆成烘焙与应用
电影与视频调色常把 curves、levels、hue、saturation、gamut mapping 等操作串成很长的链。直接对高分辨率画面的每个像素重复整条链,反馈会变慢;但同一组输入 RGB 总会得到同一组输出 RGB,因此可以先在一个小颜色格点上算完,再让每个像素查询缓存结果。
没有这层转换,画面分辨率和算子复杂度会共同放大运行成本;使用颜色格点后,昂贵工作落在生成阶段,应用阶段只剩一次固定结构的纹理采样。猜一猜:把 lattice 从 16³ 降到 2³,primary grading 可能仍可用,但局部色相扭曲会发生什么?
3D color LUT 实验
先预测:减小 lattice 或关闭 texel-center correction,会怎样影响颜色边界和存储?
scale/offset 把 RGB 极值映射到首尾 texel center,trilinear interpolation 才符合数值格点语义。
本章主题 Using Lookup Tables to Accelerate Color Transformations 的关键是把“函数计算”替换为“规则采样”:复杂度被封装进表内容,而精度由输入域、lattice 密度、插值和纹理格式共同决定。
↡在有限输入格点上预先保存函数输出,运行时用索引和插值替代重复计算的数据结构。 ↡按单个输入变量索引的表;颜色处理中常为 R、G、B 各使用一条曲线,适合 brightness、gamma、contrast、curves 和 levels。1. 1D LUT:通道独立时最便宜
对 8-bit 灰度输入,复杂函数 只需对有限输入码值求值一次,再按像素码值查表。颜色图像可以为三个 channel 分配三条 1D curve,从而快速实现独立的 gamma、contrast 或 color balance。
1D LUT 的边界也很明确:每个输出 channel 只能依赖各自的一维索引。若灰度转换需要 、、 的加权和,或 hue warp 要让一个 channel 影响另一个 channel,三条独立曲线无法表达这种 cross-talk。
↡用 R、G、B 三个独立坐标索引颜色立方体、允许任意 RGB 输入映射到任意 RGB 输出的三维格点。3D LUT 把颜色空间离散成 个 sample。它能编码灰度转换、hue/saturation、primary/secondary grading 和 gamut mapping,但存储随 增长:每轴 4 个 sample 的 1D 表只有 4 项,对应 3D 表却有 64 项。因此,选择 lattice size 时必须同时看最大误差和内存/带宽。
2. 3D LUT 的适用边界
3D LUT 适合满足三个条件的变换:每个像素的结果与空间位置无关;映射足够连续,稀疏格点之间可安全插值;输入 color domain 有明确的 floor 与 ceiling。只要任一条件不成立,表就会遗漏所需维度或产生无法控制的重建误差。
连续性尤其重要。nearest-neighbor 只返回最近格点,会造成明显 color banding;高阶插值能提高平滑度,却需要更多 sample 和计算。现代 GPU 原生支持 3D texture 的线性过滤,因此工程基线通常是硬件 trilinear。
↡沿三维格点的三个轴连续执行线性插值,用包围查询点的八个角点重建结果的插值方法。设查询点在局部单元中的小数坐标为 ,八个角点为 ,则
其中 、。这个式子在说:每个角点的权重由查询点沿三个轴的相对距离相乘得到,八个权重之和为 1。
3. GPU 路径:一次 dependent texture lookup
↡第二次纹理采样的坐标由第一次纹理读取结果决定;颜色 LUT 中先读 source RGB,再把 RGB 作为 3D texture 坐标。运行时先从 2D image texture 读取 rawColor,再用该颜色索引 3D LUT。颜色算子链已经烘焙到表里,所以 shader 不需要知道是十个 curves、一次 gamut mapping,还是更复杂的生产调色;应用阶段仍是固定次数的 texture fetch。
但输入 RGB 不能直接原样作为数值 LUT 的 texture coordinates。普通图片纹理允许坐标覆盖纹理边界,而 LUT 的数值 domain 应从第一个 sample center 到最后一个 sample center。对于每轴大小 的 LUT,应使用
这个式子在说:先把零到一缩进到首尾 sample center 的跨度,再平移半个 texel,让输入极值准确落在最外层数据点。
scale 与 offset 对整幅图恒定,应在 CPU、material setup 或 shader specialization 中预计算。大型 1D LUT 的 half-texel 误差可能小到可忽略,但常见 16³、32³ 的 3D LUT 很小,未经校正的边缘误差会造成可见 clamping 与非线性。
4. 生成、缓存与系统集成
生成 3D LUT 不必让每个颜色工具认识 3D texture。可以把 identity lattice 排成一个 2D proxy image,将它送入现有 color-correction pipeline,再把处理结果恢复成 3D texture。32³ lattice 等价于 32,768 个颜色 sample,远小于每帧数百万像素,因此昂贵 operator chain 只需处理小代理数据。
集成流程要固定 byte order、axis order、channel order 和 row layout。一次 R/B 轴互换就会让所有混色错误,却可能让灰阶测试侥幸通过;因此测试集必须包含 primaries、secondaries、skin-tone-like mixed colors、ramps 和超范围值。
5. 精度、lattice size 与格式
最小可用 lattice 取决于 transform,而不是固定行业数字。只调整 RGB/CMY primaries 的 primary grading 甚至可由 2³ corners 表达;局部 hue warp、复杂 gamut mapping 和高曲率 tone response 则需要更密格点。选择流程应从 reference operator 开始,对均匀网格、边界和高曲率区域测最大/感知误差,再选择满足阈值的最小尺寸。
8-bit texture 会把每个输出 channel 量化到有限码值,容易在平滑渐变上出现 banding。增加 lattice size 不能恢复已经在 table value 中丢失的 bit depth;需要同时评估 16-bit float、dither、输出编码和目标显示链。
6. HDR:有界 domain 与 shaper LUT
↡包在 3D LUT 前后的匹配一维曲线;前向曲线把 HDR 非均匀压缩到规范化域,逆曲线在颜色映射后恢复动态范围。HDR 打破了默认 输入域。LUT 必须选择 floor 和 ceiling:ceiling 太低会 clamp highlights,太高则让有限 samples 大量浪费在视觉不敏感的高值区。负值也可能来自 out-of-gamut 运算或带负 lobes 的 filter,不能在没有规格时直接截到零。
均匀划分很宽的 HDR range 时,暗部和中间调会集中在少数 cells。解决办法是在 3D LUT 前加 forward shaper,把输入映射到更接近感知均匀的 normalized domain;应用 3D LUT 后,再用 inverse shaper 恢复原动态范围。
shaper 不是任意 tone mapping。forward/inverse 必须配对,3D LUT 烘焙时也必须在相同 shaped domain 中求值。发布前要记录 floor、ceiling、shaper version、是否保留 negative values,以及超范围输入的 clamp/extrapolate 策略。
三步实验:从 identity 到 HDR 交付
每一步只改变一个变量,记录 color space、domain、lattice/format、scale/offset、operator hash 和最大误差。若 identity 都不能 round-trip,先修布局或采样坐标,不要继续调 grading 参数。
第一步:验证 1D 与 3D 表达能力
用独立 RGB curves 和一个 luminance/hue cross-talk operator 分别烘焙 1D、3D LUT。观察哪些 mixed colors 无法由三条独立曲线表达,并用 corners 验证 axis order。
本章小结
- lookup table 把昂贵颜色函数缓存到有限格点,使 runtime 成本与 operator chain 长度解耦。
- one-dimensional LUT 适合通道独立变换;three-dimensional LUT 才能表达 RGB cross-talk。
- trilinear interpolation 用八个角点连续重建颜色,但要求 transform 平滑且 lattice 足够密。
- dependent texture lookup 必须校正到 texel centers,并固定 proxy image、axis 和 channel layout。
- HDR 需要明确 domain 与匹配 shaper LUT;lattice size、bit depth 和范围必须分别验收。
练习
问题 1|计算采样校正。 对一个每轴 的 3D LUT,输入 与 应映射到哪些纹理坐标?
问题 2|选择 1D 还是 3D。 一条 pipeline 只包含独立 RGB gamma curves,另一条包含 luminance grayscale 与局部 hue warp。应分别选择什么表?
问题 3|修改实验处理 HDR。 当前 32³ LUT 覆盖 ,暗部 grading 粗糙但高光必须保留。你会如何改造?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- lookup table
- one-dimensional LUT
- three-dimensional LUT
- trilinear interpolation
- dependent texture lookup
- shaper LUT