这可能是最简单粗暴的DrawCall优化方案!Cocos最新插件,一键实现多纹理合批

共 2167字,需浏览 5分钟

 ·

2022-06-02 17:55

引言:开发者「逐夜00」写的这款适用于 Cocos Creator 2.x 的多纹理合批插件 Multi UI,提供了一种简单粗暴的 DrawCall 优化方式。也许并不通用,但其实现思路依然值得大家参考与讨论。


多纹理合批插件 Multi UI


插件功能


先看看 Multi UI 对 DrawCall 的优化效果:


这个界面仅需2个 DC

这个界面包含各种 Label,仅需5个 DC


而这样的优化效果,不需要修改代码逻辑、不需要调整预制结构和图集,全都是普通界面制作完成后由插件 Multi UI 一键转换完成的:

  • Label 与 Sprite 合批;

  • 不同参数 Shader 不打断合批;

  • 一键转换预制体,一键优化 DrawCall。


PS:下载地址及在线演示地址见文末。


插件由来


众所周知,DrawCall 一直是影响游戏性能的一个关键点,论坛上也常有大佬分享 DrawCall 优化方案,目前一般的解决方案是:图集 + Bmfont,配合场景节点结构优化,可以大幅度降低 DrawCall。


但是 Bmfont 如果不和使用的图在一张图集里的话,还是存在 Label 打断 DC 的情况;而且图集之间也难免会有重叠,稍不注意就会多出 n 个 DC,尤其是在一些复杂的 UI 需求下,DC 还是会居高不下。


点击查看丨大城小胖《江南百景图》技术分享


而在看到大城小胖分享的《江南百景图》多纹理合批方案后,不得不佩服:大佬终究是大佬!


再加上最近灵光乍现,发现默认 cc.Label 与 cc.Sprite 所用的材质 Material 是一样的——那么,配合多纹理合批,我们是不是完全解决合批问题呢?


于是我开始研究引擎源码以及《江南百景图》的实现方式……


实现过程


cc.Label 与 cc.Sprite 使用的顶点数据格式是完全一致的,或者说大部分渲染组件用的顶点数据格式是一致的


所以为什么 Label 会打断渲染?因为普通的 Label 在渲染的时候,相当于会生成一张图,所以一个 Label 就是一个 DC,而其他类型的 Label 处理方式就不太一样了,比如 BMFont,因为本身就是从一张 Texture 里读取的,所以相互之间就可以合批。


《江南百景图》合批


而《江南百景图》的多纹理合批方案,核心其实是修改检测合批方法,由判断是否在同一张图集,转为判断是否在同一批图集


如果 Label 的 Material 与 Sprite 的 Material 一致,修改 Label 的顶点数据,将 Label 使用的图集也同样传递给 Material,让 Label 也可以使用多纹理合批方案,那么 Label 就可以与 Sprite 合批。


到这里都是我的猜想,真正是不是这样子,还得动手试试。在漫长的阅读引擎源码、试验、修 Bug、做兼容后,简单粗暴的多纹理合批插件 Multi UI 诞生了。


这个方案的核心就是多图集合批 + 动态合图 + 自定义顶点格式,目前只支持 MultiSprite 与 MultiLabel,继承于 cc.Sprite 与 cc.Label,修改了顶点数据填充,也就是说通过增加顶点数据内容,达到降低 DrawCall 次数的目标。


插件特点


个人认为,这是目前最简单粗暴的 DrawCall 优化方案,无需修改任何代码逻辑,Multi UI 插件将自动做合批逻辑。


1、无需配置,自动开启动态图集。

2、无侵入原有代码逻辑与场景结构,即插即用。

3、插件兼容性优化,拖到编辑器里无任何差别。

4、可以直接用于整个游戏,也可以用在某个 DC 较高的界面。

5、支持一键转换,选中需要转换的资源(场景、预制体或文件夹),右键运行对应的操作即可快速转换。

插件默认提供:

转换 Multi UI;

将 cc.Sprite 转换为 MultiSprite;

将 MultiSprite 转换为 cc.Sprite;

将 cc.Label 转换为 MultiLabel;

将 MultiLabel 转换为 cc.Label。

有了一键转换,那就更粗暴了。假设你现在已有的游戏需要优化,只需导入插件初始化,对需要优化的文件夹一键转换,即可实现 DrawCall 优化。

6、此外,默认预留了3个参数,可作为 Shader 参数传递,且不会像 Material 传递参数一样打断渲染合批。目前默认是用于 HSL,如演示案例。


注意事项


  • DrawCall 的降低不是没有代价的。首先渲染的顶点数据格式改了,需要填充与传递的数据变多了。其次 Shader 内对使用图集的判断次数,也是不可控的。如果节点可以不使用 color,可以考虑将改动的顶点数据,占用 color 的数据位,或者与 color 公用,这个可以自己去扩展了。

  • 使用前注意对项目进行备份,以免出现不必要的数据丢失。


资源下载


  • 点击文末【阅读原文】前往 Cocos Store 下载插件:

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


  • 在线演示:

https://cdn.hanyougame.cn/YHMultiUI/index.html


  • 论坛专贴:

https://forum.cocos.org/t/topic/134846


往期精彩

浏览 165
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报