如何通过单一参数驱动《极限竞速:地平线5》的粒子效果

作者:Aud42nce
2024-06-02
3 0 0

编者按

本文来自 GDC 官方 Youtube 频道,原内容形式为视频演讲,indienova 对其进行了编译整理,以图文形式分享。原链接见文末。

  • 演讲人:斯隆塔姆·明茨克(Slontime minitzke)
  • 译者:Aud42nce

正文

我是 Playground Games 首席特效艺术家斯隆塔姆·明茨克,今天,我将向大家介绍参数如何影响《极限竞速:地平线 5》(Forza Horizon 5)中的粒子效果,这是一款背景设定在墨西哥的开放世界拟真驾驶游戏。

本次演讲将介绍我们如何发现通过构建图形系统并充分利用参数,可以生成更令人满意的游戏效果并高效创建各种对象。我将首先介绍在新项目中遇到的挑战,以及为什么决定使用新的粒子编辑器来克服它们;随后讨论如何重新设计游戏的核心视觉效果(VFX),并展示如何将汽车物理学作为设计核心,以实现更令人信服和满意的视觉效果;之后将深入分析一些案例,比如如何利用轮胎温度来控制轮胎烟雾效果,同时展示数个扬尘母效果,并解释控制它们的外部参数;接着解析两个被应用于数百种可破坏植物的效果;最后将提供一些有助于在多平台优化游戏的高效批量化处理建议。

新项目与新编辑器

首先,让我介绍一下开发团队对新项目的预期、面临的挑战,以及为什么我们决定换用新的特效编辑器。

我们计划将新项目的开发周期延长 50%,以便有更多时间提高特效质量;我们的目标是创造迄今为止最大和最多样化的游戏世界,复刻现实世界里墨西哥的多样性极强的生态系统,项目内容因之增加;VFX 方面的主要技术改进则是推出了能达成这些目标的新粒子编辑器。

为了更好地解释为什么想使用新编辑器,需要回顾一下旧编辑器面临的挑战。

在《极限竞速:地平线 4》的制作过程中,我们感到旧编辑器已经达到了极限,解决它产生的问题需要花费与创作内容同样多的时间。因为旧编辑器是一个被高度扩展,但数年来未经过改进的半成品,我们高度依赖编辑器开发团队来修复和添加新功能。但它仍然是一个基于栈的笨重编辑器,无论有多少技术支持,都无法改变这一本质。

在 2018 年和 2019 年初,我们花了很多时间研究各种 GDC 文档以及 Unreal Engine 和 Unity 等引擎,以弄清需要什么样的工具。

如今,一切编辑器都倾向基于节点进行开发,行业整体趋势是通过节点图编辑器为开发者提供更高的自由度。我们决定沿用这种思路,因为它能够以适配(我们期望的)新效果的方式处理原有的游戏逻辑和数据的关系。这种情况下,可以选择在内部创建一个编辑器,或者继续使用第三方软件。此时 PopcornFX version 2 显然是最好的选择,但这意味着我们要从零开始构建每一个 VFX,旧项目的成果将不再适用。不仅如此,我们也需要新的团队保障编辑器的运作。

基于游戏玩法设计视觉特效

第一步是设计与玩法相关的特效,这也是新编辑器效果评估流程的一部分。这里要试图解决的问题是什么呢?

《极限竞速:地平线 4》在汽车行为的视觉反馈方面存在一些局限性,导致我们很多时候不了解汽车行为。比如,粒子系统对哪些车轮实际在驱动汽车一无所知,因此必须关掉大多数 VFX 才能看到真实的车轮行为。任何不符合真实情况的场景都需要修改或寻找变通方法,但在某些情况下,我们依然无法实现汽车行驶时的真实车轮行为,同时有一些恼人问题一直存在,比如汽车从静止状态突然加速时产生的初始扬尘效果。为此需要采用变通方法,但这些方法可能会导致异常行为,以及其它不希望出现的情况。比如上图中,当前轮停止滚动时,可以清楚地看到不合适的扬尘,不幸的是,这个问题无法修复。

上图左侧描述了旧特效的工作原理,只能使用基本图形来确定发射点,从这些点发射出向后和向上飞的粒子,以达到尘土和碎屑扬起的效果。但现在,我们有能力自己创建发射器行为。首先是定义一个与轮胎匹配的圆柱体,随后需要找到接触点,并考虑该点周围的轮胎表面,然后根据车轮的旋转速度设置喷射粒子的初始速度。

下图是在 PopcornFX 评估阶段创建的车轮底部溅射的概念验证模型,还非常初步。右侧脚本示意图中定义圆柱体的方式几乎与上图中展示的相同。此外还有一些来自环境的输入信息来控制基础扬尘弧度和速度,然后将其输入默认物理节点,以添加重力和现实效果渲染。

基础效果目前已相当令人满意,你可以想象出这是一个在非常松散的路面上旋转的汽车轮胎。接着来看看定义圆柱体的具体脚本。

上图是这一核心效果的基础脚本。理论上,这部分内容也可以通过节点图表示,但直接展示代码更为直观。

前两行是从预设的弧度范围中选择一个随机角度,作为发射物的弧度,然后以相同方式选择半径;为了增加一些随机性,第三行对应的控制参数可自定义上述参数的随机散布;第四至六行对应的参数用于选择圆柱体上的一个位置,将其作为原点,然后根据轮胎上该点与接触点的关系来计算初始速度。

至此,工作仍然只是在 PopcornFX 编辑器中进行。因此,我们录制了一些物理层的《极限竞速:地平线 4》游戏内容,以尝试提取数据并用于验证此前构建的效果,假装这个效果在监听游戏。

如上图所示,汽车在碎石路上启动,松散的路面会导致牵引力不断变化。我们记录了黄色方框中的数值随时间发生的改变,可以看出,影响视觉效果的关键是与每分钟转数(RPM)和滑动相关的参数。

了解到这些情况后,我们改良了之前用于测试的效果设计,那些原本固定的输入值被修改为动态属性,这样一来,就可以通过右上角的效果控制台调节所有输入了。这个控制台允许实时调整影响效果的各个参数,但理论上更应该监听外部数据,而不是手动调节它们。

由于无法直接获得物理数据,我们创建了一些曲线,将前面提到的情况映射到这些曲线上,并随时间采样以驱动效果。上图是两者的实时对应:将物理数据输入进轮胎上的扬尘效果器,以验证方法的有效性。

在 PopcornFX 编辑器中验证过这一设计的有效性后,是时候将这些内容放到游戏中了。在这里,我们决定重新审视一下为游戏核心系统设计特效的方式,因为以前一直依赖已有的解决方案和数据,而没有思考想通过特效展示什么。

关键参数:滑移比

为了解决这个问题,我们首先与工作室的车辆操控和动力学团队沟通,因为他们了解汽车行为,以及我们希望通过游戏内效果展示的一切。

原来,与轮胎扬尘相关的关键概念是滑移比(Slip Ratio),它体现了轮胎旋转与线性移动的差异。当滑移比为 0 时,轮胎旋转一周,汽车应该前进轮胎周长的距离;而在滑移比为 1 时,汽车不会有任何移动。得益于游戏内置的物理层,我们对滑移的概念有了大致了解,但并不充分。事实上,这是影响先前提到的烟雾效果的主要因素。

归根结底,轮胎旋转消耗的能量,如果不用于推动车辆前进,就必须用于其他方面,比如剥离轮胎表面的物质,或者当轮胎和路面出现摩擦时产生热能。滑移比是一个关键参数,它为我们提供了所有这些事件的信息。

第一步:调试视觉效果

有了这些信息,我们首先从调试视觉效果开始,以测试游戏内的参数是否如预期传入了前面设计的效果器。利用轮胎的特性,我们将调试用粒子放置在轮胎表面,为此需要从游戏中读取轮胎位置、半径和宽度。随后根据 RPM 来旋转它们,使其与轮胎旋转保持一致,最后根据滑移值改变粒子颜色。

通过这些可视化调试,我们确认参数传递是正常的,那么是时候着手处理扬尘内容的设计了。

上图展示了一些早期的生成层逻辑。我们能够将扬尘曲线映射到物理输入,并使用基础的粒子发射器(Debri Emitter)控制面板调整这个效果的行为。当滑移比增加时,粒子开始从接触点处发射,随着速度提升,形成一个不断增长的弧,速度最大值由 RPM 确定。

上图描述了整个发射器的核心行为,说明了这些输入如何在编辑器中获得实时反馈。我们的 模板可以创建新变量,以便在运行时随时调整。接下来,让我们详细了解扬尘发射器模块的具体构造。

这是基于前面 PopcornFX 评估阶段所展示的结构而设计的图表。紫色的输入是从游戏中读取 的,但也可以在测试时通过编辑器中的控制面板手动调整。监听数据包括轮胎位置、轮胎半径、轮胎宽度、RPM 和滑移比,它们用于指导效果的具体行为。深蓝部分是通过控制面板进行调整的内部参数。

上面所有这些汇集在一起,便能创建一个全面的系统,可兼顾所有作用在轮胎上的力的效果,同时允许我们结合游戏中的其它因素,调试整个粒子系统。如果我们知道轮胎的行驶速度、旋转速率以及滑移的量,就可以将这些数据全部用于生成粒子的初始行为中。我们只需要对该效果进行一次定义,然后使用汽车物理学的数据驱动它,就能实现不同条件下的不同效果。

第一个用例——烧胎!

现在已经实现了轮胎扬尘效果器的核心行为,接下来,让我们将其用于轮胎烟雾效果,这也是游戏中最常见的效果之一。

首先回顾一下轮胎烟雾效果曾经存在的问题。我们之前讨论过烟雾量值,它能够告诉粒子系统车轮是否打滑或发热,作用和黑匣子有点像。这导致生成的效果不够细腻,烟雾从最小直接到最大,几乎没有中间过程,大多数情况下呈现出二元的开关(On-Off)行为。同时很显然,这一效果也缺乏浓烈的滚滚烟雾。为了说明如何改进这一点,让我们将《极限竞速:地平线 4》中的效果与理想效果进行比较。

显然,在漂移和烧胎的时候,图片上半部分的轮胎烟雾看起来不够引人注目。在这些场景中,玩家通常会期待出现滚滚浓烟,但生成的烟雾却相当薄弱。寻找一个更合适的触发器来驱动效果是不错的解决办法。

于是我们又一次向车辆动力学团队寻求帮助,告诉他们希望实现的理想效果,即轮胎烟雾 一开始比较薄,随着轮胎越来越热,烟雾变得越来越浓。他们简单说明了引起轮胎烟雾的原因,并提供了一些很好的参考资料。

如上图所示,一开始,轮胎温度约为 19 摄氏度,处于冷状态。

随后,大量滑动会使轮胎迅速升温,超过 100 摄氏度的阈值,在地面留下一些橡胶碎屑,产生薄而短暂的烟雾。通常在这个阶段,轮胎表面的污垢和其他污染物会先冒烟,然后才是轮胎胶料本身。可以看到,此时轮胎表面的内侧左边开始形成一个热点。

可惜上图没有捕捉到温度达到 100 摄氏度的瞬间,几秒钟后,热量已经传播到整个轮胎表面。此时,烟雾不仅变得更浓更持续,而且在相近的 RPM 下持续了 15 秒后,轮胎开始明显破裂,同时持续生成大量烟雾,并甩出大量橡胶颗粒。

事实证明,我们的汽车物理模拟器已经记录了所有必要数据。不仅如此,上述过程还观测了轮胎胶料如何对热作出反应,起烟点是多少,以及何时达到所谓的破损阈值。为此,我们新创建了一个叫做“烟雾输入”(SmokeInput)的控制参数来触发这个效果。轮胎温度将根据上述阈值映射至 0 到 1 之间,分别控制每个效果。一旦轮胎温度达到起烟点,该参数的数值将超过 0,VFX 系统开始产生烟雾,当该值增加至 1 时,烟雾量会达到最大。这个新的基于温度的效果控制可以达成的效果范围比之前更广,允许烟雾逐渐增强,改善了以前烟雾效果的二元情况。现在只需将其和新轮胎扬尘效果器相结合,看看效果如何。

烟雾效果测试

我们决定使用两个效果进行测试,即薄烟和浓烟。效果控制系统在零点附近有一个过渡,一旦度过这一阶段,薄烟排放量会增加并变浓,直到超过厚烟阈值。

上图示例中,轮胎行为影响了烟雾的整体运动。其中突出显示的参数是之前提到的温度,它们决定了所产生的烟雾类型。显然,这里的烟雾材质并不理想,但我们一直在做渲染改进,有信心制作出更浓密的烟雾材质。

回到《极限竞速:地平线 4》来讨论之前存在的问题,即粒子照明模型不像其它模块一样自然。在《极限竞速:地平线 4》中,平面上的光照效果是这样确定的:每个顶点都有一个亮度值,平面的亮度取自各个顶点亮度值的加权平均值,这导致光与阴影混合的区域出现了奇怪的视觉效果。当时的解决方案是在减少材质不透明度的同时增加半透明度,而这会导致轮胎烟雾相对较弱,轨迹的光影效果也不合适。

上图展示了一些《极限竞速 地平线 4》中微调透明度的工作,即通过在平面另一侧添加光源来降低粒子的阴影细节量。

此处是新旧粒子照明模型的比较。可以看到,现在的光照和阴影可以精确到像素,这是巨大的进步,粒子的渲染现在更加接近游戏世界的其他部分。上图右侧是一个新的六向光照贴图着色器,这也让我们更有信心使用更浓密的云,因为可以模拟来自后方的光线散射,因此也能呈现更逼真的光影效果。

快速总结一下优化轮胎烟雾的方法:

  1. 创建一个全新的、直接嵌入效果中的专用烟雾控制系统,结合新的扬尘效果器,可根据轮胎温度和运动改变烟雾的各项效果。
  2. 使车轮的运动和轮胎的温度变化直接影响轮胎的烟雾效果,更加真实地实现烟雾随时间推移而逐渐增强的过程。
  3. 精确到像素的光效和新烟雾材质使得浓密而持续的烟雾更加逼真。

我们很乐意让这些小粒子持续存在一段时间,以便玩家能够看到长时间的、令人满意的烧胎效果。有了所有这些要素,来看看我们创造了什么。

上图是改进前后的效果比较。多数情况下,新的轮胎烟雾效果能够呈现由淡淡薄烟逐渐变为滚滚浓烟的过程。令我们欣慰的是,作为游戏的核心部分,这一效果受到了玩家和评论家的好评,玩家社区中有许多用照片模式拍摄的精彩照片,尤其是对新轮胎烟雾效果的展示,这让我们非常开心。

除此以外,能够自由处理数据也可以实现一些很酷的新功能。比如通过持续监视汽车的内部空间,可以确认烟雾是否进入了汽车内部,并相应调整烟雾效果。还可以随着时间推移淡化烟雾,给玩家一种车子已经驱散了它的感觉。

至此,我们就轮胎本身产生的扬尘效果取得了巨大进展,但这还不够。比如,车辆在越野时产生的扬尘效果可能不仅和轮胎自身有关,此时该如何实现我们期待的效果呢?

第二个用例——扬尘!

让我们想想创建扬尘效果会面临什么样的挑战。每一代《极限竞速:地平线》作品中,扬尘效果的设计都面临着比上一代更大的挑战,因为我们的团队一直在不断突破极限,努力让场景中的每个地点都尽可能逼真。为此,VFX 团队需要针对不同地形材质设计合适的效果。

上图简单列举了游戏中的几种场景,但实际上,要考虑的场景类型还有很多。在游戏中,至少有 120 种地面材质需要跟踪,每种材质在不同季节的表现都不同。同时,它们还能自由搭配,形成各种组合,这就导致有许多类型的地貌需要处理。

以前的方案是复制现有效果然后微调,以适应游戏中的每种路面,显然非常繁琐。所以这一次,我们决定找到更好的解决方案。

考虑到之前从游戏中获取数据的成功经验,我们请熟悉 VFX 的渲染工程师协助实现了一个基于底层的功能,可以从游戏中选择合适的参数并直接传到效果器中。拥有这个功能后,我们开始用三种颜色适配同一效果中不同的流,并让不同材质的路面触发不同的颜色。

上图展示了汽车在一系列相似但不同的路面上行驶的效果。值得注意的是,图中的轮胎烟雾产生自同一个效果,而这些鲜艳的调试颜色则是根据轮胎实际接触的不同路面选择的。

我们使用这种能够把路面类型和扬尘颜色对应起来的方法,对路面进行分类。上图列出了《极限竞速:地平线 4》最终使用的扬尘效果。我们使用了三种基本颜色来对应路面的材质,每种材质也有更复杂的子类型,比如有些会扬起石头,有些表面是红色的,等等。这一过程也让我们意识到,如果可以使用参数来实现更多功能,而不仅仅是变换烟雾颜色,就可以进一步简化扬尘的创建过程。

比如,上图是游戏中西海岸和相邻沙漠的三种沙地类型,一种地面混杂着碎石,另一种则十分松软。我们不希望这些场景中的扬尘效果完全相同,但也不想每次都从头制作和调试。

如何达成这个目标?或许在扬尘效果中,除了轮胎本身,还可以考虑在不同地表卷起不同量的沙土,这与被卷起物质的深度,或者说轮胎陷入地面的深度有关。这些场景中,轮胎的核心行为基本相同,只是薄而紧实的地表和厚而松软的地表在密度上有区别。我们想到,也许所有带有沙粒成分的扬起物效果都可以合并为一个单一的母效果,于是我们给扬尘效果器增加了一个输入,即 effect float 4, 这一输入依赖于地形的深度。

在之前设计的效果器的基础上,输入通道从 3 个变成了 4 个。如你所见,新增的输入用来控制粒子大小。但我们并不满足于此,它完全可以驱动多个效果,比如扬起沙土的不透明度。

说干就干,我们为每种扬尘在 float 4 下定义 RGB 和深度。上图以深层沙(Sand Deep)和可塑沙(Sand Deformable)为例,展示了 XML 中的不同扬尘类型。图中标注了 4 个相关参数,其中 RGB 表示颜色,最后一个表示深度。在实现效果中,深度将起到类似轮胎烟雾案例中温度输入的作用,用于参与判定轮胎在这一地表上应该产生薄烟还是浓烟。

上图展示了简化后的效果内部逻辑,在这一示例中,我们监听灰尘的 RGB 属性,并将其拆分成为 RGB 和第四通道,即深度。深度值会监听左侧的多个属性,控制它们在各自预先定义的范围内,随后将其输入核心效果器。这就使得单一输入可以驱动效果的许多方面,而其余部分由之前展示过的面板进行输入控制。

我们决定更进一步,再添加一个输入来控制具有一系列属性的扬尘碎片。现在已经有 RGB,所以不一定要重复使用它。如上图所示,我们使用一个参数来控制碎片类型,另一个用于控制碎片的生成数量、碎片的基本大小,以及哪些平台上会出现什么质量的碎片。通过这些设置,扬尘效果不仅可以产生不同颜色、大小和不透明度的沙土,还可以生成不同类型的碎片。

上图展示了扬尘效果在不同深度的地面,以及包含额外碎片类型的效果。它们实际上来自同一个效果器,我们只是匹配了不同的输入数据,就输出了非常不同的视觉效果。

在开发这一效果器的过程中,我们有了一些惊讶的发现。比如,相比于使用大量基础效果,在进行扬尘设计时使用较少但更复杂并可调试的效果,CPU 的功耗要小的多;PopcornFX 在向现有系统中添加更多粒子时表现非常出色,这在 CPU 达到瓶颈时非常重要;单一母效果覆盖的效果类型越多,效果器的整体表现就会越好,这也让我们能够轻松将以上优化方案推广到所有 7 个平台上的扬尘效果中,让其适用于 Xbox One、Xbox Series X 和高性能 PC 平台——这对游戏非常重要,因为通常会有 12 辆车以高达 300 英里的时速穿越世界,每秒穿越数个不同类型的地面。

我们对制作的效果非常满意。这些效果在 PV 中扮演了重要角色,玩家社区也非常喜欢它们,并拍下了许多展示扬尘效果的精彩照片。

第三个用例——粉碎!

接下来谈谈粉碎效果。所谓“粉碎效果”想要实现什么目标呢?

首先,当车辆撞击可破坏对象时,冲撞效果应该尽可能自然。值得一提的是,游戏世界遍布可破坏的物品,在项目初期,我们预计可破坏物会超过 500 种,每种都应该对应一系列自然的效果。

要如何构建一个这样的效果呢?基于之前的经验,我们首先确定了需要监听的关键参数,包括冲击能量和碰撞瞬间的汽车速度。冲击能量用于确定飞起来的粒子的生成数量:冲击越强,生成的粒子就越多。

如上图,我们添加了一个基础行为,以计算任意碎片的初始速度;同时也要考虑冲击能量对射出粒子的整体运动应该有多大影响;还要考虑恰好能破坏这一可破坏物并触发效果的车辆速度。在此基础上,我们还为上述会被反复调用的参数加入了一些外部控制条件,以控制物体整体速度。

基于上面提到的速度等原始数据,还可以定义可破坏物的物理特性;物体的体积和密度可以用于计算碎片的质量;通过在全局参数中调用精确的重力和风力数据,可以使整体效果更加逼真且自然。

上图演示了此前设计的系统是如何在编辑器中进行组合的。左侧的控制面板可以测试在低冲击能量和高冲击能量下的效果,同时还可以预览在不同速度和冲击方向下的效果。

创建上述模板并实现了碎片的基本行为后,该考虑如何实现所需的所有效果了。有了扬尘效果器的经验,我们采用了基于 XML 的类似解决方案,在母效果内部实现多样化的可粉碎效果。我们添加了几个额外参数(Float4),用以动态选择 Uber 材质包中的材质。这样一来,要创建一个新效果,只需在 XML 文件中添加几行新代码,并将其分配给新对象就行了。

为了实现数量庞大的效果,我们为每种类型的碎片定义了一个索引,对应一系列预设。接下来,我们就能在 XML 中通过单一参数流实现预定义列表中特定大小、颜色和其他参数的选择。

上图呈现了可破坏母效果。看起来有点复杂,但相比它能够实现的数量庞大的效果而言,其实已经相当简洁了,因为它通过单一参数变化就能调节所有效果。

当车辆撞向某一个可破坏物体时,XML 便向效果器中设定一个参数流 float4。随后,效果器根据前面展示的预设索引,通过这个参数流自动选择碎片的颜色和尺寸,同时确定生成粒子的数量及类型,比如石板、大岩石、灰尘、木屑、塑料片等。随后在效果层中汇总所有信息,使用汽车的其它物理数据来确定生成碎片的速度方向和其余属性。

上图展示了这一系统在游戏中的效果。通过反复推敲和分类,我们成功地用仅仅两个母效果和一个 XML 文件构建了超过 500 个可破坏物体和其物理行为。在玩家不断破坏环境物体的场景中,这一解决方案为我们节约了大量硬件资源。

简单总结一下,通过新的解决方案,几乎所有可粉碎效果都被整合在一起。实现所有粉碎效果时,我们基本上只是在反复调用两个母效果,然后根据场景设置相应参数。这能在玩家进行极致的场景破坏,粉碎面前所有物体时,大幅减少场景绘制的调用。同时,这一解决方案也可以使用单一通道来输出多种碎片类型,比如烟雾、尘埃、溅起的泥土。此方案通过减少重复工作大大减少了 CPU 的工作时间,正如之前提到的,PopcornFX 更擅长少量但更复杂的效果。因此,如果分别使用单独的通道来实现不同效果,将不可避免地提高 CPU 开销。

第四个用例——瀑布,还有……

现在,让我们稍微深入谈谈 aloading 的概念,以及如何充分利用单一的模拟层来创建瀑布等效果。

我们可以使用俗称为“批处理模板”(Batch Templates)的技巧来实现这一目的。它仅仅采用一个粒子系统,但用到了许多前面谈到的原理。来看一个简单例子,它解释了如何通过一个效果层模拟所有物理效果。

批处理模板并非直接在效果层中定义输入数据,而是设计了一个中介层,在其中定义效果的位置、方向、颜色和持续时间等,然后通过中介层将这些数据发送到物理模拟层。

最终生成了这样一串气球。我们将原本的负载层改用批处理模板实现,即通过向同一模板发送不同的数据,实现原本多个负载层的功能。我们提取了实现不同视觉效果所需的所有数据,于是有了三股看起来不同的气球流,但实际上,它们所有的物理模拟都由同一效果层完成。

上图场景中的所有瀑布、水花和雾气效果都是基于这一方法创建的。所有 VFX 都来自同一个粒子系统,包含两个模拟层和大量负载数据。这大大减少了分别实现这些效果时由于重复任务导致的 CPU 资源浪费情况。

上图展示了岩井的水流效果中,进入效果器的一系列“生成事件”(Spawn Event)对应的负载数据。如位置、水源的大小、方向、粒子大小等。

如上图所示,在效果层内,不同的水流通过相同的流程生成,它们的区别仅在于输入数据不同,这和瀑布气球示例中展示的一样。

上图是一个编辑器的例子,首先使用一组负载数据实现一股水流,再用相同方式激活其他水流,最终形成瀑布。随后在水花效果和雾气效果层中使用同样的方法,并在编辑器中将它们结合,就能得到前面岩井场景中的水流效果。

如前所述,这种方法的 CPU 开销比原来的方法要小得多,因此被广泛应用。游戏中如云雾、火山喷发等效果都是这样创建的,尘暴效果也使用了类似方法。

总结

首先确定一些核心参数,围绕它们设计效果系统。通过读取游戏中的其它数据作为额外参数,调整效果以适应游戏场景和玩法。随后便可以轻松地修改效果,或通过在 XML 或其它途径创建额外变量。即使不考虑外部输入,这种方法仍然很好用,因为它可以直接在效果内定义或嵌入一切所需的数据内容。

我还强烈推荐 GDC 2021 的一场演讲,题为《如何使用简单的控制构建复杂的 VFX 系统》(Visual Effects Summit: How to Build Complex VFX Systems With Simple Controls),它涵盖了今天讨论的许多主题。

总而言之,使用模板是个很好的方法。当需要设计大量同类型效果时,在项目初期设计一个好用的模板,能够为下一步工作带来难以置信的便利。模板能更方便地保持同类效果的行为一致性,因为只需要对母效果进行一次调整,所有子效果都将相应改变。在具体场景中,也可以通过创建模板的本地副本以设计变通方法或应对特殊情况,这时只需要决定哪些修改不推广至所有依赖项即可。

考虑到我们需要从零开始实现所有效果,这一方法是非常高效的。以前需要超过 100 个复杂文件来实现车辆的扬尘效果,现在只需要不到 10 个母效果和一个 XML 文件。超过 500 种可破坏物的破坏效果只需两个母效果和一个 XML 文件就能完成。这带来了巨大的性能优势,也为不同平台的效果适配提供了便利。

问答环节

Q1:你们好像是基于材质类型来确定扬尘效果的,但实际情况中,同样的材质也可能有细微区别,这时你们会考虑具体情况下材质的表现吗?比如,你发现这里有个水坑,那里又没有,这时会需要自适应的着色器或类似工具吗?

A1:地面材质系统其实考虑了很多这类因素,同时也有单独的“地面类型”参数,某种程度上包含了一些可见的材质区别。但同时,诸如汽车行为之类的游戏内参数也明显影响着路面状况,如果路面是沙地还是柏油路的话,我们也会利用这些来决定要通过母效果制造什么样的扬尘。


Q2:相较于《极限竞速:地平线 4》, 今天提到的这些效果的 CPU 利用率提升了多少呢?

A2:在所有平台上,我们的 CPU 预算都是 2.5 毫秒,在 Xbox、Xbox One、和 Xbox X 上都是一样的。很明显 Xbox X 和 Xbox one 上的 2.5 毫秒是非常不同的,不过我们一直要求将 CPU 消耗控制在此预算内。某些情况下,比如在 Xbox One 平台,我们会考虑一些额外用例,而环境相当复杂的时候,甚至需要将这一预算进一步降低。总之 CPU 预算基本不会高于 2.5 毫秒。


Q3:你们和《极限竞速》(Froza Motorsport)系列使用的是同一个引擎吗?

A3:我们确实与 Turn 10 工作室和《极限竞速》系列共享部分引擎。


Q4:你们的 HDR 天空和渲染可能是我见过最好的之一,做得真的很漂亮。为了实现 HDR 渲染,在粒子方面需要进行哪些调整?

A4:我们的天空盒基本上如你在多年来一些 GDC 演讲中看到的那样,只是在不同场景中捕捉天空,然后结合运动矢量,尽我们所能使其更加逼真。在视觉特效方面,某些情况下——比如山顶的某些场景中——我们添加了一些额外的低洼云,以模仿现实情况。显然这是很难的,因为这就像是用粒子效果来还原一张真实、连贯、完整的天空照片。这一工作没有什么可以自由发挥的空间,我们做的事也比较枯燥,就是尽可能做到逼真。


Q5:你们是否遇到过过载问题,我注意到当场景中有像汽车这样移动速度非常快的物体时,需要产生大量粒子来避免画面空白。当粒子密集地穿过玩家位置(比如车后面的摄像机)时,PC 或者 XBOX 可能会因为过载而出现画面溶解。你们是如何克服这个问题的?

A5:对于持续扬尘或长尾轮胎烟雾这种庞大的粒子效果应用,我们实际上只渲染了这些效果的一部分。在某些情况下这显著改善了 GPU 表现,因此我们视其为有效方法。同时很自然的,对于性能较低的平台,我们减少了粒子的生成数量,同时也降低了粒子的持续时间,这样发射的粒子之间就不会出现死区。与 Xbox Series X 相比,这些效果在 Xbox One 上的唯一变化就是寿命较短。


Q6:每当我尝试使用这些参数制作这样一个动态系统时,经常会遇到边界问题。例如,你提到可以根据速度调整粒子尺寸,在大多数情况下这个策略的效果还不错,但如果汽车非常慢,就会有很多看起来行为奇怪的颗粒,对吧?有时我想把这些情况也考虑到,于是尝试为这些特殊情况添加变通方法,因此得到了一个非常复杂的系统,并且它难以扩展,因为系统里充满了特殊情况的变通方法。我想知道你是如何在不牺牲系统简洁性的情况下实现这些特殊效果,使系统总是表现良好的呢?

A6:针对你说的这个例子,或许一个比较好的解决方案是设置一个非零初始值,也就是让粒子的最小尺寸取一个预定义的值,然后控制其在最大值限制下变化。这样一来,效果器的输出基本会根据在游戏中监听到的数据,在这一范围中徘徊,我们大致就是这样做的。但显然这一切都需要大量调试,这也就是为什么我们要在 PopcornFX 中设计一个可以调整各种属性的面板。我们针对这些属性预定义了一些最小值和最大值,所以效果本身就不会崩坏,同时也不会出现过小的颗粒或者类似问题。


原链接:https://www.youtube.com/watch?v=8Pk-yAp7J_8
*本内容系编译整理,不代表 indienova 立场。未经授权允许,请勿转载。