海量粒子特效解决方案:VEG
Unity 官方除了一个 GPU 粒子特效的解决方案:Visual Effect Graph,即 VEG,能支持百万级粒子特效的播放。在性能要求高的使用场景中,这个解决方案就能完美解决原本 Particle System 性能低下的问题。关于 VEG 的基本使用方法参考官方文档和 GitHub 上的示例工程即可,这里不做介绍。这里主要介绍程序如何通过代码调用实现批量生成粒子特效的实现方法。
-
VEG官方文档:https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@17.0/manual/index.html
-
VEG示例工程:https://github.com/Unity-Technologies/VisualEffectGraph-Samples
首先,在 VEG 里面是可以同时存在多个粒子系统的。如下图所示:我这里做的 VEG 特效就是同时包含2个粒子。
由于我们是要在游戏中批量生成粒子特效(几百上千个),所以肯定不能说每个粒子特效都生成一个实例。在 VEG 中,我们可以用 GraphicsBuffer 实现。
在 VEG 的属性面板中增加一个GraphicsBuffer,这里将其命名为 PositionBuffer,表示每个特效所在的位置。
然后再增加一个 int 属性,表示当前需要渲染多少个粒子,将其命名为 SpawnCount。
还需要创建2个 Vector3 的属性,BoundCenter和BoundSize,表示这个粒子特效的渲染范围是多大。如果相机没有覆盖粒子特效的范围,则VEG会自动裁剪。
最后属性面板如下图所示:
之后在编辑画布中,就可以创建对应节点(通过右键创建节点或者直接从属性窗口拖到画布中)。
SpawnCount 在粒子特效生成时就赋值,告知 VEG 当前需要绘制多少个粒子。
在粒子初始化时,需要设置粒子特效的 Bounds 信息,如下图所示:
注意,这里的 Capacity 也要设置为合适的数量。这里是按照单个粒子的数量计算的容量,例如一个特效,同时发生10个粒子,最多生成100个特效,这里就要填1000+。否则,超过这个数量的粒子是不会发射出来的。
之后就是 PositionBuffer 的使用了,如下图所示:
这里的节点设置的意思是通过当前粒子特效的 SpawnIndex 在 PositionBuffer 中取得对应下标的值(Vector3),之后就能直接将其赋值给对应粒子的 Position。
接下来就是代码调用,这里就和传统的 GPU 直接绘制的操作差不多了:
private GraphicsBuffer m_Buffers;
public VisualEffect effect;public void SetEffectsData(NativeArray<PositionData> value, int count, Vector3 center, Vector3 size)
{m_Buffers.SetData(value);// 填充数据后绑定到 VEGeffect.SetInt(“SpawnCount”, count);effect.SetVector3(“BoundsCenter”, center);effect.SetVector3(“BoundsSize”, size);effect.SetGraphicsBuffer(“PositionBuffer”, m_Buffers);
}
接下来就是做下测试:


可以说即便是海量的粒子特效,这套系统也不会有性能压力。同时,在表现效果上,这套粒子系统也能支持绝大多数特效(参考Unity官方的示例工程),可以说是一个完美的解决方案了。美中不足的是,使用 VEG 需要美术特效制作人员和相关程序重新学习新技术,这确实就是个不小的难点了。