YH Multi UI
此贴给大家带来的是一个 非常简单粗暴的一个 DrawCall优化方案,文笔较差,大佬们凑合看
先看图
==》DrawCll 从 27 到 3
==》DrawCll 从 58 到 5
这里面还包含调试信息所占用的1个DC。
好,怎么做优化的呢,大佬们对这方面肯定都是很有心得的,论坛上也有各类的优化方案。
而我只需要10秒钟,4步,简单粗暴。
-
1.导入插件
-
2.初始化
-
3.点击操作转换UI
-
4.预览
正常的优化方案我可以通通不使用就能达到这个效果!
-
不需要修改代码逻辑
-
不需要调整预制结构
-
不需要调整图集
DrawCall优化全都由插件代码完成
这个界面仅仅需要2个DC
而这个界面结合了各种Label,只需要5个DC
里面可以查看对比,全都是普通界面制作完成后由插件一键转换完成的。
想看演示地址,这里可以直接查看
接下来简单介绍一下插件
YH Multi UI
插件由来
众所周知,DrawCall一直是影响游戏性能一个关键点。
论坛上也有各位大佬分享的 DrawCall优化方案。
目前一般的解决方案是,图集 + Bmfont,配合场景节点结构优化,可以大幅度降低DrawCall。
但是Bmfont如果不和使用的图在一张图集里的话,还是存在Label打断DC的情况
而且图集之间也难免会有重叠,稍不注意就会多出n个DC。
尤其是在一些复杂的UI需求下,DrawCall还是会居高不下。
在看到大佬分享的 《江南百景图》的多纹理合批方案后,不得不佩服 大佬终究是大佬
如此多图集的相互之间产生的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,做兼容,真是太难了。。。
方案核心是 多图集合批 + 动态合图 + 自定义顶点格式
于是 MultiUI 出来了,目前只支持MultiSprite 与 MultiLabel,继承于cc.Sprite 与cc.Label,大部分常用的功能都测试正常。
无论场景节点顺序多么乱,图集多么复杂,MultiUI都能最大限度的降低DrawCall。
无需修改任何代码逻辑,使用也相当粗暴无脑,也很符合我当时对这个的构想。
正常继承引擎组件,编辑器显示都有点不正常,这里我都做了兼容,拖到编辑器里无任何差别。
只要使用 MultiUI,就会自动做合批逻辑,可以游戏整体使用,也可以在部分DC较高的界面使用。
插件特点
恬不知耻的说,这是目前最简单粗暴的DrawCall优化方案
简单的游戏,一个游戏一个DC,完全不是问题
为什么说最简单最粗暴呢,除了无需修改任何代码逻辑以外。
其他的优化方案,都是告诉你怎么去优化,怎么才能降低DC。
而MultiUI不一样,你甚至可以不用关心怎么去实现,怎么去优化,你直接用,自然DC就降下来了!
而且支持 一键转换
插件默认提供操作:
-
转换MultiUI
-
将 cc.Sprite 转换为 MultiSprite
-
将 MultiSprite 转换为 cc.Sprite
-
将 cc.Label 转换为 MultiLabel
-
将 MultiLabel 转换为 cc.Label
直接右键选中资源(场景 预制 或文件夹),选择需要进行的操作
【选中】 需要转换的 场景 或 预制体 或 文件夹 ,【右键】运行对应的操作
这些操作,可以帮你快速转换组件!
如 转换MultiUI,选中资源 后,点击运行,待操作完成后,该资源内的cc.Sprite 与cc.Label,都被转换成MultiUI了
有了一键转换,那就更粗暴了,前期可以完全不用,游戏开发完成之后,或者现在已经有个游戏了。
游戏需要优化,那么导入插件初始化,对需要优化的文件夹一键转换,DrawCall就已经优化完成了。
除此之外,默认预留了3个参数,可作为Shader参数传递,且不会像Material传递参数一样打断渲染合批。
目前默认是用于HSL,如演示案例。
注意事项
当然DrawCall的降低不是没有代价的。
首先渲染的顶点数据格式改了,需要填充与传递的数据变多了。
其次shader内对使用图集的判断次数,也是不可控的。
如果节点可以不使用color,可以考虑将改动的顶点数据,占用color的数据位,或者与color公用,这个可以自己去扩展了。
使用前注意对项目进行备份,以免出现不必要的数据丢失
后续版本计划
-
1.看能不能支持骨骼合批
-
2.兼容适配3.x
-
3.考虑增加 性能模式,减少顶点数据,降低性能开销
插件地址
插件已上传到Cocos商店
1.0.2版本更新内容:
1.支持RichText (尝鲜版,因内部实现会有错误提示,不影响使用,后期版本优化)