对CocosCreatorr的Draw call的理解

Draw call比较直观的描述应该是: 在CPU不改变渲染数据的情况下,openGL的一次渲染。

opengGL的一次渲染:CPU调用图形绘制接口来使GPU执行渲染操作,渲染流程是CPU和GPU并行工作的过程。CPU和GPU之间通过一系列的缓冲区来联系,CPU将缓冲区的数据发送给GPU来让GPU执行渲染命令。

插一句:

大家如果对openGL的渲染流程感兴趣,可以参考https://blog.csdn.net/u013654125/article/details/79698469。

回到正题:

正因为CPU和GPU并行工作,所以会出现其中一方处理数据较慢,而另一方闲置的情况。而这种情况一般只会是CPU处理处理数据处理不过来,而GPU闲置。

来个栗子:

当你有A,B,C三个节点,其中A,B使用同一张贴图,C使用另一张贴图。

假设绘制顺序是:

A

C

B

这种情况的Draw call是:3。因为A绘制完和需要替换贴图,然后绘制B后再替换贴图,最后绘制C。

假设绘制顺序是:

A

B

C

那么可以做到A,B同时绘制,最后绘制C。

这时的Draw call是:2。

 

再详细点:

 

 


这样排就是8个Draw call。

这里如果我们把“闪”连续渲染,这样Draw call就是五个(ttf label不能连续合并)。 

 

总之,Draw call的规则是这样的:

1.render command 相邻,大致可以理解为节点树中顺序相邻

2.texture 一致

3.blend function 一致

3.shader program 一致

 

所以当我们要渲染的节点很多,且Draw call也多的时候,CPU需要在每次渲染的时候来进行数据处理,这时GPU闲置。

我们要避免这样的情况,就可以根据上述情况来着手,尽量把相同的节点放在相邻的节点树中。

最后,使用图集减少Draw call是有一定前提条件的(像上述条件),图集并不能减少Draw call,材质从哪里来的和glDrawElements次数没关系。

真正减少Draw call是需要多个连续绘制的节点使用同样的贴图时,可以一次性批量绘制

优化思路:

合理调整UI、节点排布,来源同纹理的优先渲染。

情况1:人物和影子是在同一个容器里处理,每一个容器就是一个人物,这种情况就会出现,渲染单位A,会使用两个图集套装图集+影子图集有两次drawcall。当渲染N个人物,就有N*2次drawcall。

情况2:把渲染影子拆出来,当渲染完所有人物后,再根据所有人物的位置,绘制影子。这种情况,渲染N个人物,只会有N+1次drawcall显然情况2的处理方式更优。

当每个人物还有名字、称号、血条等等元素,若这些元素是按照上面情况1的处理,那drawcall就有N*M次。把这些元素按照上面情况2的处理,显然可以减少大量的drawcall。

更详细的Drawcall可以参考一下https://www.jianshu.com/p/00913bbf3e86

posted @ 2018-11-22 18:24  小鱼2015  阅读(113)  评论(0)    收藏  举报