欢迎光临散文网 会员登陆 & 注册

Lumen全局光照和反射技术

2023-03-15 11:34 作者:一罐摇摇粉  | 我要投稿

首先这是曾经的一篇课程报告,其次也算是GAMES104课程对应章节的学习笔记,最后个人还感觉有一miumiu分享价值,那顺手水一篇专栏吧!

引言

在本世代的图形硬件与算法支撑下,人们已经可以使用光线追踪技术在计算机中生成近乎完美的真实感图像,但与之相对应的代价就是高昂的算力要求与时间成本,这在游戏生产中是不可接受的。虽然现代图形接口与游戏引擎已经普遍兼容最新的硬件光追,能够极大地平衡图像质量与所需的帧生成时间上的关系,但由于其对图形处理器的硬性要求仍旧很难将其推广至所有用户群体之中。并且,即便是使用最新的图形硬件加速卡所搭载的光追单元进行计算,往往也只能达到每帧图像个位数spp采样数的水平,其算力还是远远不能满足使用纯粹的光线追踪算法生成图像的要求,而需要搭配诸如时域采样结果复用、图像空间降噪过滤、深度学习超采样等技术来使得特定场景的最终渲染结果看上去像那么回事。

正是由于光线追踪技术当今硬件水平下的实时渲染领域存在诸多限制条件,虚幻引擎技术团队研发了Lumen这样一套用于全局光照和反射系统的渲染技术,用于满足下一世代游戏主机与个人电脑上的图形应用。Lumen能够在拥有大量细节的宏大场景中渲染间接漫反射光照结果,并确保无限次数的反弹以及间接高光的反射效果;无论是毫米级别的场景细节,还是数以千米的宏大场景,它都显得游刃有余。

使用Lumen技术得到的令人惊艳的全动态实时全局光照与反射效果

1 快速光线求交

实现间接光照的核心之一是射线在三维场景中的求交,为了实现更加高效的光线求交操作,Lumen使用了SDF有向距离场作为其加速结构。SDF顾名思义,其表征了空间中任意一点到最近表面的距离,当其在几何体外部时值为正、在内部时值为负。在传统的三维形体表达中,我们往往会使用点线面的离散表征,当需要进行几何处理时 不得不进行全局的三角形遍历,这对于计算与存储都造成了相当大的冗余;而在三维空间的SDF表征中,我们获得了一个空间中连续的场,可以在任意位置得到相应的值,并且可以利用其可微的性质进行各种各样的几何处理。例如,连续可微的SDF表征使得人们可以利用Mipmap的思想对三维形体快速生成不同等级的LOD模型,也可以通过对其求导得到模型表面的法向梯度。总体来看,SDF为我们提供了一套统一的、无限精 度的模型网格表达方式,在许多方面存在着相当大的优势。

SDF有向距离场的可视化

一旦有了场景的SDF表达,我们就可以在其中进行快速且鲁棒的光线求交操作。在以往的传统场景中,进行射线检测往往会使用一种叫做光线步进的方法进行,即每一步向射线方向进行一定跨度的试探,检测新的位置点是否处于几何体内部从而进一步计算 射线与场景的交点。而在这个过程中,步进长度的选择有成为了一大难题,过大的步长容易错失较小的几何体,过小的步长又会造成相当大的计算资源开销,人们总是绕不开要在速度与精度之间找到一个平衡点。而在SDF中,场景中的每个点都能快速查询到与其最近的几何体的距离,从而安全地引导光 线按照射线方向进行每一步的步进,即便在少数情况下错误的步进操作使得光线进入了几何体内部也可以由SDF的有向特性方向修正至几何表面,得到光线与场景的交点。

通过SDF实现快速精确的Ray Marching

由于存储整个场景的SDF将造成极大的空间浪费,因此我们可以对场景中的每一个网格生成单独的分辨率与尺寸相匹配的SDF。对于一个拥有成百上千对象的游戏场景来说,其通常是由更少的物体通过平移、缩放、旋转操作得到的,这样就可以仅生成每个物体的SDF,通过数学变换得到整个场景的表征。对于每个SDF所包裹的网格,一定还是会存在一定的空余空间冗余,于是还可以进一步对SDF进行稀疏化处理,通过索引表的方式压缩存储空间,进一步节省了存储消耗。

对每个物体实例建立的局部SD
使用局部SDF组建场景表达(左)
和使用全局SDF进行场景表达(右)

但是,当场景的物体数量非常之大时,这样的存储方式又会造成计算资源的瓶颈,因为每一根光线在做场景求交时都需要与整个场景中所有的物体进行求交查询。此时Lumen所用的解决方案就是将所有分散的基于物体的局部SDF重新合并成一个全局 的低精度稀疏SDF,在每帧对非静态的物体进行更新。此时,就可以将两种存储方式进行结合,在每次光线求交时首先查询低精度的全局SDF得到粗糙的交点,而后仅查询其周边网格的局部SDF得到更加精细的交点。如图灰度值表现了在局部SDF与全局SDF中进行光线追踪的资源开销,越明亮的像素表示更多的求交耗时,可以发现在全局SDF 的加持下,能够极大地提高光线对物体求交的性能。

局部SDF场景的光追开销(左)
和全局SDF场景的光追开销(右)

在实际工程应用中,Lumen系统还使用4层Clipmap对全局SDF缓存进行了进一步空域和时域上的优化。在空域上,Lumen使得全局SDF在最靠近相机的区域拥有最高精度,而离相机视野越远的区域则拥有更低的精度;在时域上,只有最近层级的SDF需要每一帧更新,而越远层级的SDF则有着更低的更新频率。至此,Lumen所使用的SDF架构为光线求交提供了一个高效的场景表达,使得光线追踪的过程不再依赖于特定的图形硬件也能达到相当不错的性能水准。

不同颜色所表示的4层Clipmap范围

2 光子注入与缓存

光子注入与缓存是存储场景中光照结果的过程,渲染引擎可以通过该光照结果计算场景最终的全局光照效果。这里需要关注的是,全局光照的计算其实是从光的视角照亮整个世界后,每个被照亮的面片再次作为灯光对场景做出照明贡献的过程。在Lumen的实现中,提出了一个叫做Mesh Card的概念,它将每个物体与坐标轴对齐的六面信息都拍一次快照,用于生成Surface Cache。这一个过程分为两个Pass:第一步 根据物体离相机的距离选择合适的分辨率采集每个Mesh Card信息,同时获得物体各个面的Albedo、Normal、Depth等通道纹理,将其分类存储在多张512×512的纹理图集中;第二步将所有Mesh Card拷贝至Surface Cache。所谓的Surface Cache是多张4096×4096的纹理,每个通道均享有这样一张纹理的内存空间,其中的Mesh Card信息会随着视野范围换入或换出,并在光源变动 或相机移动时对“脏”的纹理内存块进行必要的更新,若纹理空间被存满则抛弃那些对间接光照贡献度低的Mesh Card。在Surface Cache被存储时,Lumen的方案是针对各个通道的信息特征选择合适的硬件支持的压缩方法对图像纹理进行压缩,以减少大尺寸的表面纹理缓存对内存的占用。

对物体Albedo信息构建的Mesh Card
Albedo通道表面缓存构建

当完成Surface Cache的预计算存储之 后,下一渲染环节就是如何确定其中每一个像素点应有的光照结果,并通过与光子映射类似的手段将其固化在缓存中。为了生成Surface Cache Final Lighting结果,除了上一步已获得的物体材质多通道缓存以外,我们还需要Surface Cache Direct Lighting、Surface Cache Indirect Lighting、World Space Voxel  Lighting三种缓存信息。其中的逻辑关系为:根据物体材质多通道纹理计算直接光照在各个位置的着色值,并使用SDF场跟踪光源的Shadow Map判断可见性,得到直接光照表面缓存,作为最终光照结果表面缓存的贡献;而后利用最终光照结果缓存照亮三维空间,建立世界空间下对光照信息的体素网格表达,每个体素存储六个面的亮度信息,并以次为下一帧提供间接光照信息;在下一帧中建立间接光照表面缓存,该缓存具体表现为每4×4个纹素中的一个间接光照探针,每个探针跟踪半球上的16根光线 进行光照采样,最终存储为占用4×4纹素内存大小的球谐函数表达,其中探针位置与采样射线每帧进行恰当的抖动,最后与直接光照表面缓存一起合成最终光照表面缓存。如  此不断循环,上一帧的光照信息不断加入到下一帧的间接光照贡献中去,相当于利用时域复用的手段增加了间接光照的反弹次数,最终得到收敛的全局光照结果。在实际操作UE5的Lumen光照系统时,也能直观地感受到场景大幅变动后阴影区域逐渐由暗变亮的过程,这便是Lumen所用的光照缓存管线从初始状态不断传递多次光线反弹信息的结果。 

Surface Cache计算流水线
从Surface Cache构建的世界空间光照信息体素表达


物体表面放置的间接光照探针
最终光照缓存合并

对于游戏引擎而言,每次更新一整套4096×4096的Surface Cache还是太过消耗计算与带宽,Lumen则为其更新方案提出了一个固定的预算。对于直接光照表面缓存而言,每次着色开销相对较小,每一帧最多更新不超过1024×1024的纹素信息;对于间接光照表面缓存,由于要使用上一帧构建的体素光照信息并基于SDF采样,将产生较大的性能开销,于是则限定每一帧更新不超过512×512的纹素。因此,Surface Cache一次性所更新的内容一定有可能小于世界空间中的所有信息,对每一个Mesh Card就必须使用特定的评估机制来确保它们能够按照合理的顺序更新。作为实施方案,Lumen使用了基于128个“桶”的桶排序的优先级队列管理Surface Cache,并按照优先级更新其中的制定纹素区块。

3 光照探针与着色

在完成Surface Cache的建立之后,我们相当于将场景的辐照度信息一一固化在了每个物体的包围盒表面,之后便可以针对物体的某一点利用这些照度信息做具体的着色。但是针对具体的像素而言,我们还是需要对其表面所在的半球空间方向做采样,这个过程无疑是相当耗费机器性能的,Lumen对此则提出了使用光照探针的解决方案,在场景中合理地分布不同的探针并记录各个方向的光照信息,以便在着色时可以快速从场景探针中取样和插值,减少了逐像素光线采样的计算和通信开销。

屏幕空间探针分布
探针信息内存存储顺序

为了构建光照探针,首先需要确定的是探针的空间分布关系。按照最直接最自然的 想法,我们可以在场景空间中均匀分布无数个光照探针,并通过上一步所获的表面缓存以及世界空间体素光照信息烘焙所有探针。但在实际应用中,场景的表面往往是起伏不定的,靠近相机与远离空间的区域所需要的光照信息密度也是不相同的,因此均匀放置的光照探针实际上无法表达光场的变化。Lumen则提出了非常聪明的屏幕空间光照探针分布策略,在屏幕空间中每隔16×16像素放置一个探针,这个尺度间隔是足以表征间接光照这一类低频信号的,并且后期合成时通过表面本身的法线等高频信息也可以良好地还原几何表面的样貌。Lumen同时还使用了一套近似的判断准则,当检测到一些拥有巨大深度差异的临近像素时,16×16的间隔不足以表示该区域巨大世界空间距离下的光场变化,则会在指定区域进行探针的加密布置,从16×16的探针分辨率提升至每间隔8×8乃至4×4分布,实现了自适应屏幕空间探针布置。在光照探针信息存储上,Lumen又设计了一套非常巧妙的方法:探针信息的存储同样使用一套方形的纹理空间,但实际用户设备通常不是一块等比例的方形显示器,于是基于屏幕空间的探针分布对等地存储到纹理空间中时必然会有空余的内存区块,而这一区块便正好用于存储加密后额外布置的探针信息,通过索引即可快速定位对应内存,同时保证了内存的利用率与连续性。

屏幕空间探针的八面体采样
重要度采样策略

其次,还需要确定如何获得探针中应该保存的信息。Lumen所使用的方案是将探针所在球面空间做八面体映射,并在八面体UV空间下做8×8的采样。然而要在如此低 的采样率下达到视觉上完美的光照效果,重要度采样就成为了必不可少的一环,我们必须向光源方向投射更多的采样射线。为了估计光照的方向信息,可以假设场景中的相机、光源变化足够缓慢,这样就可以从上一帧的探针中遍历采样光照信息。在实际应用中,Lumen将上一帧光照信息进行重投影,并在临近的四个屏幕空间探针中求得平均得到8×8的辐照度图,图中亮的部分就是光源贡献较大的区域。这种方法并不需要昂贵的采样过程,因为光线信息已经按照索引存储在了八面体对应的图集内存中。另外,要得 到具体像素的间接光照还需要该区域的法向信息,从而将探针中背向几何面的光照信息做剔除,并对面向光源的光照信息做进一步的着色计算。但对于一个像素来说,其所具备的法线是高频信号,无法直接与低频的探针信息相匹配,因此Lumen选择在屏幕空间中像素所用探针周围的32×32像素空间内,筛选深度差异小于一定阈值的区域随机撒64个采样点,用于计算该区域的微平面法向分布函数,并进而得到BRDF概率分布函数。此时,我们同时拥有了探针处的Lighting PDF和BRDF PDF,结合二者分布信息便可剔除不需要的方向的采样,同时将省出来的采样次数用于更加重要的方向进行超采样,在同样64根采样射线限定的情况下获得更加精确的辐照度等信。 

均匀采样(黑)与重要度采样(白)示意图
均匀采样(左)与重要度采样(右)效果对比

每个探针64次采样算是为算力限制做出了妥协,为采样计算与存储空间节省了许多资源,但同时也会导致其得到的信息仍然不够稳定,直接用于渲染一幅图像容易得到斑驳的画面结果。为了解决这个问题,Lumen在使用探针信息时将一同考虑与其相邻的几个探针,用作探针信息的降噪过滤。在将临近探针与当前着色点相匹配的辐照度采 样结果纳入光栅化过程前,还需要对其进行可用性检测:一是要求临近探针采样值实际对应的重投影光线角度误差小于10˚,减少光照信息被错误重用的可能;二是要求该光线与场景命中距离与实际着色点处差距不大,防止漏光现象的发生。经过如上步骤,能使得画面渲染效果更加自然、真实。

重用临近信息时的可用性检测指标
复用周边探针信息得到的更好结果

此时屏幕空间的光照探针还存在一定的缺陷,为了在运动的画面下获得正确的渲染效果,还必须每帧更新全屏的探针。探针的采样更新过程可以被视作光线追踪过程,我们知道光线追踪着色的过程不仅与采样的光线数目、场景的复杂度有关以外还跟光线投 射的距离有关,近距离的光线求交将比远距离追踪效率高出非常多,而屏幕空间探针贴近物体表面放置,于是容易造成场景中光线追踪过程将跨越非常大的距离导致性能低下。Lumen就此又在视野空间中构建了一套在世界空间下布置的光照探针,用于存储场景各个位置的光场信息,而这些探针则在光源不变的情况下无需重复更新,仅需在相机移动时增添与删除对应的探针,相当于实现了场景光照信息的预计算。具体地,这里的世界空间探针也使用了多层Clipmap结构优化计算与存储,每个探针的球面光线采样数增加到32×32,提供更加精确的场景照明信息。这样一来,在采集屏幕空间探针信息进行光线投射的过程中,就可以重用附近世界空间探针光场信息,实现将投射光线与预计算光线相连接的效果,大大减少了光线追踪的距离。

世界空间光照探针
不同探针的“光线拼接”示意图

最后,我们已经通过各种技巧优化了得到最终屏幕空间光照探针信息的过程,可以进入最终的像素颜色计算环节。在执行最终 着色之前,Lumen选择将光照探针中的球面空间光照信息投影到球谐函数空间下,得到低频平滑的辐照度信息,从而减少原本采样下的高频跳变与抖动。在具体像素着色时,便可引用这些密集的屏幕空间探针中的低频球谐光照信息与对应G-Buffer中的高频几何信息做最终光照结果的计算,得到令人惊叹的全局光照和反射效果。

利用探针信息与几何信息渲染画面

4 总结

在过去离线的光线追踪真实感渲染器一直是许多视觉艺术家与视效公司手中最得力的工具,而如今随着图形硬件与图形算法的发展,我们几乎已经可以利用最先进的游戏引擎实时产生类似的结果,目前也有不少影视级别项目开始用上了虚幻制作管线。Lumen光照系统的出现奠定了未来游戏引擎渲染质量的标杆,虽然Lumen还是基于本世代的硬件水平做出了大量的妥协、引入了大量的“Hack”,但随着未来图形硬件的继续进步,一定会有更多更先进更具创新性的渲染技术层出不穷,Lumen没准会成为图形算法渲染领域这一征程的开端。(不过眼看着现在AI视频的稳定性每天都在提升,抛开像Lumen这种单纯的图形技术来说,以后会不会出现1ms渲染base color、15ms交给AI重绘的渲染管线出现呢,这下行业可又得经历一场洗牌了,拭目以待吧!)





Lumen全局光照和反射技术的评论 (共 条)

分享到微博请遵守国家法律