Cocos Creator DrawCall优化
概念说明
drawCall 是什么
Draw Call 就是CPU调用图形编程接口,比如 DirectX 或 OpenGL ,来命令 GPU 进行渲染的操作。在每次调用 Draw Call 之前,CPU 需要向 GPU 发送很多内容,包括数据,状态,命令等。 这里对性能消耗巨大的是提交这个命令,而对 Draw Call 的实际渲染却很快 。 (在CPU不改变渲染数据的情况下,完成一次渲染)## 新的改变
如何减少DrawCall
由于 GPU 渲染快速而,提交这个命令消耗巨大, 所以自然而然的优化想法就是把很多小的 Draw Call 合并成一个大的Draw Call, 这就是批处理的意思。在 Cocos Creator 中默认进行了合批的处理, 我们需要做的就是按照 Cocos Creator 的合批方法来规划项目内容。
在哪里查看 DrawCall
在网页模拟器的左下角可以查看,如没有可以尝试在代码中加入并执行下面的方法。
cc.director.setDisplayStats(true);
合批的流程
假设绘制顺序是 A => B => C
- 如果 A、B、C 不使用一张贴图,那么就无法进行合批于是 DrawCall 是 3.
- 如果 A、B 使用图一个贴图,C 使用另一个贴图,则 AB 进行合批,于是 DrawCall 是 2.
- 如果 ABC 使用同一贴图,进行合批后 DrawCall 为 1.
下图使用共 5 张图片,但是图片在一张贴图中所有 DrawCall 占用 1,另一个 DrawCall 是背景所占用的。

注意事项
不打断合批的操作
- 使用不同图片,但没有对图片所在文件夹进行自动图集的设置,不会影响到合批操作.
- 不同图片放在不同级节点上,但仍在一次绘制流内. 如下图,虽然图片 SpriteB 与 SpriteA 不在同一层级内,但并没有打断合图.

- 修改节点的 位置、旋转、缩放、锚点、尺寸、Skew 等熟悉.
打断合批的操作
在图片渲染中添加文字. 下图展示了再图片中添加
Label,导致合批被打断。前3个图片算一个DrawCall, 文字算 1 个,再次进行图片的渲染还算一个.
改变图片颜色,原因同文字.

改变图片透明度,原因同文字.

修改图片渲染模式(Type): 九宫格(
SLICED)、平铺(TILED).修改 Blend 模式,导致图片与其他图片的blend模式不一致.
节点上添加一个
Mask组件会打断合批, 一个Mask组件占用 2 个draw,尽量减少使用.多个使用
Label组件的节点是不会进行合批的,如下图所示.
使用
RichText组件时,使用多少个标签<tag></tag>占用多少个DrawCall
<color=#00ff00>Rich</c>
<color=#0fffff>Text</color>
<color=#00ff00>Rich</c>
<color=#0fffff>Text</color>

9. 在使用了自动图集的情况下,在不同图集中的图片会打断合批,所以在合图的过程中要避免使用多个自动图集的图片.
其他
- 要渲染的节点过多,这样 cpu 需要在每次渲染的时候进行数据处理.
- 使用自动图集减少 DrawCall要在构建后才能观察到.
- 尽量使用多个连续的节点使用相同的贴图,可以一次性批量绘制.
- 使用cocos creator版本为2.0.9,不同版本可能有不同的处理方式,还需自行检验.