60帧的丝般顺畅 - QQ飞车手游优化点滴

发表于2018-08-28
评论8 7.7k浏览

作者:申江涛,腾讯互娱客户端工程师
商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。
原文链接:http://wetest.qq.com/lab/view/401.html

WeTest 导读

加入项目组的这段时间主要是承担性能优化这块的工作,同时也会去实现一些场景材质、特效材质以及工具。今天就性能优化这块分享一下个人的经验。


设备等级划分

设备等级划分是一切优化,LOD策略的前提。

最新的iPhoneX A11 GPU性能直逼笔记本的集成显卡,要照顾三四线的小朋友,红米1你也得想办法支持。

画质选项高中低,游戏第一次启动通过设备硬件配置将设备匹配一个默认画质,匹配依据可以按照CPU,GPU,内存等,也可以根据游戏类型做一些特殊处理,每一档选个代表机器,CPU,GPU性能最好心理有数,可以参考下CPU的天梯[1]和GPU的天梯[2],想拿详细数据的自己写测试案例跑。

默认画质匹配最好是基于配置文件的,这样即使上线后发现匹配规则有问题或者设备更新换代了想优化匹配规则也可以动过热更来刷新。

为满足美术大大们的追求,可以在高画质的基础上再划分一个超高配。

设备等级划分之后,就可以做一些LOD策略了,一定要做的就是划分各种特效的级别,其次场景最好也做一下,有条件的UI元素也做一下,对于非核心信息的UI可以在低配机隐藏。

关于Shader LOD的做法有在这个回答[5]里面提到,这里就不赘述了。

优化工具

磨刀不误砍柴工,熟练掌握profile工具绝对是打开优化之门的第一步。

Unity Profile

作为最简单也是最实用的Profiler,即使是不做优化的同学也最好学会如何使用。它能够非常方便地分析出当前的CPU热点。

很多萌新会遇到无法手机连Profiler的问题,如果你也遇到了,请确定下面几个点(假设连Android手机)

1. 手机是开发者模式,且在cmd中输入adb devices能看到自己的设备

2. 配置了Android SDK

3. 编译的是develop build版本

4. Unity当前是Android工程

5. 如果不是在本机构建的,需要在cmd中输入 adb forward tcp:54999 localabstract:Unity-xxxx , xxxx是游戏的包名。

新版本Unity集成了FrameDebugger 和新的内存快照工具,更方便了。

在不开Deep Profile的情况下,看到的消耗比较粗略,很难定位具体的消耗,打开DeepProfile能看到比较深的函数堆栈,但是会有一些消耗,不过在可以接受的范围之内。

移动设备上没法开Deep。

通常遇到的一个问题是手机上的Profile结果和PC上的结果不一致,解决方案如下

一切以移动设备为准,希望详细定位的话可以选择用Profiler.Begin打桩,或者在PC上开Deep Profile找到对应的位置,展开详细的堆栈来定位。

Adreno Profiler

蛮好用的一个Android平台的GPU Profiler,之前很多人用来提取手游的资源,但是已经被高通抛弃了,已停止更新支持一些老的高通GPU的设备,这边确定好用的是红米 Note 1.

如果能找到可以用的设备可以,建议还是可以连一下看看,还是能看到很多东西的:DC数量,绘制顺序,渲染shader,动态修改shader看效果,贴图格式…

这个东西除了看性能还可以用来查一些平台相关的渲染错误。

XCode

首先你要有台Mac以及不算太老的ios设备。

首先要去Apple 申请一个免费的开发者账号,然后从Unity构建一个Xcode工程,连上真机运行。

相对于Adreno, Xcode显得专业很多,功能更加强大,最重要的是,可以看渲染耗时!这对于分析GPU热点非常有帮助。

CPU时间显示一直为0,不知道试Unity的bug还是XCode的Bug。

Instrument可以看函数耗时。

备选

Mali Graphic Debugger:只能用于Mali的GPU, 看上去很厉害,4.X从来没有连接成功过, Unity5.X的集成稍微友好一些,还没有深入研究。

Snapdragon Profiler:很卡,只能用于高端机,只能用于Android 6.0以上的系统,年底出了新版本,还可以。

Unity Frame Debugger:5.X以上才有,很方便,没详细研究。

WeTest - UPA:和Unity官方合作的客户端性能测试工具,无需ROOT和接入SDK,挺方便。

优化流程

如果想在后期轻松一些,美术的规范一定要定好,同时要有配套的资源检测,扫描工具。在定一些大的技术方案之前,各项消耗尽量做到心理有数,如果不确定就做一些实验,数据不会能骗人。

遇到上线前三天发现游戏只有十几帧的,这就只能砍效果了。

程序ic方面主要是对C#的语言底层机制的熟悉程度以及对数据结构的理解,一些明显有性能问题的写法要规避。

项目上线前两周左右就要开始对版本进行一些性能评估。高中低三档机的帧率,内存,耗电等都需要有数据。接下来就是

发现热点 -> 优化 ->继续发现热点->继续优化 –>继续…

这个过程肯定是没法由优化的人一个人搞定,最好是进行完一轮Profile之后,把需要优化的点记录下来,然后通过tapd等工具将优化任务派给对应的美术/程序同学,并去推进优化迭代,这其实牵涉到很多沟通工作。

关于GC

GC方面的优化很重要,原则就是任何大于20B的GC都值得被注意。GC的优化比较琐碎,也比较考验基本功。

除了最简单的避免使用foreach,避免频繁new内存,ToString。下面几个点可能是往往容易被忽略。

  1. GameObject.SetActive会引起GC

优化方法:对于渲染相关的,可以考虑是否隐藏MeshRenderer来替代,还有就是把GameObject拉到很远的地方,UI也同样适用。

  1. C#自带的排序有GC

优化方法:自己实现排序算法,数量不多的直接写个简单的冒泡就行。

  1. 反射会引起GC

优化方法:大部分的反射都可以用dictionary做缓存。

  1. List.Add会有GC

优化方法:List底层是数组,在数组容量不够的时候就会扩充,会产生GC。可以考虑在new的时候直接指定大小。

  1. Box Unbox 会有gc

Boxing的GC很隐藏,打桩也很难发现,Boxing的触发条件:当需要将栈(Stack)上的值类型转换为堆(Heap)上的引用类型,这个过程被称为“装箱”,它具有以下特性:

  1. 在堆(Heap)上分配空间

  2. 通知垃圾回收器有关新对象的信息

  3. 复制值类型对象中的数据并传递给新的引用类型对象

当初是发现了Behavic组件底层有GC,跟到很下面的时候发现是一个equal函数

里面有一处改动是这样。

GPU优化

不说GPU占有率,直接说GPU耗时Xms就是耍流氓。

通常XCode里面有GPU时间,对于一个30fps得游戏,理论上GPU有33ms的时间可以用,但是这个时间超过20ms的时候,就会发现再往上增加一些渲染消耗(1,2ms左右),GPU耗时不会明显增加,而原有的一些渲染消耗可能要1.5ms的你会发现只要1ms就可以了,这个时候其实GPU负载已经有点过了,GPU为了流畅度开始提升频率(iPhone 6 plus亲测)

GPU的优化其实就是和美术同学Battle的过程,找到那个平衡点,就算优化成功了。很多时候GPU的优化不仅仅是Profile看热点,而是需要你给出方案,这就很看经验了,萌新需要多问问老司机。

下面几个点一定要注意!

Overdraw! Overdraw! Overdraw!注意每一块半透明是否需要渲染,面积是否能够减少。

Shader的复杂度会影响fillrate。

游戏场景内最好不要出现alpha test,会影响Hidden Surface Removal(HSR)的处理。

不要轻易尝试后处理,耗CPU, 耗内存, 耗GPU,中低配一定要关掉。

粒子系统请慎重使用,耗CPU,多Overdraw,数量和粒子总数都要控制好。

Static Batch 会消耗内存。

Dynamic Batch耗CPU,但是当需要渲染很多个同样的MeshRenderer的时候,对于减少DC非常有效,建议开启。

单局外的性能也要注意!

耗电优化

当优化完卡顿问题之后,本人就开始想着做一些炫酷的事情了,比如更酷的特效啊,后处理加起来啊,然后对于移动平台来说,你不是不卡就可以了,耗电,发热也是要重点考虑的事情。

耗电的几个大头,GPU,网络,CPU,GPRS,喇叭,屏幕亮度等等。上面介绍了几个Profile CPU, GPU的工具,但是电量怎么Profile呢?

关于耗电的优化踩过很多坑,参考网上能找过的方法挨个试了,比如用ios设备的记录耗电情况日志,或者是XCode的Energy impact等等,统统无效,其中的坑就不一一说了。只说一个绝对有效的方法。

使用WeTest云真机耗电量测试!基于自家的耗电盒子来检测电量,测得的结果精准。

还有就是设备一直处于充电状态,和实际使用有偏差,不过都在可接受范围内。

首先要测试出一个同品类游戏或者标杆产品的耗电水平,比如测得王者5v5单局得耗电如下:

接下来就可以测自己得apk了,测试得时候,最好可以通过作弊指令去动态开启关闭一些特性,得到各项的消耗,想要测得比较精确的结果就多次测取平均。

得到各项的消耗之后,就可以有针对性的优化了。

数据上报统计

数据上报统计是指将玩家的设备信息,设备画质选择,帧率信息进行上报,这样每次测试都能获取到很多有用的信息,利用这些信息可以进行相应的调整,比如说某些默认画质匹配占比,不同设备的性能表现,各类硬件的占比,比较卡顿的场景有哪些等等,同时也可以横向对比看优化的效果。

小结

记得刚加入团队,飞车刚好要进行第一次轻度测试,那次测试的收到很多的玩家抱怨各种卡顿,竞速赛卡,道具赛卡,连我们的策划同学在跑单人单局的也觉得卡…当时为了保证流畅把大部分的机器归为了低配机,还有很多玩家,设备是中高配的,为了开上高帧率,将画质设为低…..

到PR2的时候,经过一轮强力优化,也是和美术策划同学的通力合作,将默认中高配的设备从20%多提升到了70%以上,对于低配机,我们尽量会满足30fps流畅运行,对于中高配,60帧的顺畅体验可以让他们觉得玩的是另一个游戏(Android设备需要开始多线程渲染),如今正式上线,在TapTap这种黑腾讯游戏即政治正确的社区,好评也是绝大多数。

不过还是会有一些没有优化到的地方,比如

”Android 机开局的完美起步会卡啊!“

“-请期待年前的版本”

”休闲区还是很卡啊!“

“-请期待年前的版本”

”新手引导品质太低了吧!“

“-请期待年前的版本”

….

优化是件漫长的事情,因为总有可以优化的东西,这里的面是不是可以更省,那边shader精度减一下是不是可以…..自身也需要去掌握多种的profile技术,内功也要加强修炼才行,你拿着消耗去和美术大佬谈判,总得给个靠谱的解决方案吧。

对于一个老司机,应该在项目之初就能够把各个标准都定好,给出最好的解决方案,能做的不能做的都和大佬拍好,这样后面就舒服一些,但大部分还是一边现问题一边处理,然后慢慢地把规范和自动化测试流程搭建起来,这样也不失为亡羊补牢,这里面其实又涉及了一些TA工作。

特别感谢在优化过程中能够耐心给我解答问题的各位前辈,非常感谢!

篇幅原因,能覆盖的就这些了,没有涉及到的或者有误的迎大家指正。

参考

[1] 手机CPU性能天梯图

[2] Smartphone and Tablet Graphics Cards - Benchmark List and Comparison

[3] mobile cpu上禁用alpha test的相关总结

[4] iOS Hardware Guide

[5] Unity移动开发如何依据性能选择shader? - 拳四郎的回答 - 知乎


腾讯WeTest“耗电量测试”已在云端部署,独家研制的耗电量盒子进行耗电量测试,精准定位手游耗电问题,点击http://wetest.qq.com/cloud/phone 即可体验。

如果使用当中有任何疑问,欢迎联系腾讯WeTest企业QQ:2852350015

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引