前言

网上有许多关于主流tonemap的实现代码,但都没有讲清楚这些主流tone map之间究竟有何区别、每个tonemap的特点,以及为什么需要定制,这样当美术需要某种画面感时,TA才知道如何去定制

本文将一一解析这几个存在的问题

什么是tonemap?为什么需要tonemap?

关于这两点网上已经说的很明白了,tonemap将HDR空间的颜色,映射到LDR空间,以适配只能显示[0,1]的显示器,防止颜色被截断导致的曝光

每种tonemap都由三部分组成:控制暗部的toe、控制整体亮度的Linear、压制高光的Shoulder,且几乎所有的tonemap都有着如下图所示的s形曲线

如果你看过ue的ACES Tonemap,一定不会对这三个参数感到陌生,它们代表的含义如下:

  • toe:控制暗部对比度

    用于处理HDR中的暗部,将暗部信息往下压,让画面更加干净

    优点:当toe越平缓,说明暗部颜色都往极暗区域靠,对比度越小,画面的纯黑色越干净,也就是常说的“电影感”

    缺点:会牺牲暗部细节

  • Linear:控制整体明暗的对比度

    Linear会极大幅度的影响曲线走势,因为linear越陡,曲线大部分区域都分配给了linear,整体的中间色被映射后的颜色差距越大,导致整体对比度越高

    越陡的linear会带来越强的明暗对比度,所以像ACES这种电影感的tonemap,它的linear就较陡

  • Shoulder:控制高光细节、层次感

    把极高的 HDR 值强行映射到 0.8∼1.0 的区域,防止大部分纯白

主流Tonemap之间的不同及特点

ACES

  • 特点
    • linear曲线较陡,意味着大部分中间色都在linear曲线,整体对比度高
    • toe、shoulder曲线较缓,尤其是最靠近0、1的部分,暗部、亮部偏向纯黑、纯白
  • 缺点
    • 因为linear陡对比度高,会损失暗部、亮部细节
  • 使用场景
    • 具有电影感的场景

Neutral

  • 特点
    • linear:占绝大部分,且接近1:1映射。所见即所得,美术画的 Albedo 是什么颜色,引擎里就是什么颜色
    • toe:只占一点点,个人感觉是用于将噪点映射到纯黑
    • shoulder:前面陡后面缓,对于极亮像素映射到纯白,较亮的对比度拉高
  • 缺点
    • 画面较平,缺少强的光影对比度

    • 极亮区域容易出现color band

    由于非高亮区域[0,0.8]都是线性映射,只剩0.2给高光,能用的bit是很少的,尤其显示器还是255bit,给高亮的也就50+bit

    • 当一个pixel从暗到亮到极亮的过程,变化很不自然

    当pixel在toe、linear都是比较正常的,但一旦刚刚进入shoulder区域且不断变白,会因为shoulder前面陡后面缓的特性,导致最开始颜色饱和度很高,后面慢慢变白

  • 适用场景

    • 材质编辑器预览、PBR验证

GT Tonemap


https://www.desmos.com/calculator/6tothm2tko?lang=zh-CN

  • 特点
    • 开放大量参数给美术,且将toe、shoulder、linear拆分成多个参数,完全可控。最重要的一点,参数几乎完全解耦,不像其他tonemap,部分参数互相牵连 (改了高光暗部变亮)
    • 能在保留极高局部对比度和色彩饱和度的同时,优雅地压平天空的过曝
    • 调节Black tightness、b,可以让toe能比ACES更陡,暗部对比度高,也可以手动将toe调的更平缓,让暗部偏纯黑
    • 调节Contrast,可以控制linear,Contrast更大曲线更陡,对比度越高;Linear section start、Linear section length可以控制linear区域大小,让黑白区域对比度更高
    • 调节Maximum brightness,可以控制峰值亮度,适配HDR显示器
  • 缺点
    • 没有很好的基础,参数不好掌控,容易调崩
  • 材质反光和局部对比度要求极高的场景

Filmic

  • 特点
    • Filmic toe先缓后陡,极暗部分对比度低,更偏纯黑,较暗部分对比度高
    • linear较缓,中间色偏灰
    • shoulder先陡后缓,较亮部分过渡丝滑,高亮部分偏白
  • 缺点
    • 画面可能会发灰,对比度欠佳
  • 适用场景
    • 对后处理性能极其敏感的

总结

方案 Hue Shift 暗部对比度
ACES 强(高光偏白) 极高
Neutral 无(偏向原色) 线性
GT Tonemap 参数可控 参数可控
Filmic 较弱 略发灰

为什么需要定制

可以看到上述tonemap多少都有些缺点,但GT参数是完全可控,且解耦的,还有定制的必要吗?

答案是有的,但不是定制曲线。大致有三种情况需要定制:

  • 场景亮度的突变
    • 假设从一个昏暗的室内走到阳光灿烂的室外,一套固定的GT参数是没法同时满足这种情况的

    会导致昏暗时大部分是暗的,大部分都在toe处,使得都变暗;室外亮度很高,导致大部分都在shoulder,都偏白。也就是说toe、shoulder会很影响画面的整体性,会很大程度地丢失画面信息

    如何在不同亮度情况下,让画面变化统一呢?观看GT的曲线,不难发现中间有一段几乎直的linear线段,如果pixel color亮度都在这个区域,那么不会丢失pixel的信息

    • 如何实现所有pixel都在linear呢?没错,就是自动曝光

    当画面整体较暗/亮,计算画面的曝光度,将整体pixel亮度乘上曝光值,使得变亮/暗,让亮度值落在linear区域

    • 但需要注意的是自动曝光不能统计所有pixel,有些pixel需要被剔除的

    在统计阶段对于少数极暗、极亮的pixel需要剔除掉,由于自动曝光需要计算所有pixel亮度的平均值,将这种极端pixel算入,会计算错误的曝光值。这种pixel不该管,让其将给toe、shoulder处理

  • 极端亮度的影响

    • 虽然自动曝光能控制画面整体性,但对于极亮、极暗的pixel处理依旧不好,虽然toe、shoulder可以处理这种pixel,但它们会丢失暗部细节、发白

    • 要解决这种的问题,需要用到Local Tonemapping

    通过Bloom的降升采样扩大感受野,再采样像素得到平均亮度来微调 GT 曲线的参数

    比如,平均亮度极低的话,降低toe的曲率从而降低对比度;平均亮度极高的话,降低shoulder曲率从而有更多空间来平滑白色

  • color grade

    • 虽然tonemap可以改变亮度,但不能改变颜色。当需要定制某种风格时,如蒸汽朋克、欧洲中世纪,就需要额外定制画面颜色

    • 解决方案是Color Grade,流程如下:

    • 先将linear space转到log space

    • Color Grade
      • 降低饱和度
      • 色调分离: 针对暗部(Toe)染上冷色,针对高光(Shoulder)染上暖色
    • 转回linear space
    • Tonemap

    • 为什么不是Tonemap后color grade

    Tonemap会破坏极暗、极亮的细节,且当由于亮度被映射到[0,1],在对高亮pixel去饱和,会导致错误的效果

    • 为什么是log space不是linear space

    因为人眼的感知更符合log space

定制管线

  • 由于增加了自动曝光、local tonemap、color grade,那么管线将不一样了,大致流程如下:
    • light pass HDR
    • Auto-Exposure
    • Linear to Log
    • Color Grade
    • Log to Linear
    • Tonemap
    • Gamma Correction/ ODT

Reference

HDR color grading and display in Frostbite

Cinematic Color: From Your Monitor To The Big Screen


他们曾如此骄傲的活过,贯彻始终