瘟疫的故事:无罪的帧渲染


前言


与我的其他研究一样,让我们​​从介绍开始。 今天,我们来看看法国开发商Asobo Studio的最新游戏。 去年,当我的一位同事与我分享16分钟的游戏预告片时 ,我第一次看到该游戏的视频。 “逆光掠食”的机制引起了我的注意,但我真的不想玩这款游戏。 但是,在发行之后,许多人开始说它看起来像是在虚幻引擎上制作的,但事实并非如此。 我很想知道渲染是如何工作的,以及总体上虚幻技术启发了多少开发人员。 我还对渲染一群老鼠的过程感兴趣,因为在游戏中它看起来非常令人信服,而且它是游戏玩法的关键元素之一。

当我开始尝试捕捉游戏时,我认为我必须放弃,因为没有任何效果。 尽管游戏使用了DX11,现在几乎所有分析工具都支持DX11,但我无法使用其中的任何工具。 当我尝试使用RenderDoc时,游戏在启动时崩溃了,PIX也发生了同样的事情。 我仍然不知道为什么会发生这种情况,但是幸运的是,我能够使用NSight Graphics完成几次捕获。 和往常一样,我将所有参数都调到最大,然后开始寻找适合分析的框架。

帧中断


进行了几次捕获后,我决定使用游戏一开始就进行帧分析。 握把之间没有太大区别,此外,我可以避免损坏。

和往常一样,让我们​​从最后一帧开始:


我注意到的第一件事是,与我之前在其他游戏中看到的相比,此渲染事件游戏中的平衡完全不同。 这里有很多绘制调用,这很正常,但是令人惊讶的是,只有少数几个调用用于后处理。 在其他游戏中,渲染颜色以获得最终结果后,帧经历了许多阶段,但在《瘟疫故事:无罪》中,后处理堆栈非常小,并且仅针对少数渲染/计算事件进行了优化。

游戏通过使用六个渲染目标渲染GBuffer开始构建框架。 有趣的是,所有这些渲染目标都具有32位无符号整数格式(一个除外),而不是RGBA8颜色或特定于此类数据的其他格式。 这很困难,因为我必须使用NSight的“自定义着色器”功能手动解码每个通道。 我花了很多时间弄清楚哪些值是在32位目标中编码的,但是无论如何我还是有可能错过了一些东西。


GBuffer 0

第一个目标包含24位的某些着色值,以及8位的其他毛发值。


GBuffer 1

第二个目标看起来像传统的RGBA8目标,在每个通道中具有不同的材质控制值。 据我了解,红色通道是金属感(尚不清楚为什么有些叶子被标记),绿色通道看起来像是粗糙度值,蓝色通道是主角的遮罩。 我所做的任何捕获都没有使用alpha通道。


GBuffer 2

第三个目标看起来也像是RGBA8,在RGB通道中具有反照率,并且每次捕获时的alpha通道都是完全白色的,因此我不太了解此数据应该做什么。


GBuffer3

第四个目标很好奇,因为在我的所有捕获中,它几乎都是黑色的。 这些值看起来像是部分植被和所有头发/毛皮的遮罩。 也许这与半透明有关。


GBuffer 4

第五个目标可能是某种普通编码,因为我在其他任何地方都没有看到它们,并且着色器似乎对正常贴图进行采样,然后输出到该目标。 考虑到这一点,我还没有弄清楚如何正确地可视化它们。


来自GBuffer 5的深度


来自GBuffer 5的遮罩

后者是一个例外,因为它使用32位浮点格式。 原因是它包含图像的线性深度,并且符号位对其他遮罩进行编码,从而再次遮掩了头发和部分植被。

完成GBuffer创建后,在计算着色器中降低深度图的分辨率,然后渲染阴影图(来自太阳的定向级联阴影图和来自点光源的立方深度图)。


暮光

在完成阴影贴图后,您可以计算光照,但是在此之前,将神射线渲染为单独的目标。


SSAO

在照明计算阶段,执行计算着色器以计算SSAO。


发光的不透明几何

从立体地图和本地光源添加了照明。 结果,所有这些不同的光源与上面渲染的目标结合在一起,形成了照明的HDR图像。


主动渲染元素

以主动渲染方式渲染的元素被添加到照明的不透明几何图形的顶部,但是在该场景中并不是特别明显。

累积所有颜色之后,我们几乎完成了工作,只有一些后期处理操作和UI。


在计算着色器中降低颜色分辨率,然后提高颜色分辨率以创建非常美丽而柔和的光晕效果。


在合成所有先前的结果,添加相机污垢,颜色分级以及最终的色调图像校正之后,我们得到了场景的颜色。 UI覆盖为我们提供了文章开头的图片。

值得一提的是有关渲染的一些有趣的事情:

  • 实例化(重复几何)仅用于单个网格(似乎仅用于植被)。 所有其他对象在单独的绘制调用中呈现。
  • 看起来对象几乎是从前到后排序的,只有少数例外。
  • 似乎开发人员没有做出任何努力来根据材料参数对绘制调用进行分组。

老鼠


正如我在文章开头所说的那样,我之所以要探索这个游戏的原因之一是因为渲染这只老鼠的方法。 这个决定使我有些失望:这似乎是蛮力做出的。 在这里,我使用了游戏另一个场景的屏幕截图,但我希望其中没有剧透。


与其他对象一样,大鼠似乎没有任何重复的几何图形,除非我们达到切换到网格细节(LOD)的最后一级的距离。 让我们看看它是如何工作的。


LOD0


LOD1


LOD2


LOD3

大鼠具有4个LOD级别。 有趣的是,在第三层,尾巴弯曲到身体,而第四根则没有弯曲。 这可能意味着动画仅在前两个级别处于活动状态。 不幸的是,NSight Graphics似乎没有足够的工具来对此进行测试。


大鼠没有重复(实例化)。

与重复。


在上面显示的场景中,渲染了以下数量的大鼠:

  • LOD0-200
  • LOD1-200
  • LOD2-1258
  • LOD3-3500(重复几何图形)

这使我们了解到,前两个LOD上可以渲染的老鼠数量有严格的限制。

在我所做的捕获中,我无法确定将老鼠与单个LOD关联的任何逻辑。 有时靠近相机的老鼠不是很细致,有时几乎看不见的老鼠却有很高的细节。

总结


瘟疫传说:纯真在渲染方面非常有趣。 他的成绩无疑给我留下了深刻的印象,它们为游戏提供了很好的服务。 与任何专有引擎一样,很高兴能听到开发人员自己的详尽分析,尤其是因为我无法证实我的某些理论。 我希望有一天我的文章可以从Asobo Studio那里找到,并且他们看到人们对此感兴趣。

Source: https://habr.com/ru/post/zh-CN456614/


All Articles