Origin
zhuanlan.zhihu.com
Tags
简悦
项目
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述
Speaker(s): Paolo Surricchio
Company Name(s): Santa Monica Studio
译者的话:
由于工作原因看了此篇宣讲。但说实话,此篇宣讲与其说是介绍技术,不如说是技术闲聊。奔着技术来的小伙伴们,可以 “省流” 了。。。按照本文的标题,其实并没有介绍太多如何 “造轮子” 的技术,反而花了大量的篇幅在解释为何要“造轮子”。
00 目标
本文的目标是展示我们在 SMS(Santa Monica Studio)如何编写技术,以支持高质量的定制设置,同时为未来创建一个可重复使用的工具集,以及如何应用这种方法。我们将通过研究《战神:诸神黄昏》中雪地或更广义的高度场系统重写过程来实现这一目标。高度场系统负责实时移动像雪这样的表面,当角色或物体穿过它时,会留下痕迹。
本文更多的是关于我们做出决定背后的原因,而不是系统复杂细节的介绍。在过程中,我也会强调一些关键的要点,然后在演讲结束时进行总结。
关于我们在 SMS 的工作方式,这里有一些背景信息。我们有一个世界级的艺术家和设计师团队,他们对游戏的所有细节有很多的手动控制权。使用 Maya 作为关卡编辑器,关卡是由关卡设计和艺术团队制作的。然后直接在开发套件上运行游戏,这是查看游戏渲染的唯一方式。我们使用许多工具,如 Houdini,来自动化工作流程,但总是在管道的最后阶段提供手动调整的选项。这对于工程方面提出了挑战,因为我们必须平衡过于特定或过于通用的解决方案,我们将看到高度场系统就是一个例子。虽然这些细节适用于我们特定的限制,这可能对于你的引擎或游戏来说是不同的,但选择背后的原因的教训是对所有人都适用的。
01 回顾
让我们从《战神:诸神黄昏》的制作初期开始说起。2018 年 4 月,《战神》已经发货,我们正在开发续集。从一开始就知道我们将在 PS4 和 PS5 上同时发售,而且这款游戏在两款游戏机上都必须有很好的体验。在本文中,当我提到性能或内存数字时,我特指 PS4 的数据,因为这个系统必须在较旧的游戏机上运行良好,并且应该在更快的游戏机上有所提升。从上一款游戏的结尾,我们知道一个名为 “冰霜巨人之冬” 的事件正在影响中土世界,它使得大部分的世界被雪的覆盖。由于这是我们在游戏中花费大部分时间的地方,我们知道将不得不处理大量的雪。起初,这可能不会引起我们的担忧。在上一个项目《战神 2018》中,已经实现了动态雪效果,并且看起来效果很好,应该可以直接使用。只需要在新游戏中 “勾选复选框” 就可以了。
你可以在这里看到它的效果。看起来很棒,所以我们已经完成了!是这样吗?不幸的是,事情并没有那么简单。要理解为什么,我们需要理解这项技术是如何运作的。
雪的网格是通过一种称为屏幕空间视差映射的技术来渲染的,这是我们当时的技术总监 Florian Strauss 发明的常规视差映射的一个变种。如果你熟悉视差映射,原理是相同的,但是你不是在切线 / 纹理空间中进行 raymarch,而是在屏幕上进行 raymarch。这允许各种快捷方式和优化,但也不是没有缺点。我们使用网格和特效来渲染位移信息,这就是雕刻位移的内容。让我们接下来看看:
我们使用一个随着每帧相机移动而滚动的持续性自上而下的渲染目标,在其中渲染在雪中刻画深度的网格和特效。我们可以渲染任意形状的网格,通常对于角色来说,会选择胶囊形状和球形,同时会使用一个自定义的着色器,这个着色器编码的信息是专门为了适应视差算法的工作方式。正如我所说,视差映射是在屏幕空间中进行的,因此需要一个网格来在屏幕上投影自上而下的信息。为了实现这一点,会在与常规不透明网格相同的位置渲染一个网格。
从相机的视角渲染网格,并采样我之前向你展示的自上而下投影的纹理。这将所有的信息带到了屏幕上。然后从相机的视角通过网格和粒子渲染额外的细节。
这是设置雪景所需的主要网格的横截面。
艺术家创建了主要的渲染表面,图中的浅蓝色部分。这就是用雪材质渲染并用屏幕空间视差进行位移的网格。注意,为了能够与视差映射良好地配合,这个网格必须是平的。正如我之前提到的,接下来需要一个匹配的网格来将自上而下的信息投影到屏幕上,在图中它是黄色的部分,即投影表面。在此之后,需要在其下雕刻出最大和最小的网格,这些网格实际上描述了未受扰动的雪面。这通常是通过高度纹理来完成的,这就是为什么在 Maya 中你看不到任何类似地形的波浪状表面。如果这里包含了太多的细节,我表示抱歉,你并不需要理解其中的所有内容,因为我要讲的重点是为什么我们决定重写这个系统。让我们来看看这种技术的优点和缺点。
视差映射使我们能够以每像素的精度渲染位移。另一个优点是视差映射的成本与表面的细节和使用成正比。如果你的表面全部是 “凸起的” 或“未位移的”,你可以提前退出,这样着色器就不会那么昂贵。但是,像所有技术一样,它也有缺点,我们将看到这些缺点如何阻碍了这项技术的扩展。
成本的变动性是一把双刃剑。当地形完全位移时,渲染更加昂贵,因为必须通过更多的像素进行 raymarch。这正是在战斗场景中发生的情况,我们在这些场景中最大限度地压榨了性能预算。暂时忘记性能问题,创作也是一个问题。我其实简化了 Maya 的设置,也没有包括材料和纹理的设置。我跳过了许多小细节,但所有这些移动的部分使得系统非常容易出错。最后,视差映射有不可避免的渲染错误,这些错误是该技术工作方式所固有的,而我们的版本,虽然更快,但却使这些错误变得更糟。
当视图向量与视差平面平行时,视差映射会显示出渲染错误。在屏幕空间中,这个问题更加严重,因为屏幕空间的纹理现在将所有的高度信息压缩到仅仅几个像素中。我们的屏幕空间版本在此基础上增加了其他问题:由于在顶部表面渲染细节,它们会随着最终的位移结果产生闪烁。解决这个问题的唯一方法是使用投影贴花,但为了达到这种效果,需要产生数百,甚至数千的粒子,而我们无法承受与贴花类似的任何东西。
这在使用的空间上产生了很多设计限制。为了解决这些渲染错误,我们不得不采取许多预防措施,这意味着大量的环境艺术工作并没有用在创作艺术上。并且不仅仅是环境艺术,这涉及到设计师、游戏程序员进行摄像机碰撞、电影动画师等,几乎整个团队都必须知道这一点。这是许多跨部门依赖的来源,这减慢了这种技术的使用。
这就是为什么《战神》2018 只在整个游戏的少数几个区域使用了这项技术。所有这些区域都需要特别的照顾才能使这项技术发挥作用。
我想确保我在这里并没有妖魔化这项技术。屏幕空间视差映射是一种令人难以置信的技术,但我们过度推动了它,迫使它做出超出其适用范围的更多事情。实际上,在《战神》2018 和《诸神黄昏》中,仍然在其他地方使用这项技术,并取得了很好的效果。我们的水体位移渲染技术在两款游戏中都使用了相同的屏幕空间视差技术(尽管对于《诸神黄昏》来说,渲染效果有了很大的提升)。水是一个很好的使用案例,因为由于其特性,它在游戏中已经是一个特例:它是一个平面,无论如何,艺术和游戏玩法都必须围绕它进行工作。它并不适合用于那些需要与其他网格有机交叉、并需要描绘出曲线表面的大型地形。当时,这是最好的解决方案,如果我能回到过去,考虑到当时的限制,我可能还会做出同样的选择。
现在我们希望能明确一点,为了让这项技术在地形上运行,需要过多的控制。所有这些都是因为视差映射的特殊需求,以及如何围绕提供正确的数据并解决其局限性进行工作。
02 变革
这让我们回到了《战神:诸神黄昏》制作的开始阶段。我们与艺术高级人员和主管进行了一次会议,他们告诉我们,无法使用或扩展当前的系统来满足这款新游戏的需求。这是一个由资深艺术家组成的专业团队,在这个房间里讨论的是,每个人的游戏开发经验都可以以十年计,总计超过一百年。如果情况并非如此,他们是不会这么说的。
主要原因归结为开发工作的规模。从预制阶段就明显看出,新作的所有方面都比以前大:新作的世界规模是上一款游戏的两倍多,开发团队也将比上一款游戏的团队更大,我们有更多的合作伙伴和外包工作室提供帮助。
正如我之前所说,雪是无处不在的。实际上,我们最终在数量级上比以前有更多的雪层位移。而且,未来在更多的地方使用了新的系统,而不仅仅是雪。
显然,导致扩展问题的主要因素是需要多大程度的手动控制才能使其正常运行,以及视差渲染的限制。我们需要改进工作流程,我们也明白,采用几何方法不会遇到以前的那些问题。解决了这些问题后,就可以开始构建新系统了。
在我们的引擎中,并没有一个事实上的地形系统。地形是由艺术家创建的定制网格进行制作的,所以技术必须适用于任意的网格。除此之外,希望确保系统能自动与材质编辑器的所有渲染特性进行集成,并且设置起来必须简单。在性能方面,希望最好和最差情况之间的差异更小。如果没有使用这种技术,我们不希望为内存付出任何代价,因为游戏的大部分并不使用它。最后,它必须在旧的游戏机上运行良好并看起来不错,并且在新的游戏机上以极小或无需额外工作的质量进行扩展。不过,这里是有妥协的。
旧的方案提供了每像素质量的视差效果。我们知道,要通过几何形状达到这一点,尤其是在 PS4 上,是非常困难的。但这对艺术团队来说并不是一个问题。请允许我直接跳到结论,我们成功地发布了一个满足所有需求的系统。但更重要的是,本文的核心信息是,在实现这个目标的同时,始终保持开放的态度,以便在开发过程中和开发之后,能够做更多的事情,而不会影响已经达成目标。下面,我们来看看是如何做到这一点的。
03 第一步
首先,我们需要从艺术团队那里获取一个规格说明,明确视觉目标是什么,以及希望拥有哪些特性。我们的高级环境艺术家之一,Kyle Bromley,被指定为环境艺术负责人,与我一起研究雪景技术。我向他提出,如果能预见到最终结果的样子,那就太好了。Kyle 告诉我:“给我一两天时间,我会写下一些笔记的。”
这就是他回来的内容。我想花一点时间来强调我们艺术团队的高水平技艺。
实际上,它看起来更漂亮,我不得不剪切并移除部分内容。现在,我们有了一个视觉标准,其中包含了应该达到的指导方针和想法。从文档中,也可以看到三个独立的子系统正在形成:从左到右,首先,有基于玩家行走路径的位移,然后希望改变位移内部的外观,最后,我们希望在位移区域周围有细节。
我们主要的问题是,在三角形数量或微小三角形重绘成为问题之前,我们能推动多少三角形。我在 Maya 中取了一个网格,将其细分了几次,直到我能合理地表示出细节。这些目标的指导下进行了一些更多的测试,最后知道可以自信地依赖几何位移来完成我们需要的工作。关于这个问题,接下来有更多的细节,但更重要的是第一个令人兴奋的收获。
始终从产品开始,然后逆向工作。做一个成本估算,以确保你的解决方案在你所知道的范围内是可行的。如果你的知识不足,那就尽一切可能去提升它。经过我们的渲染和硬件测试后,实际上需要让它在游戏中真实地、动态地工作。在尝试任何新的事情之前,先研究了其他游戏是如何解决这个问题的。至今为止,几何位移并不是一个新的话题。
遗憾的是,我们的一些需求非常严格:我们分析的大部分技术都无法满足需求。有些技术存在像 T 型连接这样的问题,他们可以忽略,或者从具有有限特性集的预处理网格开始。这是一个值得单独进行的话题,但经过更多的研究,我们意识到现有的技术对我们来说并不适用。我建议你们去研究一下这些技术,因为他们的限制可能对你们的游戏或你们的引擎来说并不是问题。我在最后留下了参考文献。
04 开始干!
我们自己也做了一些研究:考虑到当时的渲染工程师数量和生产进度,必须严格控制这项工作的时间。我们尝试了一些方法,我只提一下目标:尽可能只在需要的地方进行细分,但理想情况下,尽可能减少细分因子。
大约在同一时间,另一位渲染程序员 Valerio Guagliumi 正在为我们的通用着色器管线添加硬件细分功能。这是为了引领一项努力,只为 PS5 提供更好的网格细节。硬件细分满足了我们的所有需求:不需要额外的内存,可以进行调优,并且可以动态地进行缩放。我们知道它的性能问题,但有足够的信心以某种方式来解决这个问题。实际的情况比这个复杂一些。但让我们来看看第二个,也是最重要的,要点:构建事物的方式是以块为单位,没有任何一个块是核心支柱。如果没有这条要点,一切都会崩溃。我们的设计方式是,没有任何东西特别依赖于三角形将如何被细分,只需要它们被细分就行。之前技术的问题在于,必须围绕视差算法的特定要求进行大量设计。
让我们看看新系统是如何通过各个迭代进化的。我将向你展示系统在每个步骤中的输出结果是什么样的。与以前不同,艺术家只需像平常一样制作网格。我们唯一的限制是网格拓扑必须遵守一些密度规则。这个问题后来得到了解决。对于需要置换的网格,只需在材料中勾选一个复选框,构建管道会为你处理其他所有事情。在运行时,保留了与以前相同的切割逻辑,但是由于视差的所有要求都消失了,所以变得更加简化。
我们在相机周围渲染一个与之前相同大小的区域,这是从原始没有置换网格的顶视图看到的。
然后我们在渲染目标中渲染雕刻形状。我们将它们与未置换的网格深度进行比较,这样与雪不相交的形状就不会雕刻任何东西。
虽然深度纹理每帧都会重新绘制,但雕刻图是持久的,就像之前一样,我们每帧都会根据相机的移动滚动它,保持投影的中心在相机所在的位置。
04.1 细分
在计算着色器中,我们将所有信息合成到一些用于置换的纹理中,并且我们还平滑了高度以避免尖锐的置换。
考虑到正在分析每个像素的 相邻像素,我们计算每个像素周围区域的细节差异,并推导出一个细分因子,将其写入一个纹理。
在渲染网格时,我们使用硬件细分来细分三角形,细分的程度取决于细分纹理的建议,然后再置换网格。这是在测试场景中对第一次迭代的一瞥。
这个方法的酷炫之处在于,已经可以渲染出一个使用之前技术无法实现的表面。现在,你只得到一个被置换的表面,看起来并不起眼。让我们看看如何改善其外观的。
04.2 着色
我们构建了一套工具,将系统特定的高度信息转化为材质编辑器的语言。高度被转化为透明度,这意味着可以根据置换情况混合不同的层。这意味着立即就可以使用我们的材质系统的整个混合功能集,而无需做任何事情,这就是艺术家工作流程的基础。
这就是这次迭代的样子。
你可以看到,当雪被置换时,显示出了一层泥土。这可以是艺术家想要的任何层,或者任何数量的层。
在此之后,艺术家开始要求添加像顶点颜色遮罩这样的功能来控制置换。一开始,你可能会认为正在走和之前系统相同的道路,但是有一个主要的、根本的区别:这并不是技术发布所必需的。这只是为了有更多的控制权。
我发现,如果一个工具能给用户提供更多的选择,那么它就是增值的。如果一个工具是控制功能的唯一方式,那么它就是减值的。
04.3 细节
下一步是获取一些我们在远离视差时失去的高分辨率细节:我们在玩家脚步周围生成另一个自上而下的持久滚动低分辨率遮罩,该遮罩用于在雪地网格上混合一个详细的法线贴图,以在被置换的区域周围添加细节。
除此之外,我们还生成了一个自上而下的高度遮罩,从中每帧都派生出一个动态法线贴图,以模拟表面上更细致的雪的细节。默认在所有的材质上都使用了这个方法,虽然这个方法目前已经在最终的游戏中运行并发布,但并没有像本可以做的那样推动这第二部分,因为当时的视觉特效团队在时间表上没有空余。不过,这并不是一个必要的要求。
最后,我们解决了网格拓扑的限制。现在你可以向这个功能投入任何合理的网格,它都会正确地运行。正如我们设计的,只在置换周围进行细分,而且只做需要的那么少。
你还可以看到一个很好的例子,即在置换网格周围混合的详细法线贴图。
这是一个放大的截图,用来展示如何只在置换周围进行细分。我关闭了所有其他的功能,以便更清楚地看到。
到目前为止,它看起来是这样的。
这是在基础版 PS4 上使用硬件细分的大型地形网格的捕获。你可以看到我突出显示的所有波浪:这些都是 HULL 和 DOMAIN 着色器的调用。如你在底部可以看到,占用率几乎降到 0。那是因为在等待细分器完成其工作并返回。我突出显示了 HULL 着色器的简单性。这并不关键。我们受到的限制是细分器返回的速度。我们没有太多时间去深入研究细节,但总的来说,硬件细分有一个高入门固定成本。如果你拿一个网格,打开细分,通过一个直通 HULL 着色器,没有任何细分,它的速度将比常规的绘制调用慢大约 30% 到 40%,其他所有事情都相等。再次强调,这只是一个粗略的估计,只是为了给出一个高层次的想法。这个成本在旧一代的硬件上比新一代的硬件更高,所以请记住这一点。细分的经验法则是,如果你使用它,真的要使用它,并细分那些三角形。大的、细分得更多的三角形比小的、细分得较少的三角形更好。
04.4 准备
如果你知道这种打嗝(hiccup,这里指的是突发的小问题)会发生,那么它与你毫无预警的突然发生问题之间有着巨大的区别。尽管总成本确实让我们有些惊讶,但自从开始使用细分以来,我们就意识到了这一点,所以从第一天开始就在想一些解决方案来应对它。
我们知道需要在尽可能少的三角形上运行硬件细分。不幸的是,地形是这种情况的最糟糕的情况:你有大的、形状奇特的网格,这些网格很难剔除,而且即使只有有限的区域真正需要细分,也很容易同时有相当多的活跃网格。艺术团队提出在他们的 LOD 过程中手动分割网格以帮助解决这个问题,但我们知道可以为他们自动化这个过程。
受到 GPU 驱动的渲染技术的启发,我们考虑自动将网格分割成更小的部分,并尽可能少地使用细分进行渲染。这产生了巨大的差异,并且是我们在 PS4 上发布这整个系统的主要部分。所有这些都是因为在项目开始时所做的 RnD(研发)成为可能。这是我们为特定情况构建的技术的另一个例子,但是这些经验教训将对未来产生持续的回报。
我们将索引缓冲区按照几何关联性划分为多个三角形区段。对于这种特定的技术,尽量让每个区段的三角形数量保持一致,或者至少让它们的数量尽可能接近。我们会为每个网格的 meshlet 保存最大的索引计数。在进行这些操作的同时,会生成一个包含每个 meshlet 的索引偏移量、索引计数以及你所需要的任何剔除信息的缓冲区。
对于剔除需求,使用球体已经足够满足。
对于我们的每个网格,都有一个计算着色器调度,在这个过程中,会逐个检查每个 meshlet,判断它是否在视锥体之外,应该被剔除。如果没有被剔除,那么第二步就是判断它是否足够远离位移区域,应该被视为一个非细分的 meshlet。
我们将它们的索引排入两个缓冲区,一个用于细分的 meshlet,一个用于常规的 meshlet。
最后,我们不是用一个绘制调用来渲染网格,而是用两个间接绘制,一个使用硬件细分,一个使用常规顶点管线。执行剔除的计算着色器会填充两个间接绘制参数的 vertexCountPerInstance,所有 meshlet 的最坏情况索引计数乘以每种类型通过测试的 patches 数量。
如果我们用常规着色器渲染网格,得到的索引将不会匹配网格的索引。
顶点着色器是所有内容汇聚的地方。这是简化的伪代码。
在顶点着色器中,使用从硬件获取的索引来获取我们的 meshlet 信息,这使我们能够知道这个顶点所属的 meshlet 中实际上有多少索引。通过将它们折叠到 0 来剪裁不属于我们 meshlet 的额外顶点。这就是如何实现使用不同索引计数渲染 meshlet 的方法,也是为什么尽可能将网格划分为索引计数接近的 meshlet 非常重要。这里有一个附注:对于这种技术,依赖于不使用自动顶点获取。在游戏主机上,我们不这样做,因为在 GCN 硬件上是一样的。我们最终得到了想要的结果:尽可能少的三角形被细分。
艺术团队对此非常满意。我们带回了一项优化,它在某些场景中可以节省 0.5 毫秒到 2 毫秒的时间。这对团队来说是个好消息。它节省了大量的优化工作,现在这些工作可以用来提高游戏的质量。
但是,还有更多!
在《诸神黄昏》的制作过程中,Stephen McAuley 加入了 Santa Monica 工作室,成为渲染团队的负责人,随着更多的人加入,我们有了更多的喘息空间。这给了实验和改进系统的空间。虽然我们对结果感到满意,但我们知道可以进一步推动它。看着 Kyle 最初的提案,我们决定向系统添加更多的细节。由于 Composite Pass 已经可以工作,可以非常便宜地生成更多的纹理和信息。最终在系统中添加了两个更多的部分。
我们的粒子系统完全在 GPU 上运行模拟粒子。支持深度碰撞等多种功能。不幸的是,不透明粒子和迷你模型不支持深度碰撞,这些迷你模型是为每个粒子渲染的不透明模型,而不是精灵。这是因为不透明粒子和迷你模型都会写入深度,这意味着如果你开启深度碰撞,它们会与自身和其他模型发生碰撞。现在,我们已经从顶部获得了表面的表示,有了进行精确碰撞所需的所有信息。我们在粒子系统中添加了高度场碰撞,在游戏中,你可以看到当你走动时,雪花被扔出并与地形真实地碰撞。这也非常便宜,这在你在生产结束时添加功能非常友好。现在可以创建数百个小模型,并让它们无任何问题地碰撞。这比深度碰撞更好,因为不受屏幕的限制,而是可以在有雪的地方,从相机到 25 米半径的任何地方进行。
我们新增了一个特性,即在相机周围的位移处实时生成永久模型。这与你的常规植被系统在地形上生成网格并读取遮罩的方式并无太大区别,但读取的是由高度场合成通道生成的位移信息,而非绘制的遮罩。可以调整参数并在实时中看到它们的效果。
这种功能可以针对每个区域进行调整,艺术家们开始初步体验到实时程序性模型的强大以及它如何能够根据我们在工作流程中的信息做出适应性调整。这不仅看起来效果很好,而且也展示了如果我们投资这种类型的技术,将来能实现更多的可能性。艺术家们非常清楚程序性模型的能力,在关卡编辑器中已经广泛地应用了它。但是,看到它在实时运行,几乎不需要任何创作成本,在动态变化的网格上,运行成本几乎可以忽略不计,这是一种全新的体验。
这两个特性都是在后期才上线的,但由于系统及其组件的灵活性,我们在生产进度和性能预算方面都能够将它们压缩在内。我们需要的信息很容易获取,而且成本非常低。如果将 composite pass 硬编码得过于具体或者不够灵活,可能需要在生产后期进行更改,或者在没有预算的情况下加入它。
在这过程中,我们学到了:对于未来的一些系统进行研发,与将其全部用于最终产品的生产,这两者之间存在很大的差别。
我们并不仅仅在雪地上使用这项技术:我们也在 Alfheim 的沙地上应用了同样的技术。
值得注意的是,这些沙地是由合作工作室 Bluepoint Games 的艺术家们创造的。他们能够以非常少的投入,通过不同的方式使用这项技术,实现不同的视觉效果。
让我们最后再来看一次系统所有部分的分解:这是从 Kratos 的房子后面看到的一个场景。
这仅仅是没有开启任何特性的基础网格。
我们添加了四处走动的位移效果。
然后我们根据高度位移混合不同的材质层。
我们展示了由玩家四处走动所创建的详细法线图。
然后我们渲染粒子,包括不透明和透明的粒子。
最后,我们添加了程序化放置的模型。
到目前为止,我向你们展示的所有素材都是在 PS4 上捕获的。最后,我想展示这个系统在 PS5 上的扩展情况。我关闭了动态模型和额外的细节,只展示了我们通过优质纹理和细分实现的效果。
你在这里看到的只是带有细分和位移的基础网格。
05 参考资料
> 本文由简悦 SimpRead 转码