我们曾发布过关于粒子系统中使用不同曲线模型的性能的文章。这次我们将研究一下粒子系统的剔除。
只有在系统行为可以被预测时才能使用剔除。 开启一个模块不仅会影响这个模块的开销,而且可能由于从程序化的模块切换为非程序化的模式而影响到整个系统的开销。 通过脚本改变的值将不会被剔除。 使用自定义的剔除可以提供性能上的优势,但只有开发人员才能判断是否适合。需要考虑特效类型,玩家是否会注意到在它们不可见时动画停止了,以及是否可以预测影响的区域?


程序化模式
每个粒子系统都有两种执行模式,程序化和非程序化。

程序化模式下可以知道粒子系统在任意时间的状态(无论过去还是将来),但是非程序化系统中这些都是不可预测的。这意味着可以将程序化系统在任何时刻快进(或回退)到任意位置。

当粒子系统处于所有相机的范围之外时,它将被剔除。这种情况出现时,程序化系统会停止更新。当粒子系统重新可见时它将快进到新的时刻。非程序化的系统则无法这样做,即使是不可见时它也必须持续更新系统,因为它是不可预测的。

举个例子,下面的系统是可预测的。它位于本地坐标系中,所以粒子系统的位移无关紧要,粒子系统不受例如碰撞、触发器或者风之类的外力影响。这意味着可以计算出粒子系统生存周期的边界(边框),并且可以安全地将其在不可见的时候剔除。

104010jrmms7zdzwgmrvqd.png
下面是一些打破程序化模式的一些情况。

104014bq3w73flsbuqbyff.png
*一个曲线如果多于8个分段就无法支持程序化模式。如果曲线不是从0.0开始,或者不是以1.0结束,则一个分段指一串键值再加一个键值。

在播放器中使程序化模式无效

程序化模式基于确切知道系统在不受外部影响的情况下在任意时刻的状态。如果通过脚本或播放模式下在编辑器中改变了某个值,那么之前的假设将不成立,程序化模式就会失效。也就是说即使一个系统已经使用了程序化安全设置,程序化模式也不可能再有效,粒子系统也不会被剔除。

通过脚本改变值或发射粒子都会使得程序化模式无效,这点可以通过检查场景中系统的边框来判断。如果边框持续变化,那么程序化模式就不再有效。

某些时候可以通过使用粒子系统的内置功能而非脚本来改变属性,以避免程序化模式失效。

在已停止的粒子系统上调用播放会重置系统并使得程序化模式重新生效。

性能示例
程序化系统和非程序化系统有着明显的性能差异。当粒子系统不在屏幕范围内时尤为显著。在一个包含了120个默认系统的场景中,每个粒子系统产生1000个粒子,下面显示的是本地坐标系(程序化)和世界坐标系(非程序化)之间的的性能差异。左侧显示的是没发生剔除时,右侧是发生剔除时。

104011vr5q0qhz3h46x2fh.png
蓝色区域表示粒子系统的消耗

自定义剔除
下图显示的是简单的2D雨效果,它使用了碰撞模块(打破了程序化模式)。

使用了碰撞模块后的系统无法预测。碰撞体可能发生移动,或者它们自身的属性也可能随时间变化。这意味着无法预测粒子未来所在的位置,因此粒子系统在屏幕之外时也需要持续更新。

104012t9ggmfzfkhy6fxhj.png
自定义的边界球体包括了雨效果的影响区域。

104012nz8f0o6e6fop5p6b.png
100个雨系统的性能

104014gba55bzamv1gdgx8.gif
自定义剔除并非适用于所有特效。左侧的系统使用了自定剔除,可以发现与右侧的无剔除版本并不同步。这也说明了为什么非程序化系统在不可见时也必须要持续更新。

原文链接:#unitytips: ParticleSystem Performance – Culling
原文作者:KARL JONES
感谢Unity官方翻译组成员“fubb”对本文翻译所做的贡献。
转载请注明来源:Unity官方中文社区 (forum.china.unity3d.com)。请勿私自更改任何版权说明信息。 Unity, 粒子, 粒子系统, 性能锐亚教育

锐亚教育 锐亚科技 unity unity教程