自动曝光是什么?
场景里有的地方很亮,有的地方很暗
显示器能显示的亮度范围很有限
自动曝光就是:每帧看看画面整体有多亮,算出一个「曝光倍数」,把整张图统一调亮或调暗,让画面看起来舒服——类似人眼从暗处走到亮处会眯眼、从亮处进暗处会慢慢看清
游戏里也叫 Eye Adaptation(眼睛适应)
为什么需要?
场景亮度会变(进出室内、昼夜、动态关卡)。自动曝光要模拟眼睛对光线变化的反应,并选出「合适」的曝光。难点在于:什么叫合适——按太阳、按阴影,还是折中?画面该正常、欠曝还是过曝?这没有唯一答案,所以有人干脆手动定曝光
如何实现?
核心算法
自动曝光目前分为两种做法,但核心算法都是一样的,如下:
- 量:这一帧有多亮
- 每个pixel计算luminance
- 计算所有luminance的平均值,得到一个平均亮度 L_avg
- 比:离“该有多亮”差几档
- 摄影里把 18% 灰(0.18)当成正确曝光的中灰,需要计算一个系数ExposureScale,使得ExposureScale * L_{avg} = 0.18
- 人眼/相机用 档(EV) 想这件事,一档就是乘/除 2:EV = log₂(L_{avg})
- 调:给美术额外参数
- 夹紧(Min / Max):平均亮度只允许落在一个范围内
- 曝光补偿 EV(Exposure Compensation):美术手动调节亮度档位
- 用:每个像素颜色乘上ExposureScale
新派和老牌做法只在”量”上不同
老派做法
在”量”上,老派做法将所有luminance都纳入考虑,通过不断降采样,最终降采样一个数,这个数即为ExposureScale
新式做法
在”量”上,新式做法也将所有luminance都纳入考虑,但这些luminance会放入直方图按挡位划分,挡位外的(极亮、极暗)排除,剩下的加权平均,得到ExposureScale
- 中心加权
画面中心更重要,可只测中心圆,或给中心像素更大权重
-
直方图
小块极亮/极暗会拖垮简单平均;直方图可近似按「主导亮度」或中位数来适应。64 个 log2 档可盖约 16 EV,128 档可盖现实几乎全部曝光范围。建完后可丢掉大量最暗像素(约 50%–80%)和少量最亮像素(约 2%–20%),用中间部分求平均,曝光更稳
-
滑动直方图 / 预曝光
用上一帧曝光先乘回 HDR 缓冲,方便用 R11G11B10 等格式存 HDR 而不丢精度(Valve 也做过类似预曝光)
-
曝光补偿曲线
纯自动会把暗室和开窗后的亮室都拉成差不多亮,但我们更希望:暗环境最终画面偏暗,亮环境偏亮
因此 Krawczyk 拟合过 key 随亮度变化的曲线;游戏里可以自己定函数,或让美术调 1D 查找表
-
按照度适应,而不是按最终像素亮度
只看最终亮度时,白墙和黑墙经曝光后可能看起来差不多。Hoffmann 建议按「照到表面的光」(illuminance)适应,材质反射率就不掺和进来;镜面也能少干扰。天空盒怎么进测光要单独定,并常给天空手工曝光补偿
自动曝光管线
记住,需要在Tonemap前,进行自动曝光
预曝光
- 什么是预曝光
在后处理前,计算Scene Color光照时,乘上预曝光缩放系数
-
为什么需要预曝光
Scene Color RT格式一般为R16G16B16A16_FLOAT,这样的精度看似较高,但对于自动曝光来说是有不足的,因为R16G16B16A16_FLOAT的精度只支持3-4位有效数字
- R16G16B16A16_FLOAT如何表示数字?
再继续下去之前,先看看半精度是如何表示数字的
- R16G16B16A16_FLOAT使用± 1.xxxxxxxxxx × 2^档来表示(注意,小数点后的是二进制),其中小数点后有十位,这意味着每一档小数点的精度是1024
来看一个例子就知道了,4096表示为1 x 2^12
下一档是1x2^13 = 8192,在4096-8192间,有4096个数,但小数点后的精度是1024,这意味着,这种情况下每四个数,由小数点后一位表示
- R16G16B16A16_FLOAT使用± 1.xxxxxxxxxx × 2^档来表示(注意,小数点后的是二进制),其中小数点后有十位,这意味着每一档小数点的精度是1024
若是处于很暗的室内,计算得到的曝光系数很低,比如0.00005,这种情况下得到的值为0,那么就是全黑,阴影层次将消失;若处于很亮的室外,计算得到的曝光系数很高,比如8000,那么层次过渡会非常差,因为8000挡位下,每四个数,由小数点后一位表示
- R16G16B16A16_FLOAT如何表示数字?
-
如何实现预曝光
核心问题:如何计算预曝光?
每次计算完曝光系数时,记录这一系数作为预曝光系数,传回CPU,下次计算Scene Color Lighting时,使用该预曝光系数
若是第一次计算Scene Color Lighting,预曝光系数设为1
需要注意,因为应用了预曝光系数,所以需要在计算曝光系数里,计算亮度时,乘上one over 预曝光系数,避免受到影响
时间平滑
-
什么是时间平滑
从暗处走到亮处,亮度从暗到亮一点点的平滑
-
为什么需要时间平滑
- 防止亮度突变
- 模拟现实中从暗到明/从明到暗,眼睛的变化
- 如何实现
- 计算当前帧计算的亮度档位(平均亮度与中灰0.18的比值)
- 上一帧的亮度档位计算差值
根据大于/小于0,判断是从暗到明/从明到暗(因为两个方向的速度是不一样的)
-
不断基于差值,插值平滑
物理上眼睛的变化,是一开始快后面慢,因此时间平滑也需要模拟这一现象
先线性,后指数
Reference
Automatic Exposure
Adaptive Exposure from Luminance Histograms
Automatic Exposure Using a Luminance Histogram
自动曝光
Epic Games如何在4.25版中处理自动曝光






Comments | NOTHING