其他
Epic Games如何在4.25版中处理自动曝光
虽然我们提供的升级途径应该能保持项目外观的视觉效果一致性,但升级确实会破坏对先前版本虚幻引擎中自动曝光系统的向下兼容性。
在这篇博文中,我们将探讨当前系统的痛点以及我们作出这些更改的原因,还将说明这些更改对自动曝光功能今后发展的好处。
直方图算法和基本算法
基本算法使用场景亮度对数平均值来确定测量的曝光度。 直方图算法不使用整个场景,而是会丢弃高于或低于直方图目标范围的像素。这种方法采用剩余像素的亮度对数平均值来确定目标曝光。
这些算法会根据后期处理体积的曝光设置提供不同的结果。为了让这两种算法以符合预期且直观的方式达到最佳表现,我们制定了两条规则:
灰色应该是灰色。也就是说,如果用均匀的光照(或一个0.18 cd/m^2的自发光表面)照亮一张18%的灰色卡,那么屏幕上的目标颜色就应该是0.18。 全直方图应该与基本算法匹配。也就是说,如果将直方图的范围下限和上限设置为0–100%,那么它看起来应该和基本曝光算法的结果一样。
让我们以这些规则作为指导原则来考察一个示例,了解这些算法和它们的属性为何会造成诸多困惑,而我们又是如何在虚幻引擎4.25中改进的。
在4.24版中,如果我们先设置一个场景,其中有一个测量值为0.18 cd/m^2的表面,并将直方图范围设置为1–99%,那么我们会在关卡视口中得到下列结果:
(左)直方图模式(RGB 254),UE 4.24;(右)基本模式(RGB 111),UE 4.24
直方图曝光算法收敛为接近白色(测量值是RGB 254),而基本曝光算法收敛为灰色(测量值是RGB 111),即伽马2.2空间中的16%灰。
那么,为什么会发生这种情况?我们在4.25版中又是怎样改进的?
直方图模式的原意是让你不要调整直方图的中央。然而,默认数值是80–98%,这就使直方图的平均值成为白色点。
而基本模式会将计算出的场景平均亮度用于灰色点,而灰色点是由校准常量定义的,它的默认值是16%灰。
孤立来看,这两种解译都是合理的。明智的做法是针对白色点调整直方图曝光,针对灰色点调整全场景模式,但是共享参数的相似模式产生如此不同的行为会令人困惑。
我们经过调查发现,有这样几种选择:
什么都不做,就让自动模式和直方图模式产生不同表现。 把它们做成相同,但是添加标记和参数来确保向下兼容。 把它们统一起来,但是破坏向下兼容性。
我们选择了第3个选项。
第一个选项是有问题的,因为美术师仍然需要面对令人困惑的、不直观的参数。第二个选择会产生更多不直观的参数,使已有的问题变得更复杂。而第三个选项,即统一这些算法能减少复杂性和混淆,并且使工具在美术师眼中变得更直观。
在虚幻引擎4.25中,直方图和基本曝光模式都会收敛到灰色点。也就是说对于直方图模式,我们现在将直方图的平均值解译为灰色点。对于基本曝光模式,我们去除了校准常量。
下面就是这些自动曝光更改在4.25版中产生的结果:
(左)直方图模式(RGB 116);(右)基本模式(RGB 117)
测量RGB值可发现,直方图模式和基本模式都收敛到了同样的中间灰色(忽略凑整误差造成的微小差异)。使用下列公式时,两者都在一个18%灰色值的范围内:
注:如果你想让直方图趋向白色点,仍然可以通过更改曝光补偿参数来做到这一点。
比例从1.2变为1.0
给定一个以cd/m^2为单位的亮度值,该亮度值的EV100值通常按此公式计算:
对许多用户来说,这只会让他们更加困惑,因为许多人喜欢在“无单位”环境中工作,其中0.18的自发光数值在屏幕上应该显示为0.18(考虑伽马校正)。在先前版本中,为了做到这一点,你必须使用不直观的曝光补偿值log2(1/1.2) = -0.263。
这个额外的偏差造成的困惑比它解决的还多,今后会默认去除它。但是如果需要,你也可以选择将它重新加进来。
1.2的物理基础
这个公式是ISO标准:12232:2019定义的,我们使用这个标准作为摄像机的物理基础。在真实世界中,镜头不是完美无瑕的,并不是所有射进镜头的光线都会照到传感器上。大多数应用程序假设镜头的透射率为0.65,也就是说,进入镜头的光线有65%会照到传感器上,其余35%由于吸收、相互反射和渐晕而损失了。
按照这一ISO标准,在ISO 100的感光度下,镜头会在数值达到0.78/q时饱和(其中q是镜头的透射率)。既然大多数应用程序使用q=0.65。那么我们就得到了以下结果:
但是,虚幻引擎的虚拟镜头实际上不会有那样的表现,因为它不会由于相互反射或吸收而损失光线。所以我们决定使q成为用户定义的变量,可以通过r.EyeAdaptation.LensAttenutation来控制。
注:默认情况下,虚幻引擎的镜头衰减设置为0.78,使UE4的光照成为无单位的。如果你想保持以前的1.2比例,可以将镜头衰减变量设置为以前的隐含值0.65
改进的物理摄像机参数
这种方法的缺点是会造成工作流程的问题。一种常见的用例是使用自动曝光设置场景,得到合理的外观。直方图模式(下面的左图)将有正确的外观。如果切换到手动模式(下面的右图),曝光就显得太暗了。
因为自动曝光在使用手动测量模式时会考虑摄像机的参数,所以场景就会变暗。这个模式原本的意图是方便用户使用模拟实体摄像机的准确光圈值和景深值来调整实景光照。但它的缺点是,在同样的场景中使用自动摄像机没有问题,使用手动摄像机却不符合实际。
为了改进这个工作流程,使它更为直白,我们给后期处理体积添加了一个新标记:应用物理摄像机曝光(Apply Physical Camera Exposure)。通过它可以控制物理摄像机参数是否影响自动曝光。也就是说,在禁用这个属性时,使用曝光补偿值0.0的手动摄像机将会与设置为零的自动曝光场景完全吻合。
新的曝光测量遮罩
(左)后期处理设置中的“曝光测量遮罩(Exposure Metering Mask)”材质插槽;(右)示例曝光测量遮罩纹理
上面的示例测量遮罩允许你给靠近屏幕中央的像素提供比边缘像素更多的影响。这有助于稳定自动曝光。例如,在屏幕边缘出现的明亮物体有可能使预期的自动曝光值发生突变。这种遮罩可以降低靠近边缘的采样影响,从而得到更稳定、抖动更少的自动曝光结果。
(左)使用全屏曝光;(右)使用曝光测量遮罩。
注:我们删除了控制台命令r.EyeAdaptation.Focus,它要么应用加权给中央区域的值提供更多影响,要么允许你对全屏幕统一应用加权。虽然这个参数的功能与这种新的曝光测量遮罩近似,但它只会影响自动曝光基本测量模式,不会影响直方图模式。新的曝光测量遮罩为美术师提供了更精细的控制,在基本模式和直方图模式下都能见效。
改进的HDR可视化模式
注:你可以在关卡视口中转到显示(Show)> 可视化(Visualize)> HDR(眼部适应)(HDR (Eye Adaptation))启用此视图,也可以在控制台中使用命令ShowFlag.VisualizeHDR 1启用它。
蓝线是视图的目标EV100曝光值。 这就是直方图中平均场景曝光值所在的线,具体要看你使用的是直方图曝光测量模式还是基本曝光测量模式。 紫线是当前场景视图中的实际EV100曝光值。 这是这个视图中存在的当前曝光。它总是会向着蓝线移动。 白线是调整曝光补偿后的最终EV100曝光值。 这是在后期处理参数中调整曝光补偿后,显示屏上的实际曝光值。白线和紫线将根据曝光补偿中设置的值保持间隔差异。在这个示例中,直方图中的白线和紫线将保持2.0的差异。
注:必须启用HDR(眼部适应)可视化模式。然后,使用控制台变量r.EyeAdaptation.VisualizeDebugType切换调试模式。0(默认值)提供色调映射之后的场景颜色,1提供直方图调试模式。
在这种模式下的直方图调试可视化能确保非常明亮的像素(例如太阳)和非常黑暗的像素(比如颜色很深的阴影)不参与发生的HDR计算。在这个场景中,任何低于目标直方图范围的像素都将显示为红色,任何高于该范围的像素显示为蓝色。它确保了我们设置的上限和下限百分位范围不会将不需要的像素纳入计算。
曝光补偿曲线
考虑到这一点,也就不难理解为何美术师希望在明亮区域和阴暗区域中有不同的曝光补偿。他们可以通过在后期处理体积中分配曲线资源来实现所需的外观,同时还能更精细地控制哪些数值会影响环境中的曝光补偿。
(左)后期处理曲线资源分配;(右)曲线资源
注:使用内容浏览器,单击新增(Add New)按钮,然后导航至其他(Miscellaneous)类别,选择曲线(Curve)以将曲线资源添加到项目。然后选择CurveFloat。
HDR可视化模式包含曲线中表示X轴和Y轴的所有信息。平均场景EV100(Average Scene EV100)值(1)和直方图中的蓝线(实际曝光)值(1)表示曲线资源中的X轴。曝光补偿(曲线)(Exposure Compensation (Curve))表示曲线的Y轴,它与“曝光补偿(设置)(Exposure Compensation (Settings))”值相加,得到“曝光补偿(全部)(Exposure Compensation (All))”的值。
平均场景EV100是计算得到的目标EV100值,在直方图中以蓝线表示。 曝光补偿(设置)是后期处理体积中设置的曝光补偿。 曝光补偿(曲线)是从曲线资源得到的Y值。 曝光补偿(全部)是前两个数值之和,得到最终曝光补偿值。
通过将曝光补偿分为“设置”值和“曲线”值,你可以更精确地控制设置,并且更明确地理解为什么曝光补偿会有某种表现。
曝光变化速度
对数间隔调整
例如,使用旧设置时,如果我们当前的线性平均值是1.0,以1000为目标变动,那么在两秒后会达到500.5的中点。
新的线性和指数变动
它会导致抖动行为,因为自动曝光会快速适应亮度的小幅波动。 大幅度的亮度过渡总是很快,没有实用的方法来延缓这种过渡。不可能实现从黑暗区域到明亮区域的缓慢过渡效果。
为了解决这些问题,新的算法在远离目标曝光值时会从线性曲线开始(2),而在接近目标值时会转换为指数曲线(1)。
当我们接近目标曝光值时,变动会从线性变为指数性,使用一条指数曲线来保持一阶导数的连续性。你可以使用控制台变量r.EyeAdaptation.ExponentialTransitionDistance来控制这个数值。此变量在距离目标为r.EyeAdaptation.ExponentialTransitionDistance档F制光圈时将线性过渡设置为指数过渡。
默认的指数过渡距离是1.5档F制光圈。加速和减速将会线性地调节曝光,直至在距离1.5档F制光圈时切换为指数变动。
与先前的行为相比,这种变动方式的更改提供了一些关键优点:
控制抖动减少。由于在远离目标曝光值时适应过程是线性的,可避免屏幕上出现亮斑时的突变。 在需要比较慢的适应时,这些参数能提供更精确的控制。
移动平台对等
注:要在移动平台上实现自动曝光功能对等,需要支持ES 3.1。从虚幻引擎4.25起,引擎中取消了对ES2的支持 。
新的自动曝光默认值
做出这些更改后,我们发现默认曝光补偿值0.0在典型场景中显得太暗了。因此我们在新的后期处理体积中,将默认曝光补偿值改为1.0。但是,你可以选择使用“自动曝光偏差(Auto Exposure Bias)”项目设置更改该默认值。
如果你决定要模拟虚幻引擎4.24或更早版本的行为,可以将直方图范围改为80%和98.3%。然后,应用曝光补偿值log2(1.0/0.18)=2.47。
两种版本都是合理的,其中一种可能更适合你的项目。但是,新的曝光默认值会提供更宽的直方图,默认情况下能让两种不同的曝光模式更为一致
自动更新现有项目和内容
按照理想情况,我们希望内容在不同引擎版本下看起来都一样,但是这一次,这样的选择是不切实际的。我们选择的做法是,在你将项目升级到4.25时自动更新对曝光补偿的应用。
更新的逻辑存储在CalculateEyeAdaptationExposureVersionUpdate()中,它在你的Engine\Source\Runtime\Private文件夹下的Scene.cpp中。
这里需要考虑的主要更改是,如果你的项目启用了直方图曝光,而且在项目设置中启用了扩展默认亮度范围,那么我们就应用一个小曝光补偿来为发生变化的行为做调整。例如,如果最小和最大直方图的平均值是89.15,则应用曝光补偿1.5。但是,如果你有更宽的直方图,应用的曝光补偿就会更小。如果最小和最大平均值是50,将应用曝光补偿1.0。虽然我们很想保证与先前的设置完全吻合,但这样的转换是不可能的,因为要取决于场景的内容。我们发现这些默认值可以为现有内容提供合理的数值。
注:如果你发现项目的转换出了问题,你的原始曝光补偿值就存储在隐藏值AutoExposureBiasBackup中。
总结
希望这里的更改能提供对用户更友好的界面和比先前更高的直观度。还请关注有关自动曝光的文档中即将发布的论述这些主题和变动的更改。
近期焦点