美文网首页
Batching和Instancing

Batching和Instancing

作者: 随便取个占位符 | 来源:发表于2021-11-04 14:21 被阅读0次

通常引擎一般会提供3种合批的方式: 静态合并,动态合并,实例化
那么3种合批的方法到底有什么区别呢,我们需要在何时使用对应的方法?

这里我们首选从底层驱动来说起,以OpenGL为例,绘制元素的API一般为:

glDrawElements 或者 glDrawArrays 

调用这些方法后,cpu会将顶点数据传入显存,之后由显卡进行绘制。
每次调用这些方法,我们称之为一个DrawCall
那么当多次调用这些方法时,会明显导致draw增多。
所以在优化游戏时,我们很多情况首先要做的就是进行DrawCall的优化。
为了解决DrawCall太多的问题,我们很容易想到的就是把相同材质的网格进行合并。
既然你的的材质是一样的,那么我合并网格后只要调用一次 glDrawElements 就只产生一个DrawCall,岂不美哉。
所以就有第一种合批的方法:

dynamic batching

动态合批是指在引擎的运行期,将同材质的模型合并为一个大的网格数据传输给显卡。

这种情况,需要耗费CPU来进行缓存的合并,对CPU是有一定影响的。而且由于数据较大,对带宽的要求也更好。

这就是为什么有的小伙伴合批和了半天,运行效率更低的原因。
因为一方面,CPU被拿去做合批运算耗费时间,另一方面带宽占用也变大了。

那么既然运行时合批会消耗CPU,那完全可以将在运行时不需要移动的物体进行离线合批嘛。
(离线合批:在非运行时进行合批。)
于是就引申出了第二种合批方式:

static batching

静态合批下,引擎会帮我们把选择好的网格(Mesh)合并成一个大的网格。
同理会帮我们将网格信息内的uv坐标,物体的纹理等进行重新计算和合并。

这种合并显而易见的好处是不占用运行时效率。
唯一的问题是,如果顶点过多,导致网格太大,那么传输效率就会降低,是一种比较影响带宽的做法。

Instancing

最后呢就是Instancing,既然我们怎么合批都会耗费cpu和带宽,那么我什么不把这些麻烦的事情交给gpu做呢?
毕竟gpu是擅长并行计算的,而绘制多个同样材质的物体本来就是一个并行的过程嘛。
因此驱动组织都提供了可以一次传输,多次绘制的方法,这种我们称为实例化(instancing)

instancing是底层驱动支持的一种特性,在OpenGl内方法一般为在绘制函数后面增加 Instanced
比如:

glDrawArrayInstanced
glDrawElementsInstanced

glDrawElementsInstanced为例可以明显看到他和glDrawElements 的区别


void glDrawElements(    GLenum mode,
    GLsizei count,
    GLenum type,
    const void * indices);

void glDrawElementsInstanced(   GLenum mode,
    GLsizei count,
    GLenum type,
    const void * indices,
    GLsizei primcount);

可以看到instanced的函数比普通的函数多出一个叫做 primcount参数,这个参数的作用是通知显卡在绘制这些顶点时,重复绘制的次数。

在绘制的shader内,我们可以通过访问 gl_InstanceID 来查看到底绘制到第几个实例了,因为我们每个实例的位置旋转缩放和顶点颜色可能不一样。

当然intancing也不是没有限制的,毕竟驱动商是在迭代的过程中才发现这样的需求的,因此对于低于OpenGL3.0的设备是不支持实例化的。
当然现在低于OpenGL3.x的设备比较少见了,可以比较放心的去实例化方式绘制。

废话不多说我们来看看各种合批的结果吧
(软件为Render Doc)

场景 没有合并批次
没有合并批次的情况下,DrawCall达到了230个 动态合并批次
而在我们进动态合批以后,DC减少到了179个,可以说效果显著。 实例化

当我们可以实例化以后,Instancing减少到了160了! 可喜可贺。

所以从上面的例子中我们可以看出,在渲染同样材质的物体时,我们应该尽量开启实例化,而由于静态合批可以将不同材质的物体合并到一起,因此静态合批实际上是优先级最高的一种合批方式。
如果你的场景中有大量同类物品确不能静态合批,那么可以试试动态合批。

最后我们可以得到如下结论:

静态合批 > Instancing > 动态合批

如何在Cocos Creator中开启batching和合批。
我们只需要在材质内进行勾选就可以了。

batching or instancing

相关文章

  • Batching和Instancing

    通常引擎一般会提供3种合批的方式: 静态合并,动态合并,实例化那么3种合批的方法到底有什么区别呢,我们需要在何时使...

  • unity的合批

    unity的合批有两种:静态合批(Static batching)和动态合批(Dynamic batching)。...

  • 【转】UNITY GPU INSTANCING: UNLIT I

    Unity GPU instancing allows you to duplicate meshes witho...

  • 2018年面试题总结

    1.ui中的batching一个红色一个蓝色怎么合并它们? batching:批处理 打图集,合并材质 2.2个...

  • GPU Instancing

    作用: 批渲染Mesh相同的那些物体,以降低DrawCall数 这些物体可以有不同的参数,比如颜色与缩放 GPU ...

  • 序列模型的分批策略,bucketing

    Comprehensive Hands-on Guide to Sequence Model batching s...

  • Mini-batching

    Mini-batching 是一个一次训练数据集的一小部分,而不是整个训练集的技术。它可以使内存较小、不能同时训练...

  • 04-flink和sparkStreaming比较

    一、流(stream)和微批(micro-batching) 思想:只要批次足够小,则实时性更好,需要攒批数据然后...

  • 使用GPU Instancing屏幕花屏问题

    1)使用GPU Instancing屏幕花屏问题2)如何优化AssetBundle大小3)如何使用GPU Skin...

  • GPU Instancing 功能测试

    GPU Instancing 用于减少渲染大量相同物体时的DrawCall,同样减少DrawCall的方式有 Dy...

网友评论

      本文标题:Batching和Instancing

      本文链接:https://www.haomeiwen.com/subject/fbhkzltx.html