您的位置:首页 >聚焦 >

当前简讯:Cocos 性能优化的 N 种策略:降低 DrawCall 与面数、强制调用独显……

2022-10-21 19:11:37    来源:程序员客栈
iles 优化后,游戏实录

前段时间,我们发布了 3D 跑酷闯关+建造游戏源码 iles,开源的同时也上线了 Steam。我们希望借助这一案例,让开发者看到更多引擎所构建的场景的细节,同时,作为引擎研发者,我们也能亲身体验一下 Cocos Creator 开发游戏的全流程,以此发现引擎的不足与痛点,为之后的迭代提供参考。

游戏发布后,许多开发者和玩家将自己的体验感受与建议告诉了我们。参考大家的反馈,我们在 iles 的性能优化方面做了更多探索,本文将分享一些优化思路与优化手段,供有需要的小伙伴参考。

强制使用独立显卡


(资料图片)

很多 windows 机器都会拥有两张以上的显卡,在某些情况下机器会自动选择性能比较低的集成显卡来降低性能。在游戏应用里面,我们可能希望程序一直都运行独立显卡来保证游戏的流畅度。

iles 基于 electron 发布,在此基础上我们查找了一些解决方案:

环境变量里设置 SHIM_MCCOMPAT=0x800000001[1]。以下是 iles 启动的 start.cmd 文件:

setSHIM_MCCOMPAT=0x800000001cd%~dp0start..\..\iles.exe

添加 electron 启动参数[2]

app.commandLine.appendSwitch("force_high_performance_gpu")

查了下 chromium 支持的版本在 101.0.4923.0[3],electron 对应版本在 19.0.0 之后[4]

为了检测启动后机器的显卡信息、及其是否正确使用了独立显卡,我们写了一个测试程序,提供给大家参考:

GitHub - 2youyou2/electron-detect-gpu:

https://github.com/2youyou2/electron-detect-gpu

优化 DrawCall 以及面数

> 海面

整个海平面是一个很大的区域,为了保证海浪运动得比较自然,需要的顶点数就比较多,但是我们又不希望整个海平面都使用非常多的顶点数,理论上我们只需要近处的细节比较多,远处的细节可以少一点。

基于这个思考,我们将海平面分为9个区域,只有中间的部分保持高顶点数,周围使用少一些顶点数的模型,但是为了保证区域间的顶点动画是完美衔接的,高模和低模的边缘顶点数也是需要完美匹配的。

下面是我用 blender 操作的流程:

添加一个 Grid 类型的 Mesh。切换模式到面编辑模式,选中边缘以外的面,右键选择 un-subdivide。可以看到优化完后顶点会少很多。

> 树

iles 中遍布了大量的树,原始的树的模型面数还是挺高的,一棵树有300面左右。

上图这个关卡有近2000棵树,差不多 60w 面。我们添加了 lod 的支持,在近处使用比较精细的 lod,在远处使用粗糙一些的低模,在一定距离外剔除掉这个模型的渲染。

在 blender 里面做一个粗糙的低模还是比较简单的:选中模型添加一个 Decimate 类型的 Modifier,调节 ratio 减面到一个能接受的程度。

接着写了一个比较简易的 lod 选择器,在摄像机10米以内的话使用 lod0,在1000米以内使用 lod1,再远一点的就会剔除掉。在创意工坊编辑模式下希望看到的距离更远一些,所以设置在3000米以内还能看到树。

> 草

游戏中草的数量是非常多的,地块面积越大,草的数量就越多,像下面这个大场景里面草的数量很轻易就上万了。

如果我们按照普通模型的方式去渲染草地的话,每一个遍历都会消耗大量的性能。场景裁剪、instance 填充,这些是性能消耗的重灾区。

这里我希望完全自己控制整个草地的 instance 渲染流程:

把整个场景按区域划分,每个区域的范围是 5*5*5。

场景加载的时候将草按区域添加进对应的 InstancedBuffer 中(不会生成实际的草节点),这些 InstancedBuffer 填充完后运行时不会再进行修改。

场景运行中只需要对区域进行视锥体剔除,而且没有运行时填充 InstancedBuffer 的消耗,整个效率会高很多。

测试了草地的优化后海底遍布的物体也使用了同样的方式来优化。

所有这些优化加起来后性能有了显著的提升,最大的场景为优化前有 600w 面,优化完后基本可以控制在 50w 面以内。

渲染 Pipeline

我们增加了一些 pipeline 条件控制节点,尽量避免不必要的渲染流程,渲染整个屏幕还是很耗性能的。

优化开始场景

开始场景里,摄像机的视角是固定的,摄像机只会看到岛的前半部分,后半部分是看不到的,在生成海底物体的时候可以增加一下判断,处于岛的后半部分的物体不用生成,这样可以减少运行时的开销。

渲染分辨率

屏幕的渲染分辨率对于 GPU 计算的消耗影响是很大的。我们发现有些用户的机器设备并不是很好,但是有可能连接了一个很高分辨率的机器,基于不同的渲染质量,我们控制了他最大的渲染分辨率。

letresolution=[1120,630]if(renderSetting.realQuality===RenderQulity.High){resolution=[1960,960]}elseif(renderSetting.realQuality===RenderQulity.Medium){resolution=[1334,750]}

提升开发效率

Cocos Creator 3.6.0新增编辑器预览模式,我们可以在编辑器中运行和调试游戏,对于提升开发效率很有帮助。iles 升级到了 v3.6.1,整个体验还是很不错的。

提升游戏体验

除了优化性能,我们还增加了一些游戏内容或模块,提升玩家的游戏体验。

1. 新增排行榜,使用 leancloud 免费版,每天有一万次 api 接口调用次数。

2. 添加了辣椒道具,搭配火焰特效,吃了能够加速奔跑。

3. 添加了弹力蘑菇,能将小鸡弹上天空。

4. 添加了漂浮木箱,模拟水面浮力,增加趣味性。

5. 支持了键盘和手柄控制。

6. 优化加载过程,添加加载界面。

>> 左右滑动查看更多

资源下载

目前 Cocos Store 上的源码为优化前、基于 v3.6.0 构建的源码,优化后、升级到 v3.6.1 的源码将在整理后上传,敬请关注!

点击文末【阅读原文】下载源码

https://store.cocos.com/app/detail/4010

iles 下载体验 - Steam

https://store.steampowered.com/app/2001150/iles/

参考链接

[1] 环境变量设置

https://steamcommunity.com/groups/SteamClientBeta/discussions/0/154644787621730542/

[2] Electron 文档

https://www.electronjs.org/zh/docs/latest/api/command-line-switches#--force_high_performance_gpu

[3] chromium101.0.4923.0

https://github.com/chromium/chromium/releases/tag/101.0.4923.0

https://github.com/chromium/chromium/commit/f35df3e3e2276c4ec658d66961789ceb4fc4e278

[4]Electron 版本下载

https://www.electronjs.org/releases/stable?version=19&page=4

往期精彩

关键词: 独立显卡 开始场景 环境变量

相关阅读