MENU 导航菜单

Visual Effect Graph初级教程 | 篝火效果的实现

产品中心 > Unity 3D

本文通过对一个写实类篝火效果制作的讲解,带大家一步步完成四个 Visual Effect Graph 粒子系统,并将它们组合在一起完成最终的篝火效果。


我们将一起学习以下知识点:
图片 Context(上下文)和不同上下文的作用:Spawn,Initialize Particle,Update Particle 和 Out Particle 上下文
图片 Block(功能块),并学习了一些常用 Block 的用法,比如 Turbulence,Force,Flipbook Player,Set Velocity Random 等
图片 如何使用本地变量和全局变量

图片 如何通过 Rendering Debugger 窗口检查性能问题,并解决 Overdraw 性能问题


此教程为 Visual Effect Graph 系列教程的第一篇,之后我会陆续推出更多 Visual Effect Graph 特效相关的案例教程。


创建Visual Effect Graph资源(Asset)


注:本教程使用了Unity资源商店的一个场景资源(完成此教程无需购买此资源)

 

图片

Castle Valley Collection 1 (HDRP)

https://assetstore.unity.com/packages/3d/environments/castle-valley-collection-1-hdrp-165031


如下图所示,在 Project 窗口创建一个 Visual Effect Graph 资源:右键打开菜单中选择 Create> Visual Effects > Visual Effect Graph 生成资源。并将它拖动到场景中。


图片


双击打开新建的特效资源文件。Visual Effect Graph 已经在当前的特效资源文件中预设了一个默认的粒子系统,我们先看一下这个默认粒子系统是由哪些部分组成的。


01  默认的模板粒子系统:


当我们新建一个 Visual Effect Graph 资源时,Unity 会使用一个模板为我们创建一个默认的粒子系统。这里面会包含如下图所示的节点图。


整个粒子系统的执行方向是从上往下的,也就是从 Spawn(生成)上下文(Context)创造粒子开始执行,到 Initialize Particle(初始化粒子)上下文,然后是 Update Particle(更新粒子)上下文,最后到执行 Output Particle Quad(输出四边形粒子用于显示最终粒子效果)上下文。我们会在后面了解到各个上下文的作用。


另一个需要说明的是:在一个 Visual Effect Graph 中至少会存在一个粒子系统,但是大多数情况下会存在多个粒子系统。假设我们要制作一个篝火的效果,它可能会存在:烟雾粒子系统,火焰粒子系统,用于表现火焰中随机出现的小火星粒子系统,还有比如因为火焰的高温导致空气扭曲的粒子系统等。


图片


我们可以把虚线框中的 System 字样通过鼠标左键双击修改文字,比如改成如下图所示的“My System”。这可以在多个粒子系统并存的情况下起到区分的作用


图片


02  Spawn上下文(Context)


图片


我们使用上下文(Context)来定义整个特效中某一个阶段的计算阶段,比如生成新的粒子,更新现有粒子的状态等。


因为一个 Visual Effect Graph 就是由一个或者多个粒子系统组成的系统,所以它的最基本功能就是喷射粒子。不管是一次性喷出来,还是随着时间流逝按照一定速度喷射出来,本质上我们是要通过控制这些粒子来实现各种效果。因此,作为一个特效的起始点,Spawn 这个上下文(如上图所示)的工作就是定义粒子喷射的形式(一次性喷还是在几个循环里面喷完),以及喷射的速度,每次喷射前需要的延迟(Delay)等属性,然后按照这些设置来生成粒子。


在 Spawn 上下文的最后,Visual Effect Graph 通过 Spawn Event 连接到下一个上下文 Initialize Particle。


03  Initialize Particle(初始化粒子)上下文


初始化粒子上下文的作用是初始化在 Spawn 上下文中生成的粒子上的各项属性。它的的基本作用(如图所示)如下:


通过 Capacity(容量)控制粒子的总数。如图所示,这里的数值 32 是此粒子系统能够生成的最大粒子总数。即使你在 Spawn 中设置了更高的数值,最终的粒子总数以这里为准。


Bounds(边界框):在这里可以控制当前粒子以什么位置为中心(Center),以及边界框的大小(Size)。


请注意:图中的 Capacity 和 Bounds 参数是无法删除的,但是下面的 Set Velocity Random(设置随机速度)和 Set Lifetime Random(设置随机生命值)代码块(我们称为Block),是可以被删除的。


我们可以为上下文(Context)添加各种适用的代码块(Block),像堆积木一样堆起来。包含这些代码块的上下文会按照从上到下的顺序执行这些代码块,比如下图中会先执行 Set Velocity Random 代码块为每个粒子指定一个随机的速度值,然后再通过 Set Lifetime Random 为每个粒子指定一个随机的生命值。


图片


04  UpdateParticle(更新粒子)上下文


如下图所示,在此上下文中我们加入了一个名为 Turbulence(湍流)的代码块,它可以生成一个噪声场,用于控制每个粒子的运动速度。通过这个湍流代码块,我们可以为一堆粒子添加看似自然的湍流运动。


在更新粒子上下文中,Visual Effect Graph 每帧都会在所有粒子上应用包含在当前上下文中的所有代码块,并按照从上到下的顺序应用这些代码块。除了动态改变每个粒子的位置信息,我们也可以改变颜色,生命值等属性。


图片


05  Output Particle Quad 上下文


粒子系统最后一个上下文的作用是进行粒子的输出显示。如果我们把 Update Particle 上下文和 Output Particle Quad 上下文之间的链接断开,可以看到场景中的粒子将不再被渲染。


与初始化上下文一样,负责输出显示的上下文也有一部分固定的属性设置,比如 Color Mapping,UvMode 等。我们也可以添加如下图所示的 Orient: Face Camera Plane 代码块,Set Size over Life 代码块和 Set Color over Life 代码块。我们将会在后面的实例讲解中用到这些代码块。


图片


除了在默认的模板粒子系统中使用的 Output Particle Quad 上下文,还有很多其他与 Output 有关的上下文,它们可用于显示不同类型的粒子效果,比如我们可以使用 Output Particle Lit Sphere 把每个粒子渲染成一个 3D 圆球(如图所示),而且这些圆球粒子会受到场景中光照的影响。


图片

创造烟雾粒子系统


以下我们来了解如何制作烟雾粒子效果。


首先我们要在 Output 上下文中选择一个纹理作为 Main Texture,这里选择 Simple Smoke 纹理。Simple Smoke 纹理包含在 Visual Effect Graph 包提供的示例纹理库中。具体设置如下图所示。

 

图片


不过如图所示,目前看上去并不像烟雾,而是一团团棉絮样的东西。


图片


因为烟雾上升的路径是较为垂直向上的,所以要改变目前随机飘散的棉絮团状的烟雾效果,我们要在初始化(Initialize)上下文中改变烟雾的初始移动速度。也就是要在初始化上下文的 Set Velocity Random(设置粒子随机速度)块中进行设置。将粒子随即速度值如下图所示进行设置:

 

图片


因为我们选择的是 Per-component(每个组件),所以 X,Y,Z 三个轴向都会通过 A 和 B 的值来单独计算一个随机数值。比如X轴的速度会用 -0.1 和 0.1 来取一个随机值,Y 轴的速度会用 0.8 和 1 来取一个随机值,Z轴的速度则会用 -0.1 和 0.2 来取一个随机值。这三个轴的随机值一起控制初始化阶段每个粒子的初始移动速度。


值得注意的是:Set Velocity Random 这个功能块其实是 Set Attribute(设置属性)中的一个属性控制块(用于控制粒子移动速度)。如果你在 Visual Effect Graph 里面搜索,其实找不到 Set Velocity Random 这个块,你只能在文档的 Node Library > Block > Attribute 层级下找到 Set 这个词条(如下图所示)。

 

图片

 

如果你选中 Set Velocity Random 这个块,可以在 Inspector 窗口中调整更多的参数:


图片


展开下图中的 Attribute(属性)选择框,可以看到除了 velocity 外,我们还可以选择一长串其他的参数,比如 color(颜色),alpha(透明值),position(位置)等。如果你在这里为 Attribute 选择 position,那么 Visual Effect Graph 中原先显示为 Set Velocity Random 块就会改名为 Set Position Random,块中的参数也会发生相应改变。


图片


目前烟雾的上升距离有限,这时因为目前每个粒子的生命值(Lifetime)在 1 到 3 秒之间,到达生命值以后粒子就消失了。


我们可以通过增大生命值来达到让粒子活的更长久的目的,从而让烟雾升的更高。如下图所示,将 Set Lifetime Random(设置随机生命值)的参数 A 设置为 6,B 设置为 8,也就是初始化时每个粒子的生命值为 6 秒到 8 秒之间的一个数值,最少活 6 秒,最大活 8 秒。


点击键盘上的 F5 键可以刷新特效的运行,让它重新开始运行。

 

图片

 

不过增大了生命值之后会出现如下图所示的地面和上升粒子之间的空白区域。这时因为当粒子的生命值增大以后,粒子的总数很快达到了在 Capacity 参数中设置的上限,在老的粒子还未死亡的前提是无法生成新粒子的,所以就导致了粒子和地面之间空白区域的出现。


图片

为了解决上述隔空的问题,我们要降低粒子的生成速度和 Initialize Particle 初始化粒子上下文中的 Capacity(容量)数值。

我们把 Constant Spawn Rate 中的 Rate 数值改为 4,如图所示:

 

图片

 

 Capacity 数值改为 32,如图所示:

 

图片


修改完成以后我们可以看到烟雾和地面之间的空白区域问题解决了,因为现在的设置会每秒产生 4 个粒子,在粒子的最大生命值(8秒)结束之前,老的一波粒子会消失,新的一波粒子得以生成。


不过目前烟雾粒子形状较小,所以我们接下去要调整烟雾粒子的大小,让这些粒子看上去像真正的烟雾。


我们可以在 Output Particle Quad(输出方形粒子)上下文中调整烟雾粒子大小,具体步骤如图所示:


图片


图片 在 Set Size over Life(随生命值设置粒子大小)块中,打开 Size 相关的曲线图。
图片 在曲线图底部选择第二个曲线,这一曲线会以线性方式增加/减少数值。
图片 拖动设置绿色曲线最左边点的数值为 0.5。

图片 拖动设置绿色曲线最右边点的数值为 1.5。


曲线图中我们可以看到绿色曲线的四周有四条蓝色直线,你可以通过鼠标左键框选绿线得到这四条蓝色直线。然后你就可以通过选中并移动蓝色直线来调整绿色曲线起始点和结束点的相关数值。


调整粒子大小以后的效果如图所示:

 

图片

 

上述步骤让我们的烟雾看上去更真实一些了,但是目前的问题也很明显:这个烟雾并不真实。原因是我们给每一个烟雾粒子使用的都是同一张烟雾纹理,所以一团团的烟雾看上去很重复。为了解决这个重复的问题,我们接下去要用到 Flipbook(动画翻页书)功能。


首先我们要把现在用的 Simple Smoke 纹理替换成一个纹理图集 Wispy Smoke03b_8x8(如下图所示)。这个纹理图集包含了一系列烟雾效果关键帧,Flipbook 功能可以拿这个纹理图集逐帧播放动画,让每一个烟雾粒子动起来。


图片


不过如图,现在的效果显然不是我们想要的:


图片


我们要设置正确的 UV 模式,以及根据纹理图集的行和列数量来设置 Flipbook 的相关参数。请按照下图所示设置相关参数。

 

图片 Uv Mode(UV模式)设置成 Flipbook Blend(动画翻页书混合模式)。

图片 Flip Book Size(动画翻页书大小)中按照纹理图集的行和列 8x8 来设置 x 和 y 数值。

 

这时可以看到之前的显示问题消失了。


图片



下一产品:Unity宣布正式收购《指环王》《阿凡达》视效团队Weta Digital