[跳坑宝典系列]WWISE性能优化的若干建议
WWISE作为中间件,提供了很多声音设计方面的强大支持,但在使用这些功能时,如果忽略了所对应平台性能方面的限制,那么很多设计将失去可操作性,让CPU满负荷运作,内存被大量占用。
下面结合本人实际工作中遇到的问题,跳了坑再爬上来的实际体验,分享一些能优化性能的设计,并感谢Johnxu、Cloudxiao以及WWISE公司在优化环节给予的支持。
首先对于性能来说,主要就是CPU占用,和内存消耗。针对这两方面,影响CPU占用的主要是插件使用、同时发生数、样本的压缩率——也就是需要实时运算、解码的内容的量;影响内存的,则是支持当前游戏场景,需要被加载进内存的Bank的大小。
接着就是在实际设计中如何优化这些内容的具体设计了。
一、针对插件使用量,Gain、SideChain等对于音量起作用的不会是CPU暴增的原因,而Reverb类的使用则是主要原因,首先这类效果器标准做法是在aux-send上使用。其次在效果器的编辑中Tone是否勾选, Reverb.Quality,和Reverb.Density 参数设多少也是影响性能的因素——如勾选Tone,其余参数到最高,可比最低配置占用CPU多8倍左右。
而对于WWISE中提供的Reverb种类,matrix reverb效果器,虽然品质上略逊于RoomVerb,但有10%性能上的提升。另外Pre-render的使用也能大幅度降低CPU消耗。
综上,Reverb类效果器慎用,要用注意使用数量、选择种类和调节相应参数。
二、同时最大发生数,在安卓Note 2红米机型上测试,bypass所有效果器,最大发音数除去音乐以外设为6,CPU占用为30%(游戏总消耗里的百分比,并不是单独占CPU的百分比),是在一般项目组可以接受的范围,因此合理安排最大发音数必须得到重视。
1、举个实例。枪战游戏,原本设计为每发子弹有武器声音、子弹出膛声音、子弹运行声音等多个环节构成,由于性能的考虑;最终的方案是,对于连续匀速发声的枪械则改为开枪触发loop(loop做随机),停止触发stop事件的方式来做。当然这只是我采用的方案,可能还有很多更佳方案。
2、合理设立优先级,并正确设置虚拟声道行为。优先级设置无可争议,需要根据具体游戏设计来安排,而某些循环类型且并不明显的音效,可以试下将最大发音数达到上限时,让其进入虚拟声道,当最大发音数小于上限时,让loop回来,回来时的不同规则(from beginning、from elapsed time、resume)对性能也有不同的消耗。
三、针对插件和最大发音数,可以根据不同平台设置不同的档次,通过BUS上的Sound Instance Limit(最大发音数)和bypass相应效果器来搭配。Unity中有对应的SoundEngineQuality作为Parameter来映射。
四、解码音频会占用很多CPU,常用的小样本,可用ADPCM来减少压力,而常用的OGG格式参数的设置,质量越低,解码消耗越低。而在2015的WWISE版本里,OGG的不同质量的设置性能表现上也将提高。
五、unity可以设置相应的内存大小给WWISE,当profiler里出现Sound Starvation报错时,可以相关程序员商量提高分配的内存额度。而对于游戏中Bank的合理划分可以减少内存的占用。例如每个主角(主角的语音、技能等样本)一个Bank,比所有主角的技能一个Bank、所有主角的语音一个Bank要合理。因为后者会加载进一些暂时不需要的其他主角的样本。
六、大的样本使用Stream的方式加载,当然为了解决延迟问题,可以设置一些提前加载进内存的部分。
在音效设计时,希望能多用真机测性能,或者能根据PC和相关测试机性能的映射关系做出判断。
在继续使用WWISE的过程中,应该还有其他的有助于提高性能的方法可以总结,以上只是抛砖引玉,作为前车之鉴,希望同事们可以避免这些问题。