前言、手游优化为什么这么难?
手机性能比pc差很多,而且手机性能参差不齐,低端机占有的比例又比较大,导致很多游戏必须向低端机对齐,很苛刻的优化游戏的性能。
并且,手游端的开发环境还有很多缺陷,例如对Vulkan/openGL ES的支持、访问深度缓冲区,或者创建FrameBuffer等接口在低端机上经常直接不支持。某些接口支持了,但各大厂商的实现却不一样,有不同的效率问题或者限制条件。
再者,即使同是安卓系统,但底层的实现也是不一样的,某个app在这部手机占用内存只有100M,在另外一部手机上却占200多M的情况也经常出现。
一般提到性能优化,主要是针对以下两个问题:
1 游戏闪退
2 游戏卡
一般来说,闪退,可能是dump,内存越界,野指针等。但若是只出现在低端机,那多半是内存爆了。
那么问题来了--
一、我的内存哪儿去了?
内存过大80%是因为项目中的资源没有合理的管理,进行及时的释放。
A.窗体UI
很多项目组在开发游戏,为了UI好看,往往没有使用皮肤,而是整个窗体就是一个图片,又或者窗体都喜欢用大量的背景图。然后,项目组的同学在码功能的同时,又没注意这些资源的管理和释放,一张1024*1024真彩带通道图片在内存中占2M,压成ETC1带多个通道1M,pvrtc的话0.5M,图片的大小再不注意规格的话,逐渐堆积就会泛滥成灾。
确定到问题之后,怎么解决呢?一种投机取巧的方法就是引擎底层做最久未使用策略。但是取巧毕竟是取巧,这样在做在重新打开使用资源较多的窗体,比如商城界面时,会由于重新加载资源较多略卡一两秒。所有,最根本的方法,还是需要项目开发者对窗体相关资源做统筹管理。
二、游戏怎么这么卡?
A.引擎问题
如果游戏出现卡顿掉帧,多半和引擎优化有关。
引擎性能有几个关键指标:
1)渲染帧数
渲染帧数代表一秒钟内实际渲染的帧数量,低于设定的运行帧数时,说明游戏可能存在引擎性能问题,需要进行排查。大致的排查方向,可以根据后面的DP数和多边形数来判断。
2)DP数
DP数量决定了渲染流程中CPU的负担,DP数为1代表CPU调用了一次图形API(在NeoX中一般是OpenGL)进行绘制,调用API的效率并不算特别高,这导致DP数高的情况下会使CPU不堪重负,从而使游戏的渲染帧数下降,所以在游戏制作中需要避免DP数过高的情况发生。第一个DP数代表目前场景视野中总的DP数,modelDP是由于模型产生的DP数,fxdp是由特效产生的DP数,这几个DP数可以提供一些大致的优化方向。另外在这里并没有显示cocosui的DP数,可以使用python脚本cc.Director.getInstance().setDisplayStats来显示。
3)多边形数
多边形数量会影响渲染流程中GPU的负担,3D游戏中的物体由大量三角形面片组成,三角形面片越多,对GPU的压力越大。和DP数类似,QQ号卖号第一个Prim数代表目前场景视野中总的多边形数量,modelprim则代表模型产生的多边形数量。
B.如何优化
1.资源优化
1)首先可以考虑整体降低模型的批数和面数,这种方式可以最直接地降低渲染过程的压力,以达到优化游戏的目的。如果发现有模型的批次和面数太高,可以让美术把模型从3dsmax里重新导出,以降低面数,或者对于不重要的模型考虑直接删除。
其实骨骼的运算是最耗时间的,一般来说有n骨头就做n*4次矩阵运算。这个比较好证明。放一屏幕的角色,然后把骨骼运算一停,只做蒙皮,会发觉游戏的效率瞬间飞起来。另外,限制骨骼运算的帧频也能起到一定优化作用。
2)另外可以和美术交流,看看性能有问题的场景里是否存在大量重复模型的情况,以此来决定是否可以进行精简来降低DP数和面数。
3)项目中如果有大场景,则应当设置LOD Mesh,来降低远景的批数面数,从而避免远景采用高精度渲染而导致性能下降。
4)将一些模型合并为一个大模型可以减少渲染批次,但也可能因为无法遮挡剔除而增加渲染面数。
2.优化shader
Shader的编译需要花费一定的时间,所以这可能会成为渲染性能的瓶颈,使用离线编译Shader的方式可以减小Shader编译的时间开销,从而提高游戏的渲染性能。以NeoX使用的nfx文件来说,在渲染的时候,引擎会先从nfx生成nfxo文件,然后编译成的pipe文件才是真正的Shader文件。如果预先得到nfxo或者pipe,就可以加快游戏的渲染速度。
3.为模型设置不同的level
这一条适用于拥有大场景的游戏。在游戏中一个大物件周围可能有装饰性的小物件,和大物件相比,小物件可以允许在更近的距离使用低精度模型甚至不可见,从而达到在总体观感影响不大的前提下降低渲染模型批次和面数的效果。
4.最终手段,降低分辨率
降低分辨率是效果最明显的提高渲染效率的手段,但是负面影响是会很大程度上影响游戏的画面表现。如果别的手段没有效果,可以尝试降低游戏分辨率,比如从1080P降低到900P就可能带来很大的帧数提升。不过分辨率不能降得太低,不然帧数再高玩家也会被锯齿劝退的。
三、历史问题:手机发热
之前在手机内存普遍只有1G,2G的时候,手机发热也是重点优化的问题,而目前市场3G内存已经是主流,所以发热已经成为历史问题。大部分手机发热问题都是cpu引起的,如物理引擎(这个没辙,控制好量)。还有某个阶段忽然大量发热,往往出现在忽然大量解析xml,json,这两玩意也是照成卡顿的原因之一,csv的效率就比这高许多。
还有一种是游戏引擎自身框架搭建的非常复杂非常设计模式。就如某公司的F1赛车游戏,消息系统十分复杂,游戏开了十几条线程。用工具分析,每条线程占的cpu都差不多,很平均,加起来总体耗费cpu非常高。