索尼特效主美:如何用可编程粒子系统实现《死亡回归》炫酷特效?

【GameLook专稿,未经授权不得转载!】

GameLook/视觉特效能否用粒子系统来实现呢?在GDC2022大会视觉效果论坛上,来自索尼PlayStation旗下Housemarque工作室的两名大牛分享了他们非常规的可编程粒子系统。

演讲中,Housemarque工作室特效主美Risto Jankkila和高级图形程序员Sharman Jagadeesan,讲述了如何运用他们的可编程粒子系统(Programmable particle system),来创作《死亡回归(Returnal)》关键特效功能,内容包括由实时流体模拟驱动的体积雾和角色效果粒子层次的使用,比如触角。

以下是Gamelook听译的完整内容:

Risto Jankkila:

我叫Risto,是Housemarque工作室特效主美(Lead VFX Artist),另一名演讲者是Sharman Jagadessan,担任高级图形程序员。

简单介绍一下公司,Housemarque成立于1995年,在《死亡回归》之前,我们比较具有代表性的双摇杆射击游戏有《死亡国度(Dead Nation)》、《Resogun》和《死亡机器(Nex Machina)》,《死亡回归》是我们迄今为止最大的项目,去年发布于2021年。我们与索尼合作了很长时间,去年6月份成为了PlayStation工作室的一部分。

今天的分享主要讲的是我们如何利用自己的特效系统,为《死亡回归》做出一些非常规的东西。对于非常规,我指的是植被、角色(触角)效果等等,这些通常被认为不会通过粒子系统来处理。除了非常规特效之外,我们也使用了常规粒子效果,熟悉这个领域的同行可以很容易看出来。

首先,我们会剪短介绍VFX工具,我认为我们的工具比较独特,只有了解了它们,才能更容易理解我们用它做了什么。随后,我会谈到粒子层级,最后Sharman会谈到外部资源和模拟方面的内容。

HMQ特效引擎

我们自从2014年就已经开始在研发自己的特效系统,当时我们使用的也是内部引擎。在此基础上,我们为《Alienation》研发了一个GPU粒子系统,为了《Matterfall》的制作,我们转移到了Unreal Engine,同时也将特效系统移植到了虚幻引擎之中。

游戏设计层面,我们试图聚焦于灵活性和游戏性能(仅指GPU性能),另一个目标是所有东西都是完全可编程的(HLSL)。

再说一些定义:在我们的系统中,提到粒子,我们指的是HLSL文件,所以,为了给引擎打造特效,我们必须做一个文本文件,而不是敲代码;效果,指的是可以相互作为参照物的粒子系统,比如Emitter与其他粒子,系统本身不会识别Emitter;最后是VFX引擎,它运行我们所有的特效展示,本质上是虚幻引擎内的一个插件,最开始我们把它叫做特效系统,但考虑到它的功能很多,我们决定将其称为特效引擎。

接下来举一个案例,如之前所说,要做特效必须先做文本文件,在这个文件里面,我们必须定义粒子是什么,还需要确定这个例子做什么,主要是通过粒子结构进行定义。可以看到,粒子结构内部是变量,这些变量是粒子可以存储和修改的数据,你可以增加尽可能多的变量,也可以选择如何命名。

随后,我们可以确定粒子的功能,这要是通过更新函数实现,比如图中的Do_Update,我们在这里甚至不会对粒子进行渲染,这给了我们很大的灵活性。

这里团队中的美术师成员可以对特效进行修改,比如选择材质分配、动画曲线,包括增加资源甚至是颜色挑选。这些都不是用在《死亡回归》的制作当中,而是由理解着色器代码的人提前进行定制化,才能交给团队使用。

粒子层级

在我们的系统中,粒子层次很大程度上是节点粒子。当我们研发《死亡回归》的时候,节点粒子可以为我们带来新东西,它们并不是专门为了游戏而研发,但最终却对项目进展带来很大的帮助。

节点粒子的概念很简单,它们基本上和系统内所有的粒子没什么两样,但却都可以在必要的情况下检索父粒子的数据,父粒子可以有多个子粒子,但每个子粒子只能有一个父粒子。这种粒子我们在《死亡回归》项目研发中经常使用,包括植被、触角以及可破坏物体的视觉效果。

首先,我们需要在标头确定节点粒子类型,像往常一样做粒子定义,随后在更新中,我们可以通过一个函数得到父粒子数据,接下来你就可以在父粒子数据基础上做任何想要的逻辑。通过代码,可以看到我们这里只是想检查父粒子的距离是否超过100。

这是一些移动的节点粒子,并且不断生出子粒子,单独看这些例子,可能看起来有些混乱,所以我们需要给它们的运动增加一些限制。

首先我们限制粒子运动能够离开父粒子的距离,也就是图片里的绿色圆圈,最后,我们可以给运动增加一些噪音。

现在,我们有了可以用作触角移动的基础,但它依然被锁定在特定区域内。右侧是渲染过的效果,我们考虑了很多的选择,最终选择了用更新函数来实现。那么,我们是怎么做到的?

除了sprites渲染之外,我们还在特效引擎对三角形进行了渲染。两个比较关键的点是,我们可以自由定义三角形顶点位置,而且可以随心所欲地渲染更多三角形,这一点我不会很深入讲解,但图片中的代码已经可以说明很多问题。

这幅动图展示的东西已经和游戏内效果很接近,只需要替换成游戏内资源即可。我知道这种渲染可能并不罕见,但比较特别的是,我们可以逐个粒子进行渲染,带来非常好的性能表现。

我们在游戏里使用了这些系统,由于它们表现很好,我们可以用程序编写它们的行为。比如游戏里的敌人,它们会在攻击之前变身。

同样,我们也可以在区域中对植被进行节点粒子渲染,控制玩家行为不至于和它们冲撞,这个效果就是游戏里的植被在检查玩家进度。

我觉得节点粒子另一个灵活性的优势就是,我们可以用它来给《死亡回归》做简单的可破坏物体。

这些物体必须在Houdini预处理,我们首先将它拆成很多碎片,然后再重新组装到网格当中。随后,我们将网格导出到Unreal Engine,在游戏里,我们为每个主要碎片创作粒子,每个粒子都可以检索结构,这样我们就可以告诉每个粒子物体的圈层、三角形,然后渲染它们。

在游戏里,当一个物体被子弹击中之后,我们就隐藏静态网格,每个粒子都会随着它们所属的网格运动,当这个可破坏物体坠落之后,我们就停掉它的动画。这时候,我们就可以做粒子动画,这些碎片在空间里四处飞溅。

基本上,我们用它来做一些敌人特效、雕塑等物体,甚至还专门用可破坏系统设计了一个游戏内BOSS。

外部资源和模拟

Sharman Jagadeesan:

我要分享的是实时流体模拟驱动的体积雾,我们使用了一些外部资源,这里指的是粒子可以读取的GPU资源。我们的粒子本质上不做任何事情,比如你要从一个网格提取一些东西,就需要手动将这个网格与粒子结合起来,为这些缓存资源寻找许可。这些资源可以是2D纹理、3D体积效果,以及我们上面提到的缓存。

资源的案例最好的就是流体模拟,实际上,我们自从(2016年)《Alienation》开始就已经在使用,所以,全局流体模拟都可以跟随玩家,我们的美术师可以在关卡中模拟空气流动,这可以用到很多效果当中,我们接下来会介绍:

我们可以从跟随玩家的流体模拟开始,如图中的红色箭头所指。

这是游戏里的真实案例,所有的植被以及体积雾都使用了流体模拟。

资源使用非常简单,我们的特效系统可以看做不同的模块,他们不是按照代码配对,而是基于数据。一个模块可以生成一些数据,比如流体模拟,你可以将它与其他模块搭配,比如我们的粒子引擎。

可以看到,我们将其称之为FluidVel3D,然后用meta语言将其转化为游戏玩法,虽然代码很简单,但仍然可以创造出如下效果:

我们可以使用多种资源,比如将MeshBuffers绑定到同一个粒子

可以看到下面的效果:

附在敌人身上的白色粒子在受到射击的时候会离开本体,带来很流畅的视觉效果,经过冷却时间之后,它们会返回到初始位置。

游戏里有一个触发区域,你走过去就可以看到虚幻的物体,实际上就是一些粒子。

我们再说说体积,因为我们使用的次数很多,与《Resogun》不同的是,我们将其当做一种资源来使用。它们其实就是3D纹理,通过一些2D纹理,我们就可以组成一个体素(voxel)。

这张图展示的每个粒子都代表一个体素,它们都有一个ID,可以转化为一个体素或者世界里的某个位置。

我们还可以决定体积的密度,比如图中的MyDensityTex,这里我们把它写到GPU资源当中,前面的案例展示了如何读取,这里展示的是写入,但是需要注意不要将多个三角形放到一个体素里。

右侧是粒子效果,左侧是用它做的体积雾。

你可以直接把体积雾放到关卡当中,用起来非常简单。

另一个使用案例就是做一个网格,看起来像是一张饼。

在《死亡回归》当中,如果你足够熟练,五分钟内就可以进入这个房间,我看过很多人玩游戏的视频,但大部分人都只是走过去,让我很不满,因为我们在这里做了很多技术性的东西,有粒子系统、流体模拟,但人们却直接忽略掉了。不管你是否向它射击,GPU消耗都是一样的。

右侧是网格的雕塑,左侧是粒子版本,射击之后可以看到对应的效果。

在游戏里,你可以随意向它射击,虽然造不成任何伤害,但可以看到这些效果。

最后,我们能够用粒子实现特效吗?我们认为是可以的。

如若转载,请注明出处:http://www.gamelook.com.cn/2022/10/496723

关注微信