如何渲染DOOM以太帧





介绍



《毁灭战士永恒》无需单独介绍:它是《毁灭战士2016》的直接后继产品,它是通过id Software的内部引擎id Tech的第七次迭代而开发的。一次,我为Doom 2016的视觉组件的高品质以及技术解决方案的简洁和优雅而震惊。在这方面,《毁灭永恒》在许多领域都超过了它的前身,其中有些值得详细细分。在这篇分析文章中,我将尝试讨论所有这些。



我的分析是启发约死命2016硬阿德里安Courrèges翻译)。我认为,这些作品为解决AAA项目的一些渲染问题的方法提供了一个概览,因此成为了极好的教材。在此分析中,我计划讨论一般功能,而不是过于深入地研究每种渲染方法和过程的复杂性。此外,《毁灭战士永恒》中的某些段落与《毁灭战士2016》中的段落几乎相同,并且在AdrianCourrèges的作品中已经被分解,因此我可以跳过它们。



我想以一种特殊的方式标记严格的教学当前文章的性质。我绝不支持出于知识产权盗窃或其他恶意目的对产品进行逆向工程。如果您还没有玩过《永恒的毁灭战士》,那么您不必担心:我只介绍了游戏的开始,因此您不会受到破坏的危险。



因此,让我们开始吧。



随着id Tech 7的发布,引擎从OpenGL过渡到Vulkan API,使开发人员可以更有效地使用当前一代GPU的功能,例如无绑定资源。



《毁灭战士永恒》中的一帧







在上方,我们可以看到游戏接近开始时的一部分:内部有多个对手和大量照明。与上一代类似,《毁灭战士永恒》中的渲染过程负责直接渲染,但是如果《毁灭战士2016》被迫与反射表面的G缓冲一起渲染,则在我们的情况下不使用缓冲区,渲染将接管所有任务。



远离大型纹理



随着在ID Tech 5引擎上创建的游戏Rage的发布,世界开始熟悉实现称为“大型纹理”的纹理的概念。此方法在《毁灭战士2016》中使用,并为每帧渲染带有可见纹理信息的所谓“虚拟纹理”。在下一帧中分析虚拟纹理,以确定应从磁盘加载哪些纹理。但是,超大纹理存在一个明显的问题:纹理一旦进入视野,就无法加载,因此纹理出现后的前几帧看起来模糊。随着id Tech 7的发布,开发人员放弃了此方法。



通过GPU蒙皮



通常,即使在渲染任何纹理和阴影之前,顶点着色器也会评估蒙皮。生成皮肤ID Tech 7是通过计算着色器预先执行的,将生成的顶点写入缓冲区。由于采用了这种方法,顶点着色器不再需要蒙皮数据,并且由于不再在每个几何路径上执行该操作,因此,着色器交换的发生频率降低了。



计算着色器和顶点着色器中的蒙皮之间的主要区别在于将结果写入中间缓冲区。与顶点着色器一样,对于每个顶点,计算着色器线程会从影响顶点的每个骨骼接收一个转换。然后,随着每次骨骼变换,它都会改变顶点的位置,并根据顶点中存储的皮肤的重量将所有新位置加起来。结果,顶点着色器可以使用缓冲区中的结果将其解释为静态网格。



该链接提供了JánosTuránszki撰写的有关Compute Shader Skinning的出色文章。



值得注意的是,《毁灭战士永恒》使用了一种有趣的缓存-Alembic Cache与高度压缩的可回放视频相当。这些高速缓存存储要在程序执行期间发布和扩展的烘焙动画。Alembic Cache引用了Digital Foundry的技术分析,将其应用于各种动画,从大型电影场景到地板上的小触手。对于通过皮肤动画实现复杂性的动画,例如有机物和组织模拟,此方法特别方便。如果您对此技术感兴趣,建议您在Siggraph 2014上查看Axel Gneiting演示文稿



阴影贴图



下一步是阴影渲染,乍一看,id Tech 7及其前身生成地图的方法没有什么不同。



正如您在下面看到的那样,阴影被渲染为大的纹理,其深度为24位,尺寸为4096 x 8196像素,其位置质量有所不同。帧之间的纹理不会改变,根据Siggraph 2016上的演示“细节中有魔鬼”,则静态几何体会缓存在阴影贴图中,以避免在每一帧都重新绘制它。这个想法本身很简单:在光源前面移动之前,我们不需要更新阴影,因此我们可以声明“缓存”阴影贴图:具有静态几何形状的常规贴图,因为我们假设几何形状不会改变...如果动态对象在视锥中移动,则将“缓存的”阴影贴图复制到主对象,然后在其顶部重绘动态几何。这种方法允许每次更新时都不必在视锥中重绘整个场景。自然地,如果光线发生移动,则整个场景将不得不从头开始重新绘制。



3x3 PCF采样用于在对地图采样时平滑阴影的边缘。由于阳光通常覆盖大部分环境,因此使用级联阴影图可以更好地分配质量。



例如,看一下阴影贴图集。光线越显眼,屏幕上的区域越大,或者物体离摄像机越近,所选的图集片段就越大-这对于增加细节是必要的。这种启发式方法是动态评估的。







深度速度和预通过



从玩家的武器开始,将不透明,静态和动态几何图形顺序渲染到目标深度。通常,为了不对潜在的几何相交处的像素着色器进行不必要的计算,在将结果添加到缓冲区的情况下执行深度处理的初步处理。由于在相交时重绘像素会产生不必要的重新计算,并最终对性能产生负面影响,因此此方法的重要性变得无价。使用深度预通过,直接照明像素着色器可以通过在实际计算之前将它们与深度缓冲区进行比较来消除多余的像素,从而节省了宝贵的资源。





播放器武器





静态对象





动态对象



在预传递中,不仅渲染深度,而且渲染目标颜色。在动态几何中,通过运动矢量(即从上一帧中的像素位置减去当前位置的位置)来呈现速度。由于运动存储在16位浮点渲染目标的红色和绿色通道中,因此我们只需要知道X和Y运动,然后将该信息用于后处理即可应用模糊和时间反走样的重新投影。静态几何不需要运动矢量,因为它仅相对于摄影机“运动”,并且其运动可以根据摄影机本身的运动来计算。正如您在下面的屏幕截图中所看到的,我们的场景中没有太多移动。







Z层次深度



下一步是生成分层深度缓冲区mip链:此链类似于mip贴图,但是取其最大值而不是平均四个相邻像素。这种方法通常在图形中用于各种任务,例如加快反射速度并丢弃受阻的几何图形。在我们的例子中,mip链正在丢弃照明和贴花,我们将在后面讨论。最近,已经一次性完成了mip生成,一次记录了多个mip-s,但是在《永恒的毁灭战士》中,仍然对每个mip分别进行记录。







网格贴花



到目前为止,我们还没有时间了解《毁灭战士永恒》与《毁灭战士》 2016年之间的主要区别,但是网格贴花属于这一类。这些是小贴花(螺栓,格栅,凸块),与常规贴花一样,会影响任何表面特性(法线,粗糙度,颜色)。但是,典型的网格贴图是由艺术家在网格开发期间分配的,与环境中贴图的标准放置不同,它属于自己的网格。过去,Doom严重依赖贴花,而目前转向网格贴花的做法仅增加了图形的细节和灵活性。



为了获得此好处,下一次几何传递将每个贴图的ID渲染为8位纹理。此外,在应用阴影时,我们对纹理进行采样,并通过标识符获得与每个绘制调用关联的投影矩阵。矩阵将像素坐标从世界空间投影到纹理空间,然后使用这些坐标对贴花进行采样并将其与表面材质合并。这项技术的执行速度非常快,为艺术家处理各种贴花打开了广阔的空间。由于ID渲染为8位纹理,因此单个网格上最多可能有255个贴花。



所有这些的唯一条件是,渲染网格时,所有贴花纹理都绑定到进程。通过完全不相关的渲染过程,开发人员可以一次链接所有贴花纹理,并在着色器中动态索引它们。由于开发人员使用此方法在游戏中实现了更多技巧,因此我们稍后将详细讨论不相关的渲染过程。



在下面我们可以看到贴花纹理网格。为了方便显示,标识符以不同的颜色上色。







抛下灯光和贴花



《末日永恒》中的光线是完全动态的,并且多达数百个光源可以同时照射到视野中。此外,正如我们之前指出的,游戏中的贴花非常重要,例如,在同一个Doom 2016中,贴花的数量超过了数千。所有这些都需要一种特殊的方法来丢弃多余的对象,否则性能将无法承受像素着色器的严重性。



毁灭战士2016使用了基于处理器的群集光抑制版本:将光和贴花收集到圆锥形的“ froxels”中,然后在着色过程中通过从像素位置确定群集索引来读取它们。每个簇的大小为256像素,并被对数分为24个部分以保持正方形。此技术很快被许多其他开发人员采用,例如在《底特律:成为人类和正当理由》中发现了类似的方法。



随着动态光源(数百个)和贴花(数千个)的增加,在Doom Eternal中,灯光投射的CPU群集不足,因为体素变得太粗糙了。结果,开发人员为id Tech 7提出了另一种方法,并且通过在各个阶段执行的计算着色器,他们创建了软件光栅化器。首先,贴花和光线被链接到六面体(六边形)中,并传递到计算光栅化器,顶点从此处投影到屏幕空间中。然后,第二个计算着色器将三角形修剪到屏幕的边缘,并将它们组装成256 x 256像素的图块。同时,类似于群集丢弃,将光源和贴花的各个元素记录在像素中,之后,下一个计算着色器对图块32 x 32像素执行类似的过程。在每个图块中,通过深度测试的元素在位字段中标记。最终的计算着色器将位域转换为最终在光照过程中使用的光照列表。有趣的是,类似于聚类方法,元素索引仍以256 x 256像素的三维像素记录。在深度明显中断的地方,将比较新的光源列表和旧的群集光源列表的最小值,以确定每个图块中的光源数量。最终用于照明通行证。有趣的是,类似于聚类方法,元素索引仍以256 x 256像素的三维像素记录。在深度明显中断的地方,将比较新的光源列表和旧的群集光源列表的最小值,以确定每个图块中的光源数量。最终用于照明通行证。有趣的是,类似于聚类方法,元素索引仍以256 x 256像素的三维像素记录。在深度明显中断的地方,将比较新的光源列表和旧的群集光源列表的最小值,以确定每个图块中的光源数量。



如果您没有处理传统的栅格化,那么您可能不清楚这样的丰富描述。如果您想更深入地研究这个问题,我建议您研究此类过程如何工作的一般原理,例如,Scratchapixel对这一主题有很好的分析



该系统还丢弃了用于查询游戏可见性的所谓“范围”。由于用于计算线程的软件光栅化是一个漫长的过程,因此占用率很可能很低,因此添加一些额外的帧几乎不会影响性能。考虑到这一点,光很可能异步投射,因此对性能的净影响最小。



阻挡屏幕空间中的环境光



使用标准方法以一半的分辨率计算环境光遮挡:首先,从半球中每个像素的位置发出16条随机光线,然后使用深度缓冲区确定与几何图形相交的光线。越多的光线穿过几何图形,障碍物将越大。这项技术称为“屏幕空间定向遮挡”或“ SSDO”,Yuriy O'Donnell的详细描述可以在此处找到。代替传统的在单通道纹理中存储遮挡值的方法,将定向遮挡存储在三分量纹理中,并通过像素法线上方的点积来定义结果遮挡。



由于计算是在半分辨率下完成的,因此结果非常嘈杂。为了使用深度缓冲区提高质量,应用了双面模糊。环境光阻挡通常发生在低频处,因此模糊通常不明显。







不透明的直通通道



在这段文章中,许多元素终于落到了位。与《毁灭战士2016》不同,这里的所有内容都是直接通过数个大型超级着色器渲染的。据推测,整个游戏中大约有500个处理器状态和十二个描述符布局。首先渲染玩家的武器,然后渲染动态对象,然后渲染静态对象。请注意,顺序并不是特别重要,因为由于有了深度预通过,我们已经收到了深度缓冲区,因此可以预先排除与深度不对应的像素。





玩家武器





动态对象





第一组静态对象





第二组静态对象



对于大多数AAA游戏引擎而言,着色器图形和静态着色器功能使开发人员可以利用各种材质和表面来发挥创意,每种材质,每种表面都可以产生自己独特的着色器。因此,对于引擎功能的所有可能组合,我们面临着令人难以置信的各种着色器置换。但是,id Tech与其他AAA项目有很大的不同:它将几乎所有的材料和功能都组合到了几个大型巨型着色器中。这种方法使GPU可以更紧密地组合几何图形,从而对性能产生积极的影响。我们将在后面讨论。



未绑定资源



值得注意的是,形成图形的整个过程都包含``无关资源''的思想。这意味着,无需在每次绘制调用之前链接模糊,反射,纹理粗糙度,而是一次链接场景中的整个纹理列表。列表中的纹理通过常量传递给着色器的索引在着色器中动态访问。因此,通过任何绘画调用,您可以获得任何纹理,这为许多优化开辟了道路,我们现在将讨论其中的一种。







动态合并绘图调用



在完全解耦的资源架构之上,所有几何数据都是从一个大缓冲区分配的。该缓冲区仅存储整个几何的偏移量。



这就是idTech 7最有趣的技术发挥作用的地方:动态合并绘图调用。... 它依赖于解耦的资源架构和通用的顶点内存,最终显着减少了绘制调用的次数和处理器时间。在开始任何渲染之前,计算着色器会动态创建“间接”索引缓冲区,以有效地将不相关的网格中的几何图形合并到单个间接绘制调用中。如果没有不相关的资源,则呼叫合并将不起作用,因为它适用于材料属性不匹配的几何。将来,无论是深度预演还是照明预演,都可以再次使用动态索引缓冲区。



感言



最常见的计算着色器使用射线marching算法来创建屏幕空间反射。该算法从像素向世界空间向反射方向发射射线,这取决于反射表面的粗糙度。在《毁灭战士2016》中也是如此,在前传中记录了一个小的G缓冲区。但是,在《毁灭战士永恒》中不再有任何G缓冲区,甚至屏幕空间反射也不是在计算着色器中单独计算的,而是在直接着色器中立即计算的。有趣的是,知道像素着色器的这种偏差如何影响性能,因为似乎以增加寄存器负载为代价,开发人员正试图减少渲染目标的数量,从而减少内存带宽的负载。



通常,当屏幕空间纹理不包含必要的信息时,渲染伪像会出现在相应的效果中。在看不见的反射物体无法反射的情况下,这种现象最常见于屏幕空间反射。通常使用传统方法(使用静态反射立方体贴图作为备份)解决此问题。







但是,由于《毁灭永恒》中不再使用大型纹理,因此也不需要后备纹理。



粒子



模拟



在《毁灭战士永恒》中,粒子处理器模拟的一部分落在了计算着色器的肩膀上,因为某些粒子系统依赖于屏幕空间信息,例如用于模拟碰撞的深度缓冲区。其他粒子系统可以一次在框架中运行并异步计算,而此类模拟则需要初步的深度预通过数据。什么是特性,与传统的粒子着色器模拟不同,此处的模拟是通过从存储在计算着色器中的缓冲区执行一系列“命令”来执行的。每个着色器线程都运行所有命令,其中可能有多个终止,发射或粒子参数修改。所有这些看起来都像是在着色器中编写的虚拟机。我对这种模拟的复杂性了解不多,但是这种方法是基于在Siggraph 2017上的Brandon Whitney的“命运粒子体系结构”演讲中演示文稿中的方法与我上面描述的方法非常相似,并在许多其他游戏中使用。例如,我非常确定Niagara粒子模拟系统在虚幻引擎4中的工作方式相似。



灯光



与Doom 2016和Siggraph 2016中描述的方法类似,照明粒子分辨率与实际的屏幕分辨率脱钩,从而使开发人员可以基于质量,屏幕尺寸和直接控制来控制每个粒子系统的分辨率。对于低频效果,与例如需要高分辨率的火花相比,可以以低得多的分辨率提供照明,而几乎没有质量损失。光照和主要方向存储在两个2048 x 2048像素的地图集中,这两个地图集每次都可以通过未绑定的资源,就像其他任何纹理一样。此外,对于渲​​染粒子,可通过对这些地图集进行采样来绘制简单的几何图形。





照明图集的放大片段。



天空和零星



现在我们将讨论体积照明。它的生成包括四遍,并通过向天空朝向光源射线散布为天空大气创建3D LUT纹理开始







从一开始,您可能就不了解纹理在图片中确切显示了什么,但是如果将其旋转90度并水平拉伸,则一切都会变得清晰:我们散布了气氛。由于垂直方向的可变性大于水平方向的可变性,因此垂直分辨率更高。大气层由一个球体表示,因此水平旋转通常称为经度,垂直旋转通常称为纬度。大气散射是由半球计算得出的,覆盖球体顶部的经度为360度,纬度为180度。为了覆盖到观察者的不同距离,LUT纹理包含32个深度段,并且该过程分散在32个帧中,而不是在每个帧中重新计算天空数据。







多亏了LUT纹理,下一次通过类似于较小规模的簇状障碍物,通过观察到的“ froxel”来计算光散射。您可以从下面观察到从近到远的几个部分。







在第三遍中,每个单元的散射数据在视图方向上乘以每个后续单元,并写入新的3D纹理中。



结果,通过基于像素深度对新生成的3D纹理进行采样,将体积照明放置在渲染图像的顶部。





之前





之后之后



如果在视图中,则最终的“可见”天空将在半球中渲染。在此场景中,天空未包含在评论中,但是下面您可以看一下在室外场景中渲染天空的示例。







透明度



与Doom 2016相似,当存在光散射数据时,在不透明几何体之后通过向前通过来呈现透明性。同时,场景纹理的分辨率下降(下采样),并且选择了合适的Mip级别以基于表面的平滑度“模拟”透明度。光散射数据有助于从表面内部产生视觉上良好的散射。



下面您可以看到场景中纹理贴图链的示例,其中更透明的表面落入视口中。





对于透明度,只有与之相关的像素会丢失分辨率。



用户界面



通常,帧中的最后一个通道是用户界面。通常情况下,将接口渲染为辅助的全分辨率LDR(八位)渲染目标,并将颜色预乘以alpha通道。在色调映射过程中,界面会叠加在HDR纹理上。使界面与框架中的其余HDR内容配合使用通常很棘手,但是在《毁灭战士永恒》中,色调映射可以神奇地缩放界面并与其他3D内容看起来很自然。







后期处理



后期处理的第一件事是模糊:这种两遍效果从颜色纹理和自定义速度缓冲区读取数据。第一遍在垂直轴上收集四个样本,第二遍-沿水平方向收集四个样本。然后根据像素移动将色样混合。为了避免模糊,自定义速度缓冲区必须确保没有重影,并且将玩家的武器排除在进程之外。



接下来是目标影响:此RG(双色)1比1纹理包含整个场景的平均照度,并且是通过依次对颜色纹理进行下采样并获得一组像素的平均照度来计算的。大多数情况下,此技术用于模拟人眼习惯于环境亮度的急剧变化。另外,在计算色调映射期间的影响时,将使用平均照度。







完成所有这些之后,便计算出Bloom。在我们的示例中,这种效果是不够的,并且不可能将其广泛渲染,但是足以知道该计算是通过获取高于特定限制的颜色数据并逐渐降低纹理分辨率以使其模糊来进行的。



然后色调映射结合了所有效果。单个计算着色器执行以下操作:



  • 应用失真
  • 布隆纹理上渲染
  • 计算渐晕,相机上的污垢,色差,镜头眩光和许多其他效果
  • 根据平均照度获取曝光值
  • 允许色调映射通过自定义色调映射运算符将LDR和HDR的HDR颜色分配到正确的范围。


最后,该界面叠加在顶部。失真



纹理甚至在后期处理之前就已渲染:像粒子效果引起的雾霾之类的几何体以原始分辨率的四分之一的格式渲染到新的渲染目标中。在此渲染中,失真数据存储在红色和绿色通道中,而遮挡存储在蓝色中。当图像在色调映射步骤中失真时,将应用获得的数据。







结论



尽管我们确定我还没有涉及影响游戏外观的一些事情,但我们对《毁灭永恒》一枪的粗略分类已经结束。我认为,《毁灭战士永恒》是一项令人难以置信的技术成功,id Software将来将能够进一步提高标准。开发团队已成功向我们展示了聪明的思维和有效的计划如何帮助创建了高质量的游戏,我相信这是很好的榜样,同时也是教育材料。我期待id Software的未来发展。



撕裂,直到完成。



参考资料






All Articles