其他
UE4新版大气实时渲染,这些创新点你知道多少?
文丨Rcying
腾讯互动娱乐 工程师
论文作者Sébastien Hillaire应该很多人都会熟悉,之前在Frostbite的部门工作,Frostbite的体积渲染的Siggraph course(Towards Unified and Physically-Based Volumetric Lighting in Frostbite)就是他做的。现在到了Epic,负责的渲染相关工作。
这篇论文的提供的思路非常棒,简单来说使用了一定程度的近似,最后达到的效果为:
· 在保证效果跟path tracing的GT接近的情况下,比以前的预计算LUT,实时采样LUT(Bruneton08)的效率只稍微慢一点;· 有一定的LUT要素,但是LUT完全可以实时计算(大气参数可以实时修改,而且不是分帧更新之类的伪实时,是真的一帧搞定);· 在iPhone6s上可以在每帧1ms以内搞定(包括了LUT计算);· 做了一些近似假设,从而可以用数值方法计算所有高阶散射之和;而不是像之前的方法只计算一定的阶数就结束。在大气稀薄的情况下(高阶散射更加重要)效果提升非常明显。
总结一下,在效率、效果方面,可以说是把以前的方法拉起来全部A了。
当然因为采用了一定的近似,在结论部分作者也提供了一个明显偏差的情况,即大气设置非常厚重(比地球密55倍)时会出现偏差。
但是即便存在这个缺点,该方法依然是比之前的方法存在大量的优越性的。
作者官网以及paper链接:https://sebh.github.io/publications/sebh.github.iohttps://sebh.github.io/publications/egsr2020.pdfsebh.github.io
我是第一次写这种论文导读类型的文章,欢迎指正。
https://ebruneton.github.io/precomputed_atmospheric_scattering/ebruneton.github.io
知乎上也有大佬对大气散射相关原理的解析,这里我推荐一篇 @Lele Feng大佬的文章,最早的时候就是这篇文章让我明白了大气散射的原理:
https://zhuanlan.zhihu.com/p/36498679zhuanlan.zhihu.com
此外,论文中前4章也一定程度上说明了大气散射的原理,可以作为补充。
下一章开始说明Hillaire20的内容。因为本文主要为讲解论文的创新点,因此对于大气散射的原理、计算方法等不会做过多说明。这里假设读者已经完全理解了Scattering、Absorption、Rayleigh、Mie、Henyey-Greenstein、Phase Function、Transmittance等名词的意思,并且清楚大气散射的计算方法。如果发现自己看不懂,建议先阅读上述内容。
另外,开始之前我对一些论文中的名词做出本篇论文语境下个人的解释,可能存在偏差。
Phase Function ,
1.对大气散射特性的观察结论,大意即为天空中大部分的散射现象是低频的,除了靠近地平线部分会变得高频。2.Transmittance LUT的计算,其实就是老方法,不提3.Sky-View LUT4.Aerial Perspective LUT5.Multiple Scattering LUT 重点
Sky-View LUT中包含了当前相机位置接收到的各个角度的Luminance。计算时根据像素对应的视线方向直接做Raymarch得到结果(这里每一步Raymarch中的每一步采样都包含了所有阶的Scattering,如何计算看后文),论文中的例子如下图。
如上面提到,在靠近地平线部分大气散射会变得高频,因此UV的映射不是线性,而是靠近地平线部分会分配更多像素,具体公式在论文中写明了,这里就不复读了。
在论文中的测试,PC上只需要200*100的分辨率效果就足够。另外太阳本身是不会渲染在图里的,因为属于高频特征。会在后面再合成上去。
需要注意的是,这里跟Bruneton08已经不一样了,Bruneton08中不会有任何实时的Raymarch,都是LUT查找搞定;而这篇论文中,不管怎么样,在这一步实时Raymarch都是少不了的(其他的Raymarch步骤可以看情况跳过),这也是相比老方法会稍微慢一点的原因。
1.分割Camera Frustum(和Cluster Rendering中的分割一样),计算每个格子到Camera方向的In-Scattering和Transmittance,保存在Volume Texture中;2.在Volume Texture的z轴方向上根据Transmittance累加In-Scattering,使得每一个单元格保存的是该单元格到Camera的Luminance;3.在Opaque渲染之后,做一次Post Processing,采样上述的Volume Texture,对场景中的物体添加Aerial Perspective;4.Transparent物体渲染时在VS中采样Volume Texture添加Aerial Perspective。
论文作者在计算Multiple Scattering时,认为高阶散射非常低频,从此出发使用了一些简化,包括:
1.大于等于2阶的散射,将Rayleigh散射和Mie散射视为为各向同性的散射。2.计算某点的大于2阶的Scattering时,认为该点周围任意一点的Illuminance与其相同。
第1点的意思是,对于1阶散射,我们认为Rayleigh、Mie散射是正常的,但是在之后的阶数,我们认为相位函数对于任何方向都是相同的值
第2点,原文的描述有点神秘,写的是“Neighbouring points”,在问了作者之后其实意思是在计算某点的Scattering时,空间中任意一点的某一阶的Scattering都视作和该点相同。因为参与计算的点需要与该点有Line of sight,从整个地球的视角来看确实是Neighboring points。这一条近似看上去是非常粗略的,但是it works。
实际流程中,Multiple Scattering LUT的计算可以一个pass输出到一张32*32的2D LUT完成。只需要2D的原因是因为上述简化中我们使用了各向同性Phase Function,不需要存储相机跟光照方向的关系,只需要存储不同高度、不同光照角度的情况即可。
在pass中,论文中提到,首先计算
其中
// 转移函数
第二步,在上述计算完毕后,计算当前像素的Transfer Function
// 多重散射结果
有了
根据数学公式,因为
// 最终计算
根据上文,我们可以得到任意点的所有阶数的Scattering之和,包括一阶Scattering和高阶Scattering之和(
此外在工程方面,这篇文章也是尽可能压缩了各个LUT的大小以得到最好的效率,包括200*100的Sky-View LUT、32*32的Multiple Scattering LUT等等。尽管最后写成论文的就是表中的几个数字,但是这些数据毫无疑问是经过了大量试验得到的。最终在iPhone6s上能跑到1ms以内更是amazing。并且不需要任何的3D贴图,就在VS-PS里直接算就完事儿了。
本文只是挑选了我认为最具亮点的一部分来讲。论文原文中还有许多细节内容,如根据高度自动切换Raymarch方法和Sky-View LUT等,建议有兴趣的读者详读一遍。