讨论一下 Drawcall 优化,大家来围观

Drawcall 是衡量性能的一项重要指标,那么开发者应该很注重Drawcall的优化,严格遵从引擎的渲染规则进行优化。
目前优化Drawcall主要方式在于图集:
制作图集,可以有效的减低Drawcall,但不同图集之间会打断Drawcall的合并。
假设有A、B、C 三张图集。
节点结构1: AAABBBCCC,这样的排序下会产生3个Drawcall;
节点结构2: ABCABCABC,这样的排序下会产生9个Drawcall;
那么我们在制作过程中节点的排序需要尽量保证相同材质按照 结构1 紧挨着渲染,避免交叉渲染导致Drawcall无法合并。
但实际项目中有很多功能没办法按照 结构1 的方式排列,比如卡牌库、排行榜,通常会把Item制作成预制物,然后动态创建多个Item,这样的结构将是:
Item:AAABBBCCC
Item:AAABBBCCC
Item:AAABBBCCC
Item:AAABBBCCC
Item数量越多,Drawcall数量将成倍增长,以上将会产生12个Drawcall,希望这里无论多少个Item只产生3个Drawcall,这种奢求显然很难实现。

引擎能不能通过某种算法把那些同图集且显示不互相影响的节点合并Drawcall提交渲染?
或者是否能提供一个标记接口?让开发者可以自己标记那些节点进行批处理,默认不标记则按照现有的规则进行处理。

对于这一块,大家怎么想的?引擎底层还可以进行一波优化吗?

@jare @panda @Knox

1赞

很有想法啊

没人对这块有想法吗:sweat:

label注意一下,这个坑有点深

你会发现 laya做了

好像看到laya在编辑器中好像有这个标记

滚动列表的时候才会出现这个情况,一般同屏幕也只显示一个滚动列表,一百多Drawcall没影响

这可不一定,一个界面多个滚动列表的情况也是有的,而且一个Item里面用到的图集有可能会比较多的情况,那一定Item数量多了,Drawcall就会很多的。

我建议滚动你做视觉区域裁剪,把看不到的节点隐藏,这样的优化效果才是最好的

是的。
一般的Label都会使用BMFont,每一个Label就会占用一个Drawcall,一般Item里面都会包含有几个Label,比如等级、名称、属性,有些情况这些Label还没办法紧挨着放,对结构和位置有其他要求,但它们显示是不被其它元素遮挡的,希望这种情况下它们能够批量渲染。

这种肯定是要做的,也是有那么做的,但还是有部分功能表现在同一个可视界面里面就包含了比较多的Item

我也期待引擎有这个功能
换个思考方式安慰一下楼主

因为性能损耗高
→用户需要买高性能的手机
→促进国人的消费
→促进了国内手机厂商的快速发展
→促进了科技的进步
→历史,文明,进化
难道这就不是cocos(小米)对整个中国,对整个世界的贡献吗?:2::2::2: ——出自小米9发布会

3赞

不要为了优化drawcell 而优化drawcell, drawcell 一般在 20 - 30 应该就差不多。 并不是说drawcell 越低,越好。

巨深!!

肯定不是为了追求drawcall数值小而优化啊,而是为了追求更好的流畅度、省电、低发热量,让用户有更好的体验。
如果整个游戏drawcall平均保持在你说的20 - 30左右,那性能一定非常好。但现在稍微复杂一点的功能很容易突破百个Drawcall,而在那些非全屏功能互相叠加的情况下drawcall就容易上升到几百个。

2赞

围观中

BMFont这个坑碰上了还没解决,为场景中每个元素添加了一个BMFont 文字,active为false,发现内存比不加的时候居然多了一倍!场景元素也并不多,二三百个,因为这个不得不改变了游戏逻辑

不是所有地方动合适用BMFont的,比如剧情对话。
资源是需要手动卸载后才能够释放出内存的,不要以为destroy了就内存就自动回来了。

因为对引擎渲染这部份没有很熟悉,
但我有一个疑问,虽然还没有实际测试过

假设我在创建prefab的时候,动态的把所有的节点平铺在第一层,再加入parent节点,
这样是否对DrawCall有帮助呢?

当然假设有mask之类的东西,就不能这么做了…

改变parent就改变了渲染顺序了,不可行的。
节点平铺可以达到优化drawcall的效果,但开发功能很不方便,根本做不到的。你想象一下编辑器的节点没有子父节点关系,你还能不能好好做游戏了。

1赞