文末福利丨DrawCall 1106→8!实测最新 Cocos 合批优化工具,性能起飞!

面对包含复杂图文的 2D UI 场景,如何才能避免合批被打断、DrawCall 剧增的情况?Cocos Store 张晓衡体验测试了一款 Cocos Creator 3.x 性能优化工具,有效解决该问题。

高性能轻量 3D 碰撞管理器「98K 物理-轻量碰撞系统」的作者「我叫98K」,本次带来了一款全新的性能优化工具「98K 动态分层合批」,能够通过动态分层合批和范围剔除,显著降低 DrawCall。

该工具适用于 2D UI 界面的优化,特别是具有大量重复结构的 item 场景,如背包系统、滑动列表、排行榜、技能栏、聊天界面等,解决因图文分层打断合批、造成 DrawCall 剧增而影响性能的问题。

我们来测试一下在 H5、小游戏、原生等不同平台上,工具使用前后的性能表现差异。测试案例是一个 2D 背包界面,我在 ScrollView 中动态创建了 500 个 item 元素。测试结果如下:

00cf99b86d1b6675a2d30a57a4034bce.png

从测试结果来看,工具开启合批优化后,各个平台的 DrawCall 都从 1000+ 降至个位数,帧率都达到了 60 帧,ScrollView 列表滑动流畅;此外,开启渲染剔除算法也有效降低了渲染面数。

像道具背包这类应用场景,一个 item 混合有复杂的图片和文字,「98K 动态分层合批」是如何避免 DrawCall 被打断的?我们又该如何理解 DrawCall 与合批呢?

DrawCall 与合批

什么是 DrawCall 与合批?

DrawCall 是什么?

简单来讲 CPU 准备好渲染数据,提交给 GPU 进行绘制的这个过程就是一次 DrawCall。

为什么减少 DrawCall 能提升游戏性能?

首先,GPU 渲染图像的速度非常非常快;而 CPU 的内存/显存读写、数据处理和渲染状态切换,相比 GPU 非常非常慢。大量的 DrawCall 会让 CPU 忙到焦头烂额,而 GPU 大部分时间都在摸鱼。

因此,若一次性将更多渲染数据提交给 GPU,减少 CPU 的工作时间,就能提升游戏性能。

什么是合批?

简单来说,组织更多渲染数据提交给 GPU 的过程,称之为「批量渲染」,简称「合批」。

实现合批的前提是:渲染数据必须一致。

4ab6701567fe7b3f0dba8b730ee7a0bd.png

举个例子,像上图中的的节点树结构,就无法实现合批。因为 item 节点下的 Sprite 与 Label 节点渲染类型不同,并相互间隔排列,引擎无法向 GPU 批量提交渲染数据。此时,渲染一个 item 需要 4 次 DrawCall:SpriteLabelSpriteLabel

434c1a7c49e587e3cda5d53148e21580.png

我们调整一下 item 下的节点顺序,如上图。

48b49ca9aa768beb8091c6d6245a1835.png

此时,渲染一个 item 需要 2 次 DrawCall。而因为引擎会占用一次 DrawCall,所以在 Cocos Creator 中预览运行游戏,画面左下角 DrawCall 的值显示为 3。

更多关于 DrawCall 优化的理解,可以阅读陈皮皮的文章《Cocos Creator 性能优化:DrawCall》

如何避免 DrawCall 被打断?

什么是 DrawCall 打断呢?

在了解了单一 item 的 DrawCall 情况后,我们再来看看多个 item 节点树的 DrawCall 情况。

257be80cc0d8e33ab614afb7490376be.png

如上图,在层级管理器中,我们再复制一棵 item 节点树出来。可以看出,两棵 item 节点树存在 item1(SpriteLabel) → item2(SpriteLabel) 交替的情况,合批就这样被打断了。

54be833fe4717e92a42957e20eb7d8d9.png

也许你会想到:既然如此,将所有 item 下的节点合并不就好了。如上图所示,6 个节点只需 2 次 DrawCall。

但这样做有一个很大的问题:我们的逻辑代码通常是以单个 item 为单位建立的对象,如果将类型节点点合并到一起,上层逻辑代码岂不是要乱成一锅粥?

而「98K 动态分层合批」的强悍,就在于它可以让你无视 item 子节点顺序和层级关系,只需要在上层容器节点上添加 BatchItems 组件,即可最大程度上保证合批不被中断,实现该节点树的渲染优化。

39a425edc3a2805fc397110a44a0bcf7.png

其代码实现原理是:

  1. 拦截引擎渲染开始事件,对节点树下的所有子节点按类型重新分层排序;

  2. 拦截引擎渲染结束事件,立即还原渲染前的节点树排序,从而实现无入侵式的合批优化;

  3. BatchItem 组件唯一的 Culling 属性是可选的,它会拿 Culling 属性所指定的矩形区,与容器中 item 矩形做相交测试,将不在 Culling 区的元素从渲染队列中剔除掉。

使用方法

「98K 动态分层合批」支持 Cocos Creator 3.x,开箱即挂即用无需添加任何代码。

优化技巧

  • Label 文字开启缓存模式,推荐 char 模式:

c79a6ac62b336ee9bf999fb6c5628d87.png

  • 开启自动合图或自定义图集:

macro.CLEANUP_IMAGE_CACHE = false;
dynamicAtlasManager.enabled = true;

开启自动合图

37b144244b38ffd782facb7bb70c2bd1.png

开启自定义图集

  • 开启范围剔除,减少不可视的计算。

设置 item 显示范围(cc.UITransform):

1d76d885189d8a1b38243af5eabb45af.png

设置剔除范围节点(cc.UITransform):

33d7a3f3efb920f5ff3e797aa2e30233.png

使用注意

  • 名字不能重复:item 下节点名字不能重复,保持唯一性,用于分层合批的收集和排序。

  • 名字顺序不能冲突:item 内节点名顺序不能和其他 item 内节点名顺序冲突,保持前后出现的顺序。

  • 相互不能重叠:item 相互之间不能重叠,分层合批会改变绘画顺序,相互重叠会产生 item 间显示层的冲突,需要避免这种使用情况。

版本支持情况

  • 原生支持情况:v3.5.x 以下支持全平台,v3.6.x 以上暂不支持原生。

  • 低版本使用方法:原默认工程是 v3.5.2,在 v3.5.2 以下版本使用时,请将 BatchItems.ts 复制到低版本工程上使用。

资源链接

  • 插件下载:

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

  • H5 版测试链接:

http://gameview.creator-star.cn/98K/batch-items/index.html


📢 福利时间!转发本文并在评论区留言,2月6日(下周一),我们将从评论区中随机抽选3名小伙伴,送出「98K 动态分层合批」免费兑换码1个!

往期精彩

cdd6a91b1120615f3f09eb9647f6427a.png

ceb02df56aa21e8c2a2b1afba89d89e1.png

ac6c1ce33c068cd62f2d2f80c644ab4b.png9c068bbececa1772ae1f0196e8205b8a.gif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值