粒子系统优化——如何优化你的技能特效

粒子系统优化——如何优化你的技能特效

我们曾在四年前对于Unity的主流模块的性能优化知识点逐一做过讲解,俗称“小白版”。随着这几年引擎本身、硬件设备、制作标准等等的升级,UWA也不断更新优化规则和方法并持续输出给广大开发者。作为"升级版"的性能优化手册,【Unity性能优化系列】将力图以浅显易懂的表达,让更多开发者可以受用。本期就将分享粒子模块相关的知识点。

无论是CPU还是GPU,粒子系统对其的影响面都是不容小觑的。随着项目的重度化和3A化,玩家的口味变挑剔了、游戏玩法复杂度变高了、画面的特效表现变复杂了......所以我们还是更加谨慎地对待粒子系统。

一、粒子系统对于CPU有哪些影响

在UWA报告的粒子模块中,有这些参数是需要我们关注的。
“ParticleSystem.Update”:粒子系统更新的平均CPU耗时;
“ParticleSystem.Draw”:粒子系统每帧提交Draw Call的平均CPU耗时;
“ParticleSystem.ScheduleGeometryJobs”:该函数与粒子系统多线程更新任务的调度有关,一般来说,该值越大表示项目中Playing的粒子系统数量越多。


结合UWA的经验,一般来说主要受到的影响层面如下:

1、粒子系统数量
在UWA的性能简报里,直接搜索(ctrl+f)“粒子系统数量”,会出现这两条检测结果:

(1)粒子系统数量,UWA推荐不超过600(1G机型)。这个数量是指内存中所有的ParticleSystem的总数量,包含正在播放的和处于缓存池中的。

(2)Playing的粒子系统数量,这里指的是正在播放的ParticleSystem组件的数量,这个包含了屏幕内和屏幕外的,我们建议在一帧中出现的数量峰值不超过50(1G机型)。

那如何查看我项目运行过程中到底缓存了哪些粒子系统呢?这些Playing的粒子系统是否合理的呢?这里有个技巧,可以通过报告的【具体资源信息】-【粒子系统】中查看。

如上图,蓝色线条是全部加载进内存的粒子系统,紫色是疑似冗余的,黄色是实际播放的粒子系统数量。跟随游戏运行的生命周期图,可以任选一帧时的截图,尤其是数量较高的部分,再打开【所选帧】模式,可以查看这一帧下所有的ParticleSystem和所有Play的ParticleSystem。

针对上述的2条问题,优化和分析的时候也可针对这两点:

(1)关注粒子系统数量峰值(即蓝色曲线)是否偏高。可选中某一峰值帧查看到底是哪些粒子系统缓存着,是否都合理,是否有过度缓存的现象;

(2)关注Playing数量峰值(即黄色曲线)是否偏高。可选中某一峰值帧查看到底是哪些粒子系统在播放,是否都合理,是否能做些制作上的优化(详见下文)。

2、关于ParticleSystem.Prewarm
在UWA报告的重要性能参数中我们可以留意到有个函数:ParticleSystem.Prewarm,表示当前帧有粒子系统开启了“Prewarm”选项,而开启该选项的粒子系统在场景中实例化或者由Deactive转为active时,会立即执行一次完整的模拟。以“火焰”为例,Prewarm开启时,加载后第一帧即能看到“大火”,而不是从“火苗”开始逐渐变大。

但Prewarm的操作通常都有一定的耗时,建议在可以不用的情况下,将其关闭。


二、粒子系统对GPU端的影响

如果粒子系统问题较为严重,也会影响GPU端的表现。我们也可以结合UWA的真人真机测评报告中的Overdraw数据来排查定位,一般我们建议在中低端设备上不超过5。

结合Overdraw的走势图,配合对应的游戏截图,我们可以排查粒子特效是否面积过大、叠层过多等资源规范的问题。

这里再补充一些常见的优化思路
对于低端设备尽可能降低粒子系统的复杂程度和屏幕覆盖面积,从而降低其渲染方面的开销,提升低端设备的运行流畅性。具体做法如下:

(1)在中低端机型上降低粒子数、同屏粒子数,比如仅显示“关键”粒子特效或自身角色释放的粒子特效等,从而降低Update的CPU开销;

(2)尝试关闭离当前视域体或当前相机较远的粒子系统,离近后再进行开启,从而避免不必要的粒子系统Update的开销;

(3)尽可能降低粒子特效在屏幕中的覆盖面积,覆盖面积越大,层叠数越多,其渲染开销越大。

关于粒子系统的优化,我们曾在UWA DAY 2018中对移动游戏的GPU性能优化中做了些剖析,通过从Fillrate和Shader等几方面出发,结合大量优化过程中的实际案例分析游戏在GPU端的性能瓶颈:https://edu.uwa4d.com/course-intro/1/90


三、如何规范大家的粒子系统

上述是提及的是粒子系统的优化点,但对于大部分的团队来说,都是在项目中期、后期的时候去做。但如果我们对粒子特效的性能压力没有全面的、科学的检测和预判,这个其实是存在风险的。那么我们如何在日常的开发中就通过一些科学的美术规范标准和检测方法,来保障最终在真机上的表现是丝滑流畅的呢?

1、本地资源检测是UWA推出的针对资源规范方面的监控服务,在日常开发过程中可对美术资源如纹理、网格、动画资源、粒子特效等进行逐一性能检测,如下图所示。

粒子特效的检测原理本质上和ParticleEffectProfiler 类似,扫描过程需要在Game View下进行渲染,能把检测结果很直观地展现出来,对开发者是非常友好的。

报告中的检测规则为如下几条,后续还会逐渐完善增加。

(1)特效播放时平均Overdraw率过高
统计每帧参与渲染的像素的平均Overdraw,并取过程中最高的值。该值越大,特效导致GPU压力的可能性也会越高,建议对其进行检查。

(2)特效播放时DrawCall峰值过高
统计每帧的DrawCall数,并取过程中最高的值。该值较高时需要对其进行检查。

(3)特效总贴图内存过大
统计特效中包含的贴图总内存。该值较高时,可能是纹理使用过量,需要对其进行检查。

(4)特效运行时包含的ParticleSystem组件数量过多
统计特效中包含的ParticleSystem组件数。该值较高时,容易导致较高的渲染相关指标,以及较高的序列化耗时等,需要对其进行检查。

(5)特效播放时最大粒子数量过大
统计每帧的粒子数总和,并取过程中最高的值。该值越大,特效的更新开销可能也会越大。

(6)特效总贴图数量过大
统计特效中包含的贴图总数。该值较高时,容易导致较高的渲染相关指标,需要对其进行检查。

(7)开启Collision或Trigger的ParticleSystem
粒子系统建议不要开启Collison或Trigger功能,否则会有较高的物理开销。

2、结合GOT Online的GPU耗时功能,逐一对技能的特效进行监控和优化。
(1)在真机上依次运行技能特效,技能特效的大小和位置,技术团队可以通过相机自行设定。这样在真机上就可以自动测试起来,通过真机上反馈的GPU耗时,就可以马上定位到究竟是哪些技能特效在不同档次的真机上运行起来GPU压力大。

同样的,Draw Call和Triangle也是如此,可以很快发现瓶颈。

还有团队会再进一步,把特效的实例化和Active/Deactive一起检测,这样就能知道哪些技能特效在运行时会带来性能隐患了。

这种流程已经在多个团队中定期执行,反馈效果很好。

除此之外,优秀的项目总有优秀的做法,这里推荐大家参阅《战双帕弥什》团队在UWA DAY上分享的大量粒子模拟方案,https://edu.uwa4d.com/course-intro/1/207

以上就是在优化粒子系统时需要关注的一些问题和对应的方法,如何操作还需要大家结合项目实际情况,同时结合UWA服务可以快速地帮助大家定位到性能瓶颈。

【Unity性能优化系列】

《Unity性能优化系列—渲染模块》
《Unity性能优化系列—加载与资源管理》
《Unity性能优化系列—Lua代码优化》
《Unity性能优化系列 — 资源内存泄漏》
《Unity性能优化 — 动画模块》
《Unity性能优化 — 物理模块》
《Unity性能优化 — UI模块》

  • 数据幻想 发表在 2023年12月08日 回复

    [...]《Unity性能优化系列—渲染模块》 《Unity性能优化系列—加载与资源管理》 《粒子系统优化——如何优化你的技能特效》 《Unity性能优化系列—Lua代码优化》 《Unity性能优化系列 — 资源内存泄漏》 《Unity性能优化 — 动画模块》 《Unity性能优化 — 物理模块》[...]

  • 数据幻想 发表在 2023年08月31日 回复

    [...]《Unity性能优化系列—加载与资源管理》 《粒子系统优化——如何优化你的技能特效》 《Unity性能优化系列—Lua代码优化》 《Unity性能优化系列 — 资源内存泄漏》 《Unity性能优化 — 动画模块》 《Unity性能优化 — 物理模块》 《Unity性能优化 — UI模块》[...]