最近开始学习Niagara 的使用。

UE4的Niagara是最新一代的粒子系统,之前的Cascade粒子系统已经完全弃用不再维护。Niagara是虚幻引擎的次世代VFX系统。利用Niagara,技术美术师能够自行创建额外功能,而无需程序员的协助。我们将系统设计得具有更高适应性和灵活性,同时使其易用、易理解。

Niagara目前是使用插件提供,需要打开插件才能看到,在4.25之前都是Beta版本,但是在4.25已经能够正式使用。

Generated
Generated

开启后,我们就可以在引擎中使用。

一.Niagara与Cascade

Generated

Cascade的组成逻辑很简单,Module(模块)-->Emitter(发射器)-->Particle System(粒子系统),这里面模块负责定义单个粒子的行为,比如颜色/大小/运动轨迹等,发射器负责处理粒子需要的材质/朝向模式/发射器类型等等,而最终发射器组成了粒子系统。

Niagara在大的流程方向上其实和老粒子系统一脉相承。同样是模块--发射器--系统这个结构,不同在哪?最核心的点应该是模块自定义。老粒子系统的模块固定提供给开发者,虽然有着高度可调的数据,但是整体流程是封闭的,你右键永远点不出系统提供以外的模块。

而Niagara她将源头开放了,把粒子系统内最小的组成---模块完全打开。模块脚本让我们能够随心所欲的发挥,这个开口几乎放开了整个引擎的数据供Niagara粒子使用,简直奢华。你可以随意修改粒子发射行为,位置/颜色/速度等属性不在局限于“initial color”“initial size”“sphere location”等固定的模块,我们可以借鉴大量图形算法实现复杂的画面效果。

Cascade的基本理念是,尽可能使用模块化方法来创建效果。为了实现此目的,在创建任何新效果时,Cascade会提供一组默认模块,以及用于添加更多模块或全新发射器的工具,具体取决于美术师需要实现的效果。虽然该系统多年来效果良好,但仍存在一些小问题,导致一些任务执行时间较长,而且易于出错,例如在几种效果之间共享数据或者一次性更新许多效果。

为解决这些问题,Niagara完全采用了模块化的方法。Niagara将构成粒子系统的各个发射器分隔成独立的单元。Niagara系统 没有让粒子系统包含各个发射器,而是由许多个独立的 Niagara发射器 组成。每个Niagara发射器包含一种效果,而该效果由你所熟悉的各种模块控制。例如,time位置大小,这些模块可以调整粒子的行为和外观。但是,由于这些Niagara发射器是存储在内容浏览器中的独立actor,它们可以更新并与你想要创建的任何Niagara系统共享。这样你无需花费大量时间,即可对发射器进行修改。

设计Niagara的目的:能够让用户完全控制整个系统,并且数据与项目之间的数据传递是非常清楚的。

Generated

Niagara核心组件

Generated
Generated
  • 系统Systems
  • 发射器Emitters
  • 模块Modules

Niagara System

Generated
Generated

Niagara系统包含多个发射器,结合后可产生一种效果。

例如制作烟花效果,可能需要多次爆发。为此需创建多个发射器,并放置在名为Firework的Niagara系统中。 在Niagara系统编辑器中,可在系统中修改或覆盖发射器或模块内的任何内容。系统编辑器中的 时间轴(Timeline) 面板将显示系统包含的发射器,并可用于管理此类发射器。 发射器编辑器和系统编辑器大致相同。

右图是首次创建Niagara发射器或Niagara系统时将显示对话框,包含选择要创建发射器或系统种类的数个选项。其中一项用于选择模板。此类模板基于部分常用基本效果,并已在堆栈中放入各种模块。 可更改模板中的参数。可添加、修改或删除模块。在系统模板中,还可添加、修改或删除发射器。模板只是用来启发创造性,并提供部分即刻使用的东西。

  • 利用系统模板新建系统(Create a new system from a system template):若选择此选项,即可从显示数种常用效果系统的模板列表中选择。与发射器模板相同,此列表可以由美术主管或创意总监策划。若刚接触UE4,此选项可帮助你了解Niagara中构建FX系统的方式。
  • 利用选定发射器集新建系统(Create a new system from a set of selected emitters):若选择此选项,搜索下方将显示可用发射器列表。选择新系统中要包括的发射器,并点击绿色 加号 (+)按钮进行添加。若已创建系统所需全部发射器,则使用此选项。
  • 在项目内容中复制现有系统(Copy an existing system from your project content):若选择此选项,搜索栏下方将显示现有系统列表。选择之一进行复制。
  • 创建不含发射器的空白系统(Create an empty system with no emitters:若选择此选项,系统将完全为空。若要新建与其他系统完全不同的系统,则使用此选项。

Niagara emitter

Generated
Generated

Niagara发射器包含模块。其用途单一,但可重复使用。Niagara发射器的一大独特之处在于,可使用模块堆栈创建模拟,并在同一发射器中以多种方式进行渲染。继续以烟花效果为例,可创建一个发射器,其中包含用于火花的sprite渲染器,和用于火花之后流光效果的条带渲染器。

  • 利用发射器模板新建发射器(Create a new emitter from an emitter template):若选择此选项,即可从显示数种常用效果的模板列表中选择。在大型开发工作室中,美术主管或创意总监可以策划模板列表,确保将公司的最佳实例烘焙到模板中。此类模板对UE4的新手而言同样是良好起点。
  • 在项目内容中复制现有发射器(Copy an existing emitter from your project content):若选择此选项,可将已创建发射器的副本新建为发射器。此选项适用于创建多个类似发射器。在搜索栏中输入要复制的发射器命名,然后在结果列表中选择。
  • 继承项目内容中的现有发射器(Inherit from an existing emitter in your project content):若选择此选项,可新建继承现有发射器属性的发射器。此选项将使新发射器成为选定现有发射器的子项。此选项适用于创建多个具有特定共同属性的发射器。可修改父发射器,所有子发射器将反应此类修改。
  • 创建不含模块或渲染器的空白发射器(高级)(Create an empty emitter with no modules or renderers (Advanced)):若选择此选项,新发射器将不含模块、项目或渲染器。此选项适用于从头构建发射器。但使用此选项需对Niagara系统的工作原理有所了解,并对发射器需具备的功能有清晰认识。

Niagara Modules

Niagara模块是Niagara VFX的基础层级。模块等同于Cascade的行为。模块将与一般数据通信、封装行为,与其他模块堆栈,并写入函数。 使用高级着色语言(HLSL)编译模块,但可用节点在图表中进行可视化编译。可创建函数,包括输入,或写入到值或参数图。甚至可使用图表中的 CustomHLSL 节点写入HLSL内联代码。 欲了解Niagara发射器中可用默认模块的详情,参见Niagara系统和发射器模块参考 。

Niagara中的粒子模拟作为 堆栈 运行。模拟从堆栈顶部流向底部,依次执行名为 模块 的可编程代码块。重要的是,每个模块都被指定到决定其执行时间的 分组

Generated
  • TArray<FNiagaraEventScriptProperties> EventHandlerScriptProps;
  • TArray<UNiagaraRendererProperties*> RendererProperties;
  • FNiagaraEmitterScriptProperties UpdateScriptProps;
  • FNiagaraEmitterScriptProperties UpdateScriptProps;
  • FNiagaraEmitterScriptProperties SpawnScriptProps;
  • FNiagaraEmitterScriptProperties EmitterSpawnScriptProps;
  • FNiagaraEmitterScriptProperties EmitterUpdateScriptProps;

发射器生成

发射器启动时,将运行 发射器生成。此操作与蓝图的构造脚本类似,期间将执行可在后续脚本中使用的一次性设置。其无法引用单个粒子,但可用于设置发射器变量、运行发射器模块,并设置将在粒子脚本中使用的变量。

发射器更新

在发射器活跃的每帧中,都会运行 发射器更新 部分。用户可决定生成的的粒子数量、计算粒子更新脚本中使用的常量值,和在此执行发射器的逐帧“tick”逻辑。在此部分中设置 发射器生命周期 模块十分重要,以确保执行各发射器的所有生命周期逻辑。此操作可使系统正确关闭。

粒子生成

每次生成粒子时将运行一次 粒子生成 部分。用户可使用此部分设置粒子的初始状态。如发射器未设为使用“内插生成”,则该部分的输出将定义其渲染首帧的粒子状态。如发生“内插生成”,则将从上一帧开始的时间范围内均匀分布粒子。如未发生“内插产生”,将出现即时爆发,并运行各粒子的更新脚本,运行时间为该帧创建开始计算的小数部分。利用此操作用户可获得平滑轨迹,还可用于允许粒子更新脚本定义其渲染首帧的粒子状态。如需要随机性来区分粒子,在生成脚本中选择随机值并保存该值以在随后更新“tick”中使用。

粒子更新

粒子更新 部分控制单个粒子生命周期中的行为。用户可对此部分中的物理模拟属性、渲染属性等进行更改。如用户想将数据广播到其他发射器,则发射事件的模块可在该部分中发生。将“更新寿命”模块设在此部分中十分重要,以确保所有粒子可继续存活,直到生命周期终结后销毁为止。

添加事件处理器

添加事件处理器 部分决定该发射器对碰撞或其他发射器中传入的事件的响应方式。

渲染

渲染 部分包含以下一个或多个模块:

  • Niagara光源渲染器属性:此模块包含“光源渲染”和“排序顺序”设置。
  • Niagara网格体渲染器属性:此模块包含“网格体渲染”、“排序”、“绑定”和“排序顺序”设置。
  • Niagara条带渲染器属性:此模块包含“条带渲染”和“排序顺序”设置。
  • Niagara Sprite渲染器属性:此模块包含“Sprite渲染”、“排序”、“子UV”“绑定”和“排序顺序”设置。

参考和参数类型

参数 是Niagara模拟中的数据的抽象表现。将参数 类型 分配到参数,以定义参数代表的数据。共有四种参数:

  • 基元(Primitive):此类参数定义不同精度和通道宽度的数值数据。
  • 列举(Enum):此类参数定义一组固定的指定值,并取其中一个指定值。
  • 结构体(Struct):此类参数定义一组基元和列举类型的组合。
  • 数据接口(Data Interfaces):此类参数定义从外部数据源中提供数据的函数。此可为UE4其他部分中的数据,或外部应用程序中的数据。

点击 加号 按钮(+)并选择 新建参数(Create New Parameter),可向发射器添加自定义参数模块。也可点击 加号 按钮(+)并选择 设置特定参数(Set Specific Parameter),向发射器添加自定义 设置变量(Set Variable) 模块。

Niagara VFX工作流程

创建发射器

创建发射器时,将模块放入堆栈,此类模块将定义效果外观、采取操作等。在 发射器生成 组中,放置定义首次生成发射器时发生的情况的模块。在 发射器更新 组中,放置随时间影响发射器的模块。在 粒子生成 组中,放置定义发射器中生成粒子时将发生的情况的模块。在 粒子更新 组中,放置随时间影响粒子的模块。在 事件处理器 组中,可再一个或多个定义特定数据的发射器中创建生成事件,然后就可以在触发对该生成事件的反应行为的其他发射器中创建聆听事件。

创建系统

将各发射器组成一个系统,此系统将显示想要创建的整体视觉效果。目前存在系统的特定模块,编辑系统而非发射器时,编辑器的部分元素将出现不同行为。在Niagara编辑器中编辑系统时,可更改或覆盖系统包含发射器中的模块。还可利用Niagara编辑器的时间轴(Timeline)面板管理包含发射器的计时。

创建模块

Generated

模块函数流程

  • 模块将累积到临时命名空间,然后可将更多模块堆栈在一起。只要对同一属性贡献,模块便可正确堆栈和累积。
  • 写入模块时可用以下函数:
    • 布尔运算符
    • 数学表达式
    • 三角函数表达式
    • 自定义函数
    • 使样板函数易用的节点
  • 创建模块后,任何人均可使用。
  • 模块都使用HLSL。逻辑流程如下:
Generated

Niagara范例

继承

  • 如使用扁平层级,则无法有效定位和使用库中现有资源,将诱使用户重新创建此类资源。重复工作不仅效率低下,还会增加开销。
  • 层级继承将提高可发现性,还可高效重复使用现有资源。
  • 系统中的子发射器可覆盖继承内容。
  • 可添加模块,或者模块也可恢复到父值。
  • 以上内容同样适用于生成、生命周期、循环、突发等发射器级别行为。

动态输入

  • 动态输入的构建方式与模块的相同。
  • 动态输入可向用户提供无限继承扩展能力。
  • 动态输入作用于值类型,而非参数类型。
  • 图表逻辑和面向用户的值可驱动任何值。
  • 动态输入与创建模块具有几乎类似的功能,但前者无需实际新建模块即可放入堆栈。
  • 可以通过使用并链接动态输入,以多种方式修改及自定义模块;这可以防止模块膨胀并提升性能。

Micro表达式

  • 内联值均可转换为HLSL表达式片段。
  • 用户可访问粒子、发射器或系统中的变量以及HLSL或VM函数。
  • 此十分适用于无需新模块的一次性功能。

事件

  • 事件是元素(如粒子、发射器和系统)间的一种通信方式。
  • 事件可为任何类型的数据,打包为负载(如结构体)并发送。之后其他项目可聆听此事件并进行处理。
  • 可用选项:
    • 利用Particle.ID直接在粒子上运行事件。
    • 在系统中所有粒子上运行事件。
    • 设置生成粒子以响应事件,并对此类粒子进行处理。
  • 事件是图表中的特殊节点(结构体)。使用事件节点的方式:
    • 命名事件。
    • 向其添加需要的数据。
    • 将事件处理器添加到发射器堆栈中。
    • 设置事件处理器的选项。
  • 具有事件的单独执行堆栈。
    • 可将细致图表逻辑放入事件处理器。
    • 可设置带有复杂逻辑的完整粒子系统,之后事件触发时将发生单独行为集

数据接口

  • 具有可扩展系统,以便访问任意数据。
  • 任意数据包括网格体数据、音频、外部DDC信息、代码对象和文本容器。
  • 数据接口可编写为插件,以便之后获得更好可扩展性。
  • 用户可利用骨骼网格体数据接口获取与骨骼网格体有关的数据。

Houdini

  • 使用Houdini,可计算分割点、生成位置、撞击位置、撞击速度、法线等。
  • 之后可将Houdini中的数据导出为常见容器格式(CSV)。
  • 可在UE4项目中将此CSV导入Niagara。