失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 浅谈Batch(批次合并)

浅谈Batch(批次合并)

时间:2022-11-07 07:12:38

相关推荐

浅谈Batch(批次合并)

基础知识:

1.Drawcall:

CPU调用一次GPU的绘制函数成为一次Drawcall。

2.在执行一次Drawcall过程中,CPU的性能主要消耗在哪里?主要有两点:

CPU在调用绘制API后,会把指令转换成和设备无关的指令(这样就能做到在所有硬件设备上兼容了),这一转换产生开销,不过开销其实并不大。

主要的消耗在于当进行渲染状态切换时,CPU会从用户模式切换到内核模式,这一转换非常消耗性能。

所以,减少Drawcall次数,或者更精确点来说,减少Batch次数,就可以有效舒缓CPU的压力了~

3.什么时候需要进行渲染状态切换?

当材质不一致又或者pass不同的时候,就需要进行切换了。

4.如何减少Batch次数呢?

尽可能把相同材质的Batch合并成一个,一次性提交给GPU处理。

1.静态合批 Static Batching:

原理:在预处理阶段,把一些材质相同的模型的顶点统一变换到世界空间坐标下,并且新构建一个大的VB把数据保存下来,在绘制时,就会把这个大的VB提交上去,只需要设置一次渲染状态,再进行多次drawcall绘画出每个子模型。 所以Static Batching是不会减少drawcall的,但由于只修改了一次渲染状态依然可以减少CPU的消耗。而且在渲染前,也可以进行视锥体剔除,减少顶点着色器对不可见的顶点的处理次数,提交GPU的效率。

限制条件:

1.static顾名思义,不能修改他的transform属性(位置,旋转等)。

2.材质必须相同。

3.不能有超级大量的相同模型(如:森林里的树)

优点:无需额外使用CPU的算力,一次渲染命令就可以同时渲染出多个独立模型。

缺点:因为需要额外维护多一份数据,所以包体会变大,占用的内存也会变多(所以才会有上面说的限制条件3)

其实总的来说,Static Batching其实就是计算机里最经典的空间换时间,以此来提升渲染效率。

2.动态合批 Dynamic Batching:

原理:在每一帧运行时,计算相同材质的模型,把他合并批次进行渲染。动态合批只需要设置一次渲染状态,且能减少drawcall次数。

限制条件:

1.材质相同

2.顶点数不能过多

优点:动态顾名思义,可以修改transform的属性,而且因为实时计算结果,所以也不需要占用运行时内存和增大包体大小

缺点:每帧都要进行合批,每帧都得运算,CPU开销较大。

静态合批VS动态合批:

其实静态合批和动态合批实现的大致原理是差不多的,主要是进行合批的时间点不同,一个是在编译时处理,一个是在运行时处理。 但正因为处理时间点不同,最终也产生了具体的差别:

1.静态合批在编译时处理后需要占用储存空间把数据存储下来,而且运行时加载这些数据也会占用运行内存。

2.动态合批则每帧都需要进行大量计算来进行批次合并。但以为是实时计算出结果,所以也不会出现像静态合批那样,限制Object不允许修改transform的属性。

3.静态合批和动态合批都是在CPU端进行优化处理的。

3.实例化渲染GPU Instancing:

当有大量的Object,他们具有相同的Mesh和相同的Material时(例如花花草草,森林里的树木等),就可以使用GPU instancing了。因为对每个Object都会产生一个新的实例,所以可以对具体不同的实例设置不同的参数(如 color,scale)等。

4.SRP Batcher:

前三种处理方式的出发点基本都是为了减少Batch的次数,而SPR Batcher出发点却完全不同,SPR Batcher并不会减少Batch的次数,而是减少每个Batch所需要处理的工作。其工作原理就是在GPU中设置缓冲区,用于记录存储材质相关的数据,这样就可以减少CPU发送给GPU的数据量,减少Batch的工作量了。 当场景有大量的材质而仅有少量的shader时,使用这种方式可以大幅提升效率。

在文章的最后讲一个故事:

在一个星球上,有两块大陆,一块叫CPU,一块叫GPU,两块大陆通过一个桥梁连接着,桥梁每分钟同行一次。

假设CPU每分钟放行一辆车过桥,那么1小时车流量才60台.(估计此时CPU上大塞车都等着过桥了吧……)

那么假设CPU每分钟放行两台车过桥,1小时车流量就能达到120台;放行10台车,车流量就能达到600台。效率大大提升。

这时,CPU就在想,为了我这大陆上不堵车,我不限流了,把车子大量放行过桥,可这时,GPU处理不过来了……GPU开始堵车了,CPU的车子也过不去了……

这个故事告诉我们,当CPU忙不过来的时候,进行批次合拼,确实是可以提高效率减少性能瓶颈,可也不是说drawcall就一定是越小越好,如果当前性能瓶颈在GPU,那么即使减少了drawcall也不见得性能就有所提升。就好像假设我们在PC上玩游戏,PC的CPU运算速度足够快,减少drawcall也不会让游戏更流畅。现在的手机CPU芯片也越来越强大了,图形处理的技术也越来越成熟了(对性能的消耗降低了很多)。 对drawcall进行优化之前最好了解清楚你的游戏运行的平台,具体运行压力在CPU还是GPU,才能更合理的根据需求指定优化策略。

如果觉得《浅谈Batch(批次合并)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。