这几天在做特效系统的优化,稍有些心得,分享一下。
首先要讨论的是优化层次,然后再说说优化策略。
游戏这个东西是程序美术策划共同努力工作的结果,所以优化再更宏观的角度来看不只是程序的问题。在具体工作中经常会出现,美术作了一个特别牛鼻的特效,效果及其绚丽,但是他却消耗了大量的资源,导致游戏性能低下。这是很常见的问题,因为美术他不管程序怎么处理,他只追求效果,而且美术的特点是很感性,对于一些具体技术细节不是那么靠就,比如说粒子发射量,很多情况下用不着那么多的粒子就可以达到了效果,美术却不注意。从这点上来说即便程序什么都不优化,只要美术制作的时候稍加注意即可。而且在有些情况下适当损失效果而换来的是性能的极大提升这也是值得的。再说一下策划,对优化的贡献。很多情况下只要策划变换一下思路,同样可以制作出好玩但是实现容易的游戏,我就不信某些策划说非要这样才好玩的话,殊不知就这么一个拍脑袋沟皮想法要花去多少人工,很多情况下程序或者美术一些不能解决的问题或者短期不能解决的问题都可以让策划在设计上避免掉,同时也不会损失什么游戏性,毕竟实现游戏性的设计千千万,干吗非要非找最难以实现的那一种。这是各个部门协调配合的优化,这种优化其实是最有效的。程序费劲巴拉的搞一个月,也许比不过美术稍微调整一下参数,更比不上策划适当修改一下设计来的好。
接下来就说点实际的优化了,程序上的。粒子系统这块大致的优化可以从以下几个方面着手考虑。
1. 看不到的特效是否需要更新。
这个问题要分开来看,有些特效可以在看不到的时候不更新,比如场景里那些循环播放的特效。而有些特效即便看不到也许要更新比如爆炸特效。解决这个问题需要在特效系统上增加一个bool变量用于标示是否需要持续更新,在美术制作的时候设定。这样可以有效地降低特效更新次数。
2. 粒子效果是否需要根据运行时的帧率自动调节。
答案是肯定的,肯定需要在帧率不足的时候引擎也好客户端也好,自动设定特效显示级别来弥补性能损失。具体可以这样实现,对特效系统各个元素增加显示级别参数,高显示级别可以显示地显示级别,但反之不可以。美术在制作的时候要清楚地设定特效中的元素那些是高显示级别的那些是低显示级别。特效模块内有这么一个控制素有特效显示级别的参数进行全局控制,可以在引擎内部或者客户端监控帧率或者特效模块的耗时,当过高的时候降低引擎特效显示级别,反之则调高。
这样做的好处是所有效果都是美术在编辑器中设定并确认过的。
还有一种不得已的优化办法,就是自动调低粒子发射量,特效系统的粒子是影响性能的基数,调整这个东西可以最直接的影响效率,但是这确实不得已的办法。原因很简单,美术在编机器里面设置使用100个粒子的效果看起来不错,而引擎自动把他调低后的效果也许就不再是美术想要的了,而这一切美术有没有在编辑器里面确认。不过这个岛是可以变相应用于特校级别上。
3. 粒子更新是不是要放在多线程。
如果这个特效仅仅是显示,可以确保设计上的简洁同时不带来更多的问题,把特效更新放在多线程里是可以的,要做好特校的启动和回收就行了。但如果特校是和某些逻辑相关的,在设计上也许会很复杂,这就要具体情况具体分析了,我对这种情况的处理是很慎重的,以保证设计简洁为优先考虑。
4. 如何避免大量粒子重叠时导致的像素填充性能低下的问题。
特校里面几乎所有的面片都是要scene blend和alpha blend的,当有大量的面片出现,此时像素填充率就成为了主要性能瓶颈。这里提两个优化思路。第一个是使用alpha reject参数,这样可以较早的拒绝掉部分像素,第二就是使用render target,把特校渲染到一个1/4 viewport面积下的纹理上在贴回来,这种办法还有些具体的细节需要仔细考虑。总之就是尽一切可能减少要处理的像素数。
5. gpu粒子
有不少文章提gpu粒子,总的来说这个是用于大部分特校需求,值得尝试。需要在设计上考虑的问题是复杂的特校不只是粒子,或者billbord这样固定形态的东西,如果还可以发射模型,光源或者其它什么,怎么在设计上更加合理简洁,这是需要注意的。
6. 其他通用方法
简单来说就是通常的优化办法,什么尽量一次渲染,尽量少的更改管线状态等等,这些应该讲是必须做到的,总的来说也不是很难做到。