Cocos Creator 性能优化:DrawCall

前言

在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。

无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。

本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。


正文

什么是 DrawCall?

DrawCall 中文译为“绘制调用”或“绘图指令”。

DrawCall 是一种行为(指令),即 CPU 调用图形 API,命令 GPU 进行图形绘制。

DrawCall 一般可以简称为“DC”,当然此“DC”非彼“DC”…


为什么要减少 DrawCall?

发生了什么

当我们在讨论减少 DrawCall 时我们在讨论什么?

其实我们真正需要减少的并不是 DrawCall 这个行为本身,而是减少每个 DrawCall 前置的一些消耗性能和时间的行为。

看不懂?其实我也不知道我在说些什么,还是接着看下面的内容吧 : p

举个栗子

问:尝试在两个硬盘之间传输文件,传输 1 个 1MB 的文件和传输 1024 个 1KB 的文件,同样是传输了共 1MB 的文件,哪个更快?

答:传输 1 个 1MB 的文件要比传输 1024 个 1KB 的文件要快得多得多。因为在每一个文件传输前,CPU 都需要做许多额外的工作来保证文件能够正确地被传输,而这些额外工作造成了大量额外的性能和时间开销,导致传输速度下降。

回到渲染

图形渲染管线的大致流程如下:

上图只是对渲染管线的部分概括,方便大家理解,实际的图形渲染管线比较复杂,不在本文讨论范围内。

从图中可以看到在渲染管线中,在每一次 DrawCall 前,CPU 都需要做一系列准备工作,才能让 GPU 正确渲染出图像。

而 CPU 的每一次内存显存读写、数据处理和渲染状态切换都会带来一定的性能和时间消耗。


到底是谁的锅?

一般来说 GPU 渲染图像的速度其实是非常快的,绘制 100 个三角形和绘制 1000 个三角形所消耗的时间没差多少。

但是 CPU 的内存显存读写、数据处理和渲染状态切换相对于 GPU 渲染来说是非常非常慢的。

实际的瓶颈在于 CPU 这边,大量的 DrawCall 会让 CPU 忙到焦头烂额晕头转向不可开交,而 GPU 大部分时间都在摸鱼,是导致游戏性能下降的主要原因。

所以 DrawCall 这玩意越少越好~


如何减少 DrawCall?

在游戏运行时引擎是按照节点层级顺序从上往下由浅到深进行渲染的,理论上每渲染一张图像(文本最终也是图像)都需要一次 DrawCall。

既然如此,只要我们想办法将尽可能多的图像在一次 DrawCall 中渲染出来(也就是“渲染合批”),就可以尽量少去调用 CPU,从而减少 DrawCall。

简单点,就是减少让 CPU 工作的次数,但是每次都多给点活,不就可以省去一些“CPU 准备工具然后工作”和“工作结束叫 GPU 加工”的步骤了嘛,代价就是每次工作的时间会变长~

明白了这个原理之后,下面让我们看看在实际游戏开发中应该如何操作吧。


静态合图

静态合图就是在开发时将一系列碎图整合成一张大图

图集对于 DrawCall 优化来说非常重要,但是并不是说我们把所有图片统统打成图集就万事大吉了,这里面也有它的门道,胡乱打图集的话说不定还会变成负优化。

最重要的是尽量将处于同一界面(UI)下的相邻且渲染状态相同的碎图打包成图集,才能达到减少 DrawCall 的目的。

还记得游戏渲染时是按顺序渲染的吗,所以“相邻”很关键!要考,做笔记!

改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

举个栗子,我这里有一个由 10 张碎图和 1 个文本所组成的弹窗(假设都使用同样的渲染方式):

  1. 在不做任何优化且未开启动态合图的情况下,渲染这个弹窗需要 11 个 DrawCall。
  2. 将所有碎图打成一个图集,文本节点夹在精灵节点之间的情况下需要 3 个 DrawCall,在顶部最外层或者底部最外层的情况下需要 2 个 DrawCall。
  3. 文本使用 BMFont,将所有碎图和 BMFont 打成一个图集的话只需要 1 个 DrawCall,如果碎图不和 BMFont 打成一个图集的情况则参考第 2 项。
  4. 碎图不打包图集,开启动态合图,在理想情况下,文本使用 BMFont 最少只需要 1 个 DrawCall,不使用 BMFont 的情况同样参考第 2 项。

如果上面的例子你不太能理解的话,那请接着看下面的内容,相信你阅读完本篇文章的全部内容后再来看这个例子将会茅塞顿开哈哈哈~

动态合图和 BMFont 会在后面说到。

当然上面这个例子算是比较理想的情况,实际上的情况可能会比例子更为复杂,精灵和文本可能会更多,也不一定能将所有图像资源都打包进一个图集。所以我们只能是尽量合理地去优化,避免出现“捡了芝麻,丢了西瓜”的情况。

不建议任何图像资源的尺寸超过 2048 * 2048,否则在小游戏和原生平台可能会出现问题;

而且图像尺寸越大,加载的时间也越长&#

  • 10
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值