60帧的丝般顺畅 - QQ飞车手游优化点滴
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也同样适用。
2. C#自带的排序有GC
优化方法:自己实现排序算法,数量不多的直接写个简单的冒泡就行。
3. 反射会引起GC
优化方法:大部分的反射都可以用dictionary做缓存。
4. List.Add会有GC
优化方法:List底层是数组,在数组容量不够的时候就会扩充,会产生GC。可以考虑在new的时候直接指定大小。
5. 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
60帧的丝般顺畅 - QQ飞车手游优化点滴的更多相关文章
- Web程序设计基础期末大作业——模仿QQ飞车手游S联赛官网编写的网页
QQ飞车手游是我非常喜欢的游戏,也是我现在为数不多的常在玩的游戏,刚好我Web程序设计基础的大作业是要做一套网站,我就借此机会模仿飞车S联赛官网的页面自己做了一个网页,又加了一些自己的元素,由于我做这 ...
- 想让安卓 APP 如丝般顺滑?
随着安卓手机市场占有率的节节攀升,随便在大街上找几个人估计 80% 用的都是安卓手机吧!用安卓手机的人这么多,不知道大家是否曾经感觉到过 APP 卡顿.死机?是否遇到应用程序无响应.闪退?本文就为大家 ...
- 丝滑顺畅:使用CSS3获取60FPS动画
原文链接: Smooth as Butter: Achieving 60 FPS Animations with CSS3 在移动端使用动画元素是很容易的. 如果你能遵循我们的这里的提示, 在移动端适 ...
- 如丝般顺滑地从Windows迁移SQLServer数据库到Linux
老鸟看过菜鸟的上一篇<MSSQL On Linux备份与还原>文章后,很满意,但是还是忍不住发问:"这篇文章讲的是MSSQL在Linux系统上的备份与还原,如果我之前是Windo ...
- 大促密集,CDN如何保障电商体验如丝般顺滑?
简介: 前不久,阿里云技术天团空降CSDN在线峰会,对核心技术竞争力进行解读.其中,阿里云高级技术专家曾福华分享了<双11: CDN如何保障电商大促如丝般顺滑>的议题.俗话说:养兵千日,用 ...
- 如何把 Caffeine Cache 用得如丝般顺滑?
一.关于 Caffeine Cache 在推荐服务中,虽然允许少量请求因计算超时等原因返回默认列表.但从运营指标来说,越高的"完算率"意味着越完整的算法效果呈现,也意味着越高的商业 ...
- QQ群排名优化到霸屏的策略怎么做?
谈起QQ群排名霸屏,首先要弄清楚概念,有些刚接触QQ群的朋友可能不太了解,所谓的QQ群排名霸屏,就是指当你的客户群体搜索QQ群某个关键词时,出现在QQ群搜索结果前面的群,全部或者大部分都是我们自己的群 ...
- 让API并行调用变得如丝般顺滑的绝招
当数据量较大的时候,都会通过分库分表来拆分,分担读写的压力.分库分表后比较麻烦的就是查询的问题,如果不是直接根据分片键去查询的话,需要对多个表进行查询. 在一些复杂的业务场景下,比如订单搜索,除了订单 ...
- 如丝般顺滑:DDD再实践之类目树管理
在上次反思DDD实践之后,在类目树管理项目中再次实践DDD.从需求分析到建模和具体的落地,结合个人体会,都是干货.
随机推荐
- UVa 1151 - Buy or Build(最小生成树)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 字符串匹配KMP算法(转自阮一峰)
转自 http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字符串匹配是计算 ...
- Centos7 搭建jupyter远程服务器
前提:已经安装好jupyter 和Ipython,个人安装anaconda自带jupyter和Ipython 步骤1:生成配置文件: jupyter notebook --generate-confi ...
- PCA算法的最小平方误差解释
PCA算法另外一种理解角度是:最小化点到投影后点的距离平方和. 假设我们有m个样本点,且都位于n维空间 中,而我们要把原n维空间中的样本点投影到k维子空间W中去(k<n),并使得这m个点到投影点 ...
- javaWeb中怎么获取提交表单里面的值
在javaWeb中如何获得html文件中的表单里面的值? <!DOCTYPE html> <html> <head> <meta charset=" ...
- Java 分支结构
Java 分支结构 - if...else/switch 顺序结构只能顺序执行,不能进行判断和选择,因此需要分支结构. Java 有两种分支结构: if 语句 switch 语句 if 语句 一个 i ...
- Unity3D Errors And Fix
Author Error: Shader warning in 'Custom/ShowAnimation': Not enough temporary registers, needs 9 (com ...
- c#随便聊聊数据库操作
最近在学习web后台以及Python,到了程序员的转折年纪了,哎.估计很久不会写博文了.言归正传. 在原理的数据库连接池HiKari项目上.我扩展了独立的3个库,说是3个库,其实原本该是一个库.先聊聊 ...
- MySQL正则表达式的问题
原本以为 正则表达式里面的特殊\d匹配数字放到sql语句里面也是适用的,没想到一直不匹配.但是放到编程语言java或者js里面又匹配.看了一下原来sql对正则的支持没有那么全面.一定要用[0-9]代表 ...
- MYSQL 8.0.11 安装过程及 Navicat 链接时遇到的问题
参考博客:https://blog.csdn.net/WinstonLau/article/details/78666423 我的系统和软件版本是这样的: 系统环境:win7.64位 MySQL版本: ...