最新 Cocos 机型性能适配方案上线!轻松兼顾画面质量与流畅度
引言:机型性能适配是优化游戏性能、提高玩家游戏体验的一个重要环节。在 Cocos Creator 中,如何进行手机性能检测与机型适配?来自「深圳小爱灵动」的开发者 iwae 和我们分享了他的机型性能适配方案,源码和体验地址见文末。
先看看这个 Cocos 机型性能适配方案:BenchMark 性能检测的效果预览。
该方案支持手机性能检测与手机性能适配,为高中低档机型提供兼顾质量与流畅的运行方案。在游戏加载过程中,程序会根据 GPU 型号和屏幕分辨率等,决定画质和适配方案,玩家也可以在项目中实时切换方案。
在介绍具体实现方式前,先来讨论一下:我们为什么要做手机性能检测?
为什么要做手机性能检测?
从上面的预览可以看到,在高中低3档设置上,手机的画质有截然不同的表现。随着手机行业的发展,手机的性能越来越高,从2016年的骁龙820到2022年的骁龙8Gen,手机的性能提升了近6倍不止。
来源:安安兔评测数据
可这是不是意味着在 3D 游戏赛道,我们可以尽情地去卷游戏画质呢?
答案是存在疑问的。
根据去年底 Android Studio 最新公布的安卓设备份额报告可以看出,目前安卓4.0~安卓9.0依然有着不小的用户存量。
毫无疑问,我们的游戏必须考虑到高中低端机型的用户,给最广大玩家带去更好的游戏体验。所以在机型适配上,我们要尽量实现 T 型适配:针对高端机型,提供高品质高画质内容;针对中低端机型,要向下兼容,确保运行流畅。
手机性能评级
那么,如何在 Cocos Creator 上做机型适配呢?
首先,考虑到当前小游戏平台内存和性能的局限性,我们放弃了实时检测。其次,目前大部分主流机型的测试报告都可以从 GFXBench 官网(https://gfxbench.com)上拿到,所以本次的方案是通过对比法,获取手机的 FPS 跑分报告,并做出相应的适配方案。
第一步,通过 pipelineSceneData 拿到 GPU 型号。
pipelineSceneData 内的信息
第二步 ,用手机的 GPU 信息,加上手机分辨率的长乘宽的结果去和 GFXBench 的数据库进行对比(这里我们使用了第三方的地址 https://unpkg.com/browse/detect-gpu@4.0.14/dist/benchmarks/ 的数据缓存,建议把这些 JSON 保存在自己的 CDN,或者把手机的 JSON 信息保存在本地做解析)。
如果拿到了手机的 FPS 跑分信息,就可以通过提前定义好的适配等级(0-4,共5级)来获取手机表现。
如果没有拿到 GPU 信息或 GFXBench 里匹配的数据样本,则通过手机的长宽信息进行判定(准确率略低),这个算法主要是基于全屏屏手机屏幕的价位决定的。
到此,我们就成功拿到了手机的性能评级,接着就可以根据性能评级去做高低端机型优化啦。
高中低端机型优化
Cocos 性能消耗主要在三个方面:逻辑开销、物理开销、渲染开销。我们根据手机的性能评级分别进行以上3点的优化。
通过阅读引擎源码(感谢社区小伙伴 xzben 教我阅读)可以发现,game.frameRate=30 时候,代码层在 _updateCallback 有做跳帧处理,针对动画和物理的设置物理的线性速度都会有影响,通过设置 frameRate=30 可以很有效地提升低端机性能。
private _updateCallback () {
const director = legacyCC.director;
let callback;
if (!JSB && !RUNTIME_BASED && this._frameRate === 30) {
let skip = true;
callback = (time: number) => {
this._intervalId = window.rAF(this._frameCB);
skip = !skip;
if (skip) {
return;
}
director.tick(this._calculateDT(time));
};
} else {
callback = (time: number) => {
director.tick(this._calculateDT(time));
this._intervalId = window.rAF(this._frameCB);
};
}
this._frameCB = callback;
}
逻辑开销有很大一部分经常来自 update 或者 lateUpdate 的消耗,这部分逻辑大佬们可以针对项目做适配。
物理开销方面,如果 frameRate=30 后,我们可以对物理的线性速度额外乘2,但对于高速运动的物理场景,可能会出现穿墙的情况。
渲染开销方面,通过全局的宏设置,可以控制大部分渲染相关的参数,包括雾效、阴影、阴影贴图大小、IBL 等。
这里针对渲染开销做了4层优化:
显存开销:阴影贴图大小、天空盒是否开启(如果需要严格控制显存,天空盒需要做动态加载,Demo 中是提前加载好的)。
网格渲染开销:网格 LOD、阴影是否开启。
常规渲染开销:IBL、雾效、普通材质与高级材质切换等。
粒子特效开销:粒子特效剔除、粒子特效粒子数量减少。
高 VS 超高
具体对比下几个设置的差异。超高档开启了 IBL,因此使用 PBR 材质的模型有受环境光影响;同时阴影贴图大小设置为了1024,阴影细节的表现会更细腻。
中 VS 高
中档关闭了阴影,整个画面的立体感下降了不少,老美人鱼显得更加沧桑;同时全局做了降帧处理,frameRate 设置成了30,乌鸦和虎鲸的动画会有一点生硬。
低 VS 中
低档关闭了全局阴影,水面材质切换到了 Unlit 无光照材质,同时暂停了粒子特效模拟的 God Ray,画面的层次和细节又少了一点点。
LOD Mesh 对比(右边为低档)
此外,低档中背后的4根封印石柱设置了 LOD Mesh,相比中档减少了55000左右的三角形个数,但是在视觉上的差异却不大,这里的 LOD 并没有做视距上的控制(to-do)。
此处创建 LOD Mesh 也比较简单,复制一份 Mesh,直接通过自带的 Mesh 压缩即可。
在实际应用场景中,通常会把复杂 Mesh 根据离摄像头的距离或适配方案的设置,做 LOD 的降级。如下图的树,最低档的 LOD 开销只有最高档的三分一不到。
LOD 方案在草面设置就更暴力一点,近处的是几何体,中景用的面片插片,到了远景直接用一个面片躺平了。
最低 VS 低
最低档会关闭 FOG 雾效,同时关闭天空盒和画面抗锯齿。
FAQ
Q:为什么部分手机浏览器上分辨率数据不准?
A:以三星 S21 为例,使用数据库没用的 adreno 660 GPU,这时候请求了分辨率判断,三星在省电模式下,分辨率会改为 720P,这时候判定就会失误。
Q2:UNPKG - detect-gpu 里的 JSON 数据体积很大,会不会影响加载?
A :这里只会下载对应的 GPU 数据,对速度和域名有要求的项目(比如微信),可以把这些 CDN 加载本地,对于统计到没有 GPU,可以下载 BenchMark 跑分后加入到 JSON 当中。
部分对加载速度要求很严的项目,也可以把这部分逻辑上传到服务器,前端只负责获取 GPU 和分辨率信息。
Q3:为什么检测出来的 GPU 信息好长,没有正确返回?
A:这个 BenchMark 信息是外网的,弱网环境下可能会请求不到,建议放在自己的 CDN 或者本地。
资源链接
本方案将持续更新维护,未来计划:
增加延迟渲染管线 Demo,实现分辨率修改+FXAA 等级适配;
基于摄像机距离的 LOD 实现;
更优的材质适配方案;
粒子数量适配。
Cocos 机型性能适配方案:BenchMark 性能检测现已发布到 Cocos Store,限时 ¥ 19.9 抢购中,速戳文末【阅读原文】或到 下载吧!小伙伴们可以在线体验一下,也欢迎到论坛专贴里交流反馈!
资源下载
https://store.cocos.com/app/detail/3662
在线体验地址
http://www.yiyizu.com/babyshark/
论坛讨论帖
https://forum.cocos.org/t/topic/133327
本文为「Cocos 中文社区第4期征稿活动」参与作品。投稿现已截止,感谢小伙伴们的热情参与!本期征稿我们增设了「人气作品」评选,前往论坛给你喜欢的作品投上一票吧!投票地址:
https://forum.cocos.org/t/topic/134493