Red Dead Redemption 2图形分析

我最喜欢的游戏之一,《荒野大镖客:救赎》Red Dead Redemption)于2018年回归,并附带了游戏机前传在2019年,它发布了PC版,我终于设法玩了; 我立刻被她的图形打动了。但是,我很沮丧:在台式机1050Ti GPU上,我几乎无法以25 FPS的平均设置进行游戏。我知道我的汽车不是很强劲,但在中等设置下为25 FPS?



今天,我们将看一些游戏中的帧示例,并分析游戏中使用的图形技术。



前言



这是对游戏的非官方分析。我刚刚使用RenderDoc分析了帧捕获。如果您想从开发人员自己那里获取信息,则可以研究Fabian Bayer的 SIGGRAPH演讲中的幻灯片幻灯片(页面底部),视频(从1:58:00开始)。



您还可以阅读由Adrian Correzhe [ 翻译成Habré] 执行 GTA5 图形分析。由于RDR2和GTA5都是由同一公司创建的,并且使用相同的引擎,因此GTA5的一些技巧也将在此处介绍。 另一个重要的一点是,我不是一个经验丰富的图形程序员,还是这个领域的初学者。因此,我不太了解。如果您发现错误或需要改进的地方,



给我写信我们走吧!



解析框架



这是我们的主要分析框架:





该帧是在具有中等设置的PC上捕获的。



在RDR2之类的游戏中,几乎不可能在一帧中探索所有的技巧。他们的工作在几个框架之间进行。因此,我捕获了几帧,但是上面显示的将是主要的一帧。它包含许多属性,包括:聚光灯和聚光灯,定向照明(非常小,但确实如此),建筑物,NPC,马匹,树木,植被,云朵等。它显示了游戏中使用的大多数渲染技术。


RDR2是一款开放世界的游戏,因此正在进行流数据下载。因此,成帧从一组任务开始,例如创建和删除纹理,扫描着色器资源,随机扫描,更新描述符,缓冲区等。



地球/泥浆图



污垢起着重要作用。除了充当游戏机制外,污垢还使环境更加逼真。该游戏将人和马的轨道纹理与马车车轮轨道的纹理一起渲染到位移图中。渲染地形时,此累积的纹理用于视差遮挡贴图



泥浆地图


污垢图:R16_UNORM尺寸为2048x2048



天空和云



经过污垢计算后,游戏将执行大量GPU计算工作。它们主要是指天空和云彩。云,雾和体积照明是RDR2中最突出的影响。您可以从Fabian的幻灯片中了解有关此步骤的更多信息。他比我更详细地解释了所有这些。



环境图



环境图是RDR2和GTA5反射的主要来源。

与GTA5一样,RDR2从摄像机位置生成环境立方体贴图。游戏引擎会为环境地图生成一个稀薄的GBuffer,类似于《孤岛惊魂4》中使用的那个



环境图反照率


多维数据集环境图的面(反照率): RGBA8_SRGB



环境贴图法线


环境立方图的面(法线): RGBA8_UNORM



环境图深度


环境多维数据集边缘(深度):D32S8



在每一帧中生成环境多维数据集贴图可能是一项非常繁琐的任务。 RDR2使用优化来降低计算成本。例如,游戏仅绘制静态和不透明的对象,在渲染每个面孔之前执行平截头截尾剔除,并绘制具有较低LOD级别的模型版本。但是,我发现对于环境贴图,浮雕多边形的数量仍然很高。



通过G缓冲区后,将使用抛物面天空图和云纹理生成天空环境的立方体图。下一步是卷积。对于基于图像的照明,RDR2引擎使用分割和近似。此方法使用预过滤的环境映射以及BRDF环境LUT。为了进行过滤,游戏会折叠环境多维数据集并将折叠后的版本存储在多维数据集mip纹理级别中。



在对立方体辐照度贴图执行光传递之前,RDR2将烘焙的大规模环境光遮挡渲染为另一个立方体纹理。该游戏使用屏幕空间环境光遮挡,但SSAO仅在小范围内提供帮助。烘焙的环境光遮挡有助于在更大范围内进行变暗,例如使露台和室内变暗。



环境图


立方环境贴图(烘焙的AO)的边缘:R8_UNORM



游戏使用延迟的图块渲染来计算环境贴图的光照。针对环境贴图的每个面,在一次计算着色器通道中一起计算光剔除和照明。 (感谢@benoitvimont给出的技巧。)此外,对于烘焙照明,游戏使用自上而下的世界光照贴图技术,类似于刺客教条III中使用的技术



对于立方体贴图的每个面,RDR2都会在天空环境纹理上渲染最终颜色。然后,游戏以与天空环境多维数据集相同的方式过滤环境多维数据集。



环境地图最终版


环境立体图的面(最终):R11G11B10_FLOAT



同样,当玩家靠近建筑物时,RDR2加载位于建筑物内部的环境图。也有从磁盘流式传输的多维数据集映射的G缓冲区。



BakedEnvironmentMapAlbedo


多维数据集环境贴图的烘焙面(反照率):(BC3_SRGB烘焙的AO存储在alpha通道中)



BakedEnvironmentMapNormal


多维数据集环境贴图的烘烤面(法线): BC3_UNORM



烘焙环境图深度


环境立方体烘烤的边缘(深度):R16_UNORM



游戏计算这些地图的光照并像以前一样对它们进行过滤。它一次仅计算一张烘焙的环境图,并且仅在一天中的时间更改时重新计算它。所有环境贴图都存储在纹理立方体贴图数组中。没有执行立方图到双抛物面图的转换



G缓冲区通行证



此阶段从初步深度穿越浮雕的深度开始,然后游戏在G缓冲区中渲染场景。



GBuffer 0 RGB GBuffer 0 A
反照率目标
反照率目标A




  • RGBA8_SRGB-此缓冲区在RGB通道(基色)中包含反照率。我不太了解Alpha通道数据的用途,但是在平滑阶段会使用它们。




GBuffer 1 RGB GBuffer 1 A
正常目标
NormalTargetA


  • RGBA8_UNORM:RGB通道包含法线,而alpha通道包含与织物和头发有关的东西。




GBuffer 2 RGB GBuffer 2 A
MaterialTarget
MaterialTargetA


  • RGBA8_UNORM:此目标用于材料属性。

    • R:反射率(f0)
    • G:平滑度
    • B:金属
    • 答:包含阴影(此通道在后续步骤中将用作阴影遮罩)


GBuffer 3 R GBuffer 3 B
Material2TargetR
Material2TargetB


  • RGBA8_UNORM:红色通道包含空腔。蓝色通道中再次有一些神秘数据。在Alpha通道中是与头发有关的数据。我在绿色通道中找不到任何内容。


GBuffer 4 RG
MotionBlurTarget


  • RG16_FLOAT:此缓冲区包含屏幕空间中用于实现运动模糊的速度。


GBuffer 5 Depth GBuffer 5 Stencil
深度目标
StencilTarget


  • D32S8像GTA5一样,RDR2使用反z表示深度,并使用模板缓冲区为一组特定的网格分配值。


根据烘烤的数据生成另一个目标:



GBuffer 6 R GBuffer 6 G
烤AO
神秘目标


该缓冲区在红色通道中包含与环境映射阶段相同的烘焙环境光遮挡。但是,此纹理中还有其他通道。绿色通道包含的数据类似于GBuffer 3蓝色通道中的数据。同样,我不理解该数据的用途。在捕获的帧中,我在蓝色和Alpha通道中找不到任何数据。我将对此进行更详细的研究。



生成阴影贴图



在G缓冲区阶段之后,游戏开始渲染阴影贴图。它对点光源阴影贴图使用2D纹理阵列,对聚光灯光源阴影贴图使用立方纹理阵列。



一些阴影贴图游戏使用较大的阴影图集纹理(例如,在DOOM中)。该方法的优点之一是阴影图的大小可以根据距离而变化很大。使用纹理数组时,由于数组中所有纹理的大小必须相同,因此失去了灵活性。RDR2具有三个用于不同质量级别的不同纹理阵列。例如,探照灯具有:



  • 512x768 D16(用于远距离信号源)
  • 1024x1536 D16 ( — )
  • 2048x3072 D16 ( / )


点源向各个方向投射阴影。为了完成此任务,游戏使用了一种称为“ 全向阴影贴图”的技术,该技术将场景从相机位置渲染为立方体深度图。使用此技术,可以绘制出火的阴影和灯笼亚瑟的阴影。与聚光灯一样,聚光灯具有三个不同的阵列,用于不同的质量设置。



游戏中大多数静态点源都有烘焙的立方阴影贴图。

因此,游戏尽可能使用烘焙的阴影,并且仅在玩家接近光量时才生成阴影贴图。但这实际上更有趣。



大多数壁灯都是聚光灯,但是游戏不会为其生成全向阴影贴图。而是生成一个阴影贴图,并将此阴影贴图的内存复制到点源阴影贴图的立方阵列中。





左侧是大小为1024x1536的探照灯的阴影图,右侧是立方纹理格式512x512的相同图像数据



请注意,线性z存储在局部阴影贴图中。


这解释了为什么开发人员不将方形阴影贴图用于聚光灯。聚光灯阴影贴图和点源立方体贴图中的像素数必须相同。您会看到正确的图像被切成碎片。这是因为聚光灯和点阴影贴图的宽度不同。



另请注意,此纹理不能覆盖360度。但是,幸运的是,建筑物的光源通常在背面有一堵墙,而烘焙的阴影贴图则将其覆盖。



另一个有趣的一点是,该过程以相反的方式运行。例如圣丹尼斯-游戏中最大的城市之一。游戏会为探照灯生成全向阴影贴图,然后将这些数据复制到探照灯的阴影贴图数组中。我不知道为什么RDR2用这种方式进行阴影贴图。我在互联网上找不到任何此类技巧。



在RDR2定向遮蔽,实现在几乎相同的方式在GTA5这是具有四个级联的级联阴影映射来自1024x4096纹理(具有中等图形设置)的每个1024x1024切片均用作级联。



影瀑布


聚焦阴影图集: R16_UNORM



舞台灯光



最后,是时候结合所有这些环境贴图,gbuffer,阴影贴图和ao缓冲区了。



该阶段包括两个阶段:第一个阶段用于全局照明(日/月),第二个阶段用于局部光源。



全球照明通行证



游戏渲染了一个全屏四边形,用于计算定向照明,在我们的框架中为月光。它还使用来自上述“自上而下的世界光照图”的烘焙照明。



LightPass1


局部光线通过



在此过程中,游戏为点光源体积绘制了低多边形的形状,为聚光灯体积绘制了八边形的形状。使用加法混合将灯光从后向前渲染。



为了避免不必要的着色器调用,游戏使用了深度受限测试,是Vulkan / D3D12 固有的可选 OpenGL / D3D11 功能她还使用模板测试来丢弃被诸如窗玻璃之类的半透明物体吸收的像素。这些对象将在直接传递期间渲染。



LightPass2


渲染水和反射



在这篇文章中,我不会谈论渲染水,因为它值得单独发表,但是我会谈谈反射:



  • 如上所述,环境图是反射的主要来源。对于标准反射。例如,对于窗口反射,游戏使用它们。
  • 反射镜具有平面反射,可以从反射方向重新渲染场景。此过程也通过延迟渲染执行。
  • 水反射将屏幕空间反射与帧开始时生成的反射贴图结合使用。


直接遮光阶段



延迟渲染管线的缺点之一是无法使用GBuffers正确渲染半透明材质。为了解决此问题,游戏像大多数使用延迟渲染一样,使用直接着色将半透明材质重新渲染到前端。



但是直接通行证可能很昂贵:



  • , .


, , , . ( ), .


  • .


, . - . - (, ) .


  • , .


必须更改传送带的状态,以便能够在修剪前边缘和后边缘之间切换。这样的改变可能代价高昂。


此时,将为光晕效果生成另一个渲染目标。该目标存储光晕的亮度。如图中所示,半透明物体发出的光更强烈。



BloomMask


目标亮度绽放: R8_UNORM



请注意,长距离开花会更明亮,使雾蒙蒙的地区更明亮。


后期处理



在此阶段,执行临时平滑,光晕,运动模糊,可见深度的影响和其他效果。我计划将一个单独的帖子专门用于后期处理。因此,我们在这里不做特别讨论,但是我想谈一谈有关绽放的问题。多亏了体积照明,基本上渲染目标已经有了光源。



RDR2中的Bloom实施与“使命召唤:高级战争”中的“下一代后期处理”中所述的实施非常相似



  • 没有阈值的目标作为输入,
  • 渲染目标R11G11B10_FLOAT水平为7-mip,
  • 13阶双线性滤波器用于下采样,3x3帐篷滤波器用于放大。


然后,游戏将过滤后的绽放效果目标与主要目标以及绽放亮度目标相结合。



结论



还有很多要说的,但是我不希望这篇文章太长。我想分享我对所有这一切的结论,以及我在分析过程中发现的一些奇怪之处。



  • , — . , . ( , .) bloom: - , , - , . GPU? ?
  • , RDR2 . , (, GBuffers). ? ?
  • : ( ) . SSAO, SSR, . target SSAO ?


别误会我的意思,我没有责怪任何人(尽管...我对低帧频感到有些沮丧),只是想弄清楚如何做出这样的决定。毕竟,很多人都在为这款游戏而努力他们可能没有足够的时间进一步优化游戏。



后记



就这样!RDR2是一款外观精美的游戏,不仅因为使用了图形,而且还因为其艺术和照明效果。一切看起来都很棒。我爱上了这款游戏的调色板。特别是在晚上,它让我想起了罗伯特·福特如何胆怯地杀死了杰西·詹姆斯,老人无国界和其他35毫米西部片。



All Articles