【ue4】【使用】特效系统Cascade与Niagara

Cascade 使用

我们知道,只有Actor才能显示在游戏场景中。

那么当我们拖动一个作为资源存在的 ParticleSystem 粒子系统时,发生了什么?

是谁,放任一个本本分分的资源溜进了游戏场景中去?

(敬请收看今日走进UE之谁偷了我的粒子-.-)

Particle System 的层次结构

当我们把一个 ParticleSystem 类型的粒子系统拖到场景中去时, 引擎会自动创建一个 Emitter Actor 对象。 而这个 Actor对象,是这个粒子系统在游戏场景中的代表。

我们知道,Actor 只是一个容器,真实承载着各种功能的是 Actor 名下的众多 Component

那么一个 Actor 自然需要一个或多个 Component 去实现 ParticleSystem 与众不同的功能。

不巧,当 Emitter Actor 被创建的同时, 就默认为其创建了一个 ParticleSystemComponent 的组件。

而这个组件,这里简称其为 PSC, 自然是整个粒子系统的等各种功能的集结地。

我们可以发现,在 PSCDetail 面板的 Particles 目录下有一个名为 Template 的资源项(Asset)。 它目前恰恰指向我们原来拖到场景中的资源对象。

那么从资源到 Actor 的过程就不言而喻了(本期走进UE可以结束了-.-)。

拖动资源到场景 -> 创建 Emitter Actor -> 创建 PSC -> 将 资源变量 Template 赋值为一开始拖动的资源。

下面就会对 Template 里的资源进行渲染,而渲染的最终结果除了一些暴露在外面的属性,就取决于这个资源本身的内容了。

我们双击这个资源,就可以打开一个新的窗口,这个窗口就叫做 Cascade, 也就是UE4自带的粒子编辑器。

从上图我们也大致可以看的出来,一个 ParticleSystem 资源中包含有两种结构。

Emitter

Module

Emitter 即发射器,一个 ParticleSystem 可以包含多个发射器。

一个发射器可以包含多个 Module, 这里的 Module 并非本来UE4里的模块,而是一个渲染的单位。

一个 Emitter 通过多个 Module 的不同组合和参数设置来实现丰富的最终效果, 如粒子的数量、速度、旋转、颜色、生命周期等等等等等等。

一个 ParticleSystem 再通过多个 Emitter 的组合来实现更加Amazing的效果。

至此,我们可以总结一下 ParticleSystem 的层次结构了。

一些 Module

UE4粒子系统中的 Module 的计算顺序是从上至下的, 即放在最前面位置的 Module 优先级更高。 可以直接用鼠标拖拽来调整。

而且 Module 对于最终效果的影响也是在已执行的 Module 基础上进行累加的。 可以选中想修改的 Module, 然后在其 Detail 面板进行修改。

当我们创建一个 Emitter 的时候,它会默认包含一些 Module, 如下图

但是其中有两个 Module 是我们无法删除的

Required -- 所需模块 -- 一些 Emitter 自带的参数设置

Spawn -- 生成模块 -- 对粒子如何生成进行一些参数设置

下面介绍一些比较常用的 Module

Type Data

TypeData 表示不同的粒子系统类型。

可在发射器名称与 Required 模块之间的黑色空白区设置或显示其类型。

其类型主要包括

Sprite

GPU Sprite

Mesh

Beam

Ribbon

AnimTrail

Sprite

Sprite 类型是创建粒子系统是默认的类型。

在 CPU 上模拟粒子运行。

使用 Billboard 面片来渲染粒子 -- 始终朝向镜头。

可用于模拟各种烟雾、火花、火焰效果。

如初学者内容自带的 P_Steam_Lit 烟雾就是典型的 Sprite 类型的发射器。

GPU Sprite

GPU SpriteSprite 类似, 也是使用 Billboard 来渲染粒子, 只是将模拟粒子运动的计算放在了 GPU 端高性能并发地执行, 所以能够支持更多的粒子数目。

可用于粒子数较多的 Emitter 中。

适用于支持 MRT 功能(多重渲染目标) 的设备。

如初学者内容自带的 P_Sparks 特效中的 SmokeSparks 发射器就使用 GPU Sprite

Mesh

Mesh 类型是为了支持使用网格来渲染粒子。

可以选中 Mesh 模块后在其 Detail 面板进行设置 Mesh 资源的选择等。

Beam

Beam 类型可以实现在两个物体之间连线的粒子,类似于 U3D 中的 LineRenderer

此连线可随着两个物体之间距离的变化进行拉伸或收缩。

可用于类似连接两个玩家的链条,或者带有跟踪效果的激光条等。

选中 Beam Data, 可以看到它的细节面板如下

一些简单的解释如下

Beam Method -- 光束方法,总共三种。

  • Distance 为沿X轴方向的光束。

  • Target 为两点之间的光束。

  • Branch 为暂时没有效果。

Texture Tile -- 调整粒子材质的平铺数,只对第一套UV有效

Texture Tile Distance -- 每一个粒子材质平铺的宽度,为0时表示关闭

Sheets -- 沿光束所渲染的面片的数量

Max Beam Count -- 光束数量上限

Speed -- 光的速度,为0时直接跳转

Interpolation Points -- 大于0时会在源点和目标点之间插值,可用来增加噪波特效

Always On -- 是否做主始终有粒子存活

Up Vector Step Size -- 决定光束的 Up 向量的方法 - 0表示每个点计算; 1表示只在开始点计算并应用到所有点; N 表示插值计算N个点

Branching Parent Name -- Beam Method 为 Branch 时,指定分支的父发射点

Distance -- Beam Method 为 Distance 时,设置光束的传播距离

Taper -- 光束随时间衰减的方式及其他参数

Rendering -- Geometry表示是否渲染几何体,其他的都是调试用的

Cascade -- 通用的Cascade编辑器属性

当我们选择了 Beam 类型之后,可以添加4种特有的模块以配置 Beam 表现。

Beam Modifier 用来修改光束的源点或目标点的属性

Noise 用来在光束上增加噪波影响

Source 用来指定源点,当没有指定时发射器的位置会作为源点

Target 用来指定目标点

当我们设置 Beam MethodTarget 时,我们添加 SourceTarget 模块, 并分别指定其 MethodName

我们指定的 Name 要在场景中的 Emitter ActorDetail 面板里添加到 Instance Parameters 里去

关于其他的具体参数可参考此文档 UE4粒子光束类发射器及应用

Ribbon

Ribbon 类型的粒子可用于实现__飘带__的效果,其原理是将粒子之间用飘带连接起来。

类似于 U3D 里的 TrailRenderer

在场景中移动时,飘带会跟着轨迹飘动并逐渐消失。

AnimTrail

AnimTrail 类型的粒子也模拟拖尾效果。

它可以挂接到角色动画的骨骼上,跟随挂接骨骼的运行轨迹形成拖尾效果。

然后就可以在这个通知状态的 Detail 面板里进行一些设置以播放特效

Required

Required 模块是 Emitter 创建时默认就添加而且不能删除的模块。

大体包括 Emitter相关属性 时间相关属性 渲染相关属性 等的配置。

如材质、发射器的 Transform、发射器的持续时间,发射延时等。

在为粒子系统创建材质的时候, 材质的 Blend Mode 一般为 Translucent, 即半透明模式。

而且需要通过 Particle Color 节点来修改粒子的颜色。 相当于从 Particle System 传过来的颜色参数会放到 Particle Color 里, 从而影响最终的材质显示。

Light

Light 模块可以为粒子系统添加光源。

暂时只用于 CPU 粒子。

Collision

Collision 模块可以添加对粒子的碰撞检测支持。

比如初学者内容自带的 P_Sparks 特效。

Event

Event 模块为粒子系统提供触发事件以及事件响应的功能。

分为 Event GeneratorEvent Receiver 两种。

下面是 Generator的细节面板

可以在 Type 里选择不同的事件类型,包括生成、发射、碰撞等。

通过 Custom Name 设置事件名称,以在 Receiver 里据此处理不同的事件。

下面是 Receiver 的细节面板, Receiver 又分为 Event Receiver SpawnEvent Receiver Kill All,

分别表示在接收到事件时生成新粒子 和 在接收事件时删除该发射器所有粒子。

一个发射器可以有多个 Event Receiver

其中 Source 里面即为响应事件的类型的名称。

Camera Offset

Camera Offset 模块用来实现将粒子根据相机位置进行位移的功能。

Vector Field

__向量场__是一组在空间中分布的向量。 这些向量表示粒子在该位置时的速度或者加速度。

可用 maya 或者其他第三方工具制作向量场。

UE4 使用 体素 来表示向量场。 每个体素保存了向量的 xyz 分量。

目前向量场仅支持 GPU粒子。

向量场分为两种 -- 局部 和 全局。

局部向量场只影响该 Vector Field 模块所在的粒子系统。

全局向量场会影响空间中所有的粒子系统 -- 需要将向量场资源作为 Actor 放入场景中去。

通过向量场的 Tightness 取值设置粒子的速度 - 当 Tightness 取值为 0 时,向量值会累加到粒子速度 -- 表示力。 - 当 Tightness 取值为 1 时,向量值会直接赋值给粒子速度 -- 表示速度。

也可通过 VF 开头的其他 Module 对向量场的旋转和缩放进行调整。

关于 LOD

当粒子系统距离相机较远时,可以通过 LOD 来降低渲染的开销。

我们只需要先将 LOD0 的粒子系统制作好。

然后点击工具栏里的 Regenerate Lowest LOD, 引擎就会自动创建最低级的粒子系统(LOD1)。

默认情况下创建的LOD1粒子系统的所有设置都继承自LOD0,但发射粒子个数被降低到1/10。

默认情况下创建的LOD1粒子系统除了 Spawn 模块外其他的都不能修改,因为它们是 从更高级共享 过来的。 这个时候我们只要在想要修改的模块上右键, 选择 从更高级复制 即可进行编辑。

如果需要添加更多的 LOD 层级,点击工具栏的 添加 LOD 即可。

可以在粒子系统的 LOD 设置中设置不同的距离使用不同的 LOD

Niagara 使用

准备

在使用 Niagara 之前,需要先启用此插件

最好把 Extras 也点上。

FX 目录下可添加 Niagara 相关资源。

如图,这些资源包括

Niagara System -- Niagara 系统

Niagara Emitter -- Niagara 发射器

Niagara Script -- Niagara 脚本资源

Niagara Parameter -- Niagara 参数集合

从这里就可以看出, 虽然说 Niagara 也有 SystemEmitter, 但是 Emitter 已经从 Niagara 中分离出来,变成了一个独立的资源存在。

而且又多个两个新成员,这真让人感到恐慌又兴奋。

从宏观的层次结构上来看,CascadeNiagara 是差不多的, 也是 System -> Emitter -> Module 这种模式。

但是 Niagara 的存在是合理的,因为存在即合理(黑格尔)。

下面我们就来探索一下 Niagara 的合理之处。

Niagara System

Niagara System 类似于 Cascade 中的 Particle System 资源。

当我们拖动一个 Niagara System 类型的资源到场景中去时,也会有类似的流程 > 拖动资源到场景 -> 创建 Niagara Actor -> 创建 NSC -> 将 资源变量 Niagara System Asset 赋值为一开始拖动的资源。

然后我们的重任就全都落到这 Niagara System 资源身上了,双击打开它,就是我们的 Niagara 特效编辑器。

上图是包含了一个 Emitter 的 System。

我们可以向一个 System 添加许多 Emitter

从右边的 Selected Emitters 窗口可以看出,Niagara 的界面还是比较整齐的。

一眼就可以看出有4个模块。

蓝色的为 System 系统属性 -- 包括 Spawn(初始化执行一次) 和 Update(每帧都执行)

橙色为 Emitter 属性 -- 包括 Spawn(初始化执行一次) 和 Update(每帧都执行)

绿色为 Particle 属性 -- 即每一个粒子的属性,也包括 Spawn 和 Update - 也包括一个 Add Event Handle 以配置事件相关的 Module

红色为渲染属性 -- 表示渲染相关的属性

而我们把每一个 Spawn 或者 Update 展开, 每一个展开项就是一个 Module 了。

这里 Spawn 和 Update 相对于 Cascade 来说是对 Module 更加合理地分了类。

我们注意到每个 Module 前面有不同的图标,有的是圆形的,有的是向右上的箭头, 这里向右上的箭头就是前面提到过的 Niagara Script 脚本资源,它也可用作一种 Module

我们可以双击这此脚本资源,即可打开此脚本资源的节点图标,像蓝图一样对其进行编辑。

这也是 Niagara 最具吸引力的地方。

这个我们会在后面的 Demo 里实际使用。

Niagara Emitter

对于 Niagara 粒子系统的编辑,我们最好放在 Emitter 而非 System 里进行,以防止一些 bug 产生。 到目前为止 Niagara 还有一些扰人的bug, 让人又爱又恨。

即正确的做法是 > 建立 Emitter -> 完成 Emitter 的编辑 -> 将 Emitter 整合进 System 里

Emitter 除了没有蓝色的 System 属性之外,其他的与 System 都一样。

Niagara Script

这里所说的 Script 是用途 Module 的Script,除此之外, Script 还可用作 FUnction(函数) 或者 Dynamic Input(输入参数)。

正如前面讲到的那样,个人认为 Niagara Script 是整个 Niagara 的灵魂。 其实质是可以自定义的 Module,从而提供了对整个粒子系统更加致命的控制权。

下面通过一个小 Demo 来体验对 Niagara 的使用。

Renderer

关于各种 Renderer 类型的使用请参考 Niagara - How To's

Demo

这个 Demo 的最终效果是实现粒子特效先散开,然后聚拢成 SkeletalMesh。

炸开效果

新建 Emitter, 并且

设置 发射器更新 -> Spawn Rate 为 0.0

添加 发射器更新 -> Spawn Burst Instantaneous -> Spawn Count 为 10000

取消 粒子生成 -> Add Velocity -- 取消速度

设置 粒子生成 -> Sphere Location -> Sphere Raduis 为 100.0

设置完之后预览界面会显示下图效果

使用 Curl Noise Force 实现炸开效果

点击 粒子更新 右边的加号

添加 Force -> Curl Noise Force 模块给其增加炸开的力, 并设置 Noise Strength 为 500.0 - 注意此模块要放在 Solve Forces and Velocity 之前

勾选 Solve Forces and Velocity -> Mass 并设置值为 1 以开启力的混合

设置完成后预览界面即会显示炸开效果

聚拢效果

新建一个 Niagara Module Script, 用来设置自自定的 Module

双击打开

注意上面红框内的4个需要注意的地方

Module Usage Bitmask 表示可以使用此脚本文件的模块, 这是一个按位的掩码

Category 允许我们自定义其存在的目录

Parmeters 里包含外部的输入变量,可自己增加

在节点图表中,映射获取相当一个输入参数表,映射表相当于一个输出参数表

实现聚拢效果的实质是控制每一时刻每一个粒子的位置。

如果我们能拿到每个粒子的位置的数据,同时也能传入一个 SkeletalMesh 的位置数据, 那么再考虑一下时间, 在这两个位置之间进行插值,就可以最终形成聚拢效果。

在 ParaMeters 里可以看到, Particles 目录下本来就有两个变量 -- NormalizedAge 和 Position

其中 Particles.NormalizedAge 是 粒子系统的归一化时间, 即当前已经运行的时间比率映射到 [0, 1], 这个值是在 粒子更新 -> Update Age 模块不断更新的(Update Age 模块也是一个 Script)。

我们在 Module 目录下新建一个 SkeletalMesh 类型的变量,这个变量后面将从外部进行输入。

有了 Particle.Position 和 Module.SkeletalMesh, 我们就可以对这两个所代表的坐标进行插值计算了。

这里我们为了想自己控制每个时刻插值的比重,所以还要传入一个曲线, 所以要新建一个 CurveToFloat 变量。

最终的节点图表如下所示。

其中 Sample Curve 节点根据传进来的曲线和当前的运行时间来获取某一时刻曲线上的值, 这个值作为 Position 和 SkeletalMesh 的插值比重。

其中 Get Tri Position WS 节点用来获取 SkeletalMesh 上某个面片的位置信息, Random Tri Coord 随机取 SkeletalMesh 上一点的 Coordinate -- 由于粒子数很多,所以可以最终形成。

最后使用一个线性插值Lerp将两个坐标进行混合,结果输出到 Particle.Postion 上即可, 其中 结果 = A(1-C) + BC。

我们将制作好的 Script 作为 Module 添加到 粒子更新 处, 并传入相应的 Curve 值和 SkeletalMesh 值。

以上只是对 Niagara Script 的一个很简单的使用。

有了众多运行时每个粒子的数据,我们可以十分彻底地对整个粒子系统运行阶段进行精确的控制, 从而实现任意想要的粒子效果。

【Tips】 Niagara 有时候会有些小 bug, 有时候碰到播放不出来等情况,就要看运气行事了。

比较

Cascade 的文中意思有 小瀑布 的意思。

而 Niagara 是 尼亚加拉大瀑布 的意思。

其优势上下,一目了然。

但是这也只是说最后的结果,以后的走向,现阶段的 Niagara 还不是十分完美,所以才没有完全淘汰 Cascade。 但是个人认为 Niagara 取代 Cascade 只是时间的问题。

从应用层比较

如果让我说 Niagara 与 Cascade 最本质的不同,我觉得就是 Module 的改头换面脱胎换骨了。

原来的 Module, 我的理解更像是一种配表工具,就像 Niagara 里的 Parameters 一样, 我们很难精确地控制其背后的逻辑。尤其是粒子运行时的一些信息(位置,速度等)。

NiagaraModule, 不仅仅有了更好的分类,而且还可以作为脚本,使用节点图进行编辑, 直接从各种 Parameters 里面获取数据,掌握对整个粒子系统从发射到完结的整个过程, 理论上是可以实现任意我们想要的粒子效果了,着实是只有想不到,没有做不到。

总结

参考资料

虚幻引擎学习之路:粒子系统篇(一)

虚幻引擎学习之路:粒子系统篇(二)

虚幻引擎学习之路:新粒子系统Niagara

Niagara Key Concepts