问题与范围
曲线工具在 SDR 图片里通常围绕 0...1 设计:控制点在这个区间内,输入也大多落在这个区间内。它适合常见调色,却容易掩盖一个前提:当输入超过末端控制点时,到底该怎么办?
扩展线性或 HDR 工作流并不保证亮部小于等于 1。若实现静默把输入限制在 0...1,所有超过 1 的亮部会落到同一个端点,亮部层次被压成平面;若直接把默认改成外推,已有 SDR 配方又可能改变外观。本文讨论如何把这项选择变成可测试的颜色合同,不讨论具体显示器观感、端到端视频导出或性能结论。
先给结论
- 曲线插值方式和端点之外的处理方式是两个不同的决策,不能共用隐式开关。
- 为兼容旧配方保留钳位默认值;需要扩展范围时,再显式选择线性外推。
- 外推本身不足以保证 HDR 正确,还需要把工作色彩空间、精度与动态范围行为写入处理合同。
- 验证应同时覆盖旧默认、端点外数值、alpha 保持与合同声明,而不只看一张 SDR 截图。
为什么一个 SDR 默认值会压扁高光
设曲线最后一个控制点是 (1, 1),线性工作流中却传入亮度 2。若插值参数被限制到 0...1,它会返回末端值 1;1.2、1.5 与 2 也会得到同一个结果。这样做不是“保存高光”,而是把后续本来可以继续处理的差异提前丢掉。
线性外推会保留控制点末端的趋势,因此上例可以继续保留 2。它也不能成为新的无条件默认:一些历史配方就是在端点钳位的 SDR 假设下建立的。默认行为悄然改变时,控制点不变,结果却改变,持久化的编辑记录也失去了稳定性。
更可靠的模型是把两项语义分开:
// 简化示例:新编辑明确要求端点外的线性关系。
let curve = C7Curves(
rgbPoints: points,
interpolation: .linear,
extrapolation: .linear
)
interpolation 说明控制点之间怎么计算;extrapolation 说明值越过端点时怎么处理。旧配方则不必因为新增 HDR 场景而改写自己的默认结果。
从算法选择到像素合同
Harbeth 的 C7Curves 把这两件事分别建模为 Interpolation(.legacy 或 .linear)和 Extrapolation(.clampToEndpoints 或 .linear)。默认仍是 .legacy + .clampToEndpoints。只有在线性插值时才会把端点策略传入 Metal kernel;legacy 路径固定不外推,避免历史路径被新语义改变。
对应的 Metal 函数在不允许外推时才限制插值参数;允许外推则保留端点外的线性关系。它处理 RGB 三个颜色通道,并保留输入 alpha,而不是把透明度当成亮度的一部分。
不过,“数值没有被钳位”不等于“处理链已经正确理解 HDR”。在 linear + linear 组合下,C7Curves 的像素合同声明 preservesExtendedRange。亮度和曝光滤镜也声明扩展线性 Display P3、float16 与扩展范围保持行为。这样后续节点看到的不只是一个浮点纹理,而是知道它的颜色与动态范围语义。
颜色转换也要避免隐式丢数值。Harbeth 的 PQ/HLG 与线性转换会保留值的符号,避免负值在转换中被默默截成 0。这里的重点不是鼓励任意负亮度,而是让每一步对自己的数值域负责:该转换、该钳位、该 tone map 时,必须由明确的合同表达。
测试应验证哪些边界
本轮在 macOS 上运行了 FilterPrimitiveCoverageTests 与 FrameProcessingCapabilityTests,34 项通过。其中的曲线测试使用 RGBA16Float 输入,验证默认线性曲线保持 SDR 端点、linear + linear 保留 -0.5 与 2 等端点外数值并维持 alpha;同组测试还验证亮度、曝光和 PQ/HLG 转换的扩展范围合同。
这些测试证明的是当前实现的像素与合同路径,不等同于所有设备上的 HDR 显示效果、相机输入、视频编解码组合或最终导出验收。接入产品时,仍需按目标设备和输出格式补充端到端检查。
Harbeth / Kakapos 如何承接
Harbeth 是 Apple 平台的 GPU 图像与逐帧处理引擎;这里的案例属于其 HarbethIO 与 ImageNode 可组合的颜色处理合同,不把它扩展成相机或视频编辑产品。
Kakapos 负责媒体生命周期与编排。媒体层应把帧的颜色与动态范围语义连同处理结果交给可替换的逐帧后端,而不是把媒体状态机与曲线 kernel 混为一个职责。
小结
HDR 曲线的关键不是简单地“允许大于 1”,而是让端点行为成为显式、可组合且可回归的决策:旧配方继续钳位,新编辑按需线性外推,并由颜色空间、精度与动态范围合同共同约束。这样才能同时守住兼容性和可用的高光层次。