Rendering-drawcalls优化技术

什么是DrawCall?

drawcall是渲染一个物体所需要的指令集,由CPU像GPU发送,drawcall中会包含GUP渲染物体所的,  
如模型顶点数据,法线,纹理贴图等等渲染相关数据。cpu在发送指令期间是不能做其他事情的,这就形成主要的性能瓶颈之一。

推荐下方很有趣的学习资料链接

Render Hell – Book I

什么是Batching?

由于太多的drawcall,自然会有降低drawcall的说法。在unity中称为Batching,简单说就是通过一定的规则合并drawcall的技术,从而减少渲染调用的次数。

介绍Unity中的主要Batching技术

  1. Dynamic Batching:这是一种古老的技术,目前很多引擎都是支持的。主要的原理是合并通用相同材质(material)的小的网格(meshes)变成一个打的网格,替代原先的多个渲染调用。因此这项技术不适用网格顶点多的模型,比如球迷可能就需要谨慎考虑该技术了。 Static batching 的原理Dynamic Batching类似,只不过是在运行渲染前已经合并好,不像Dynamic是运行时即时合并的。

  2. SRP Batcher:这是Unity 2017.1版本引入的新技术。SRP Batcher不会减少Drawcall调用而是把他们变得精简,它会缓存某些渲染状态(材质,颜色,顶点等等)到GPU的某块内存中。所以就没必要把每一个drawcall都发送给GUP。但是对shader编写需要遵循严格的结构规则。比如需要在属性声明中按如下约定规则的结构体。

    1
    2
    3
    cbuffer UnityPerMaterial {
    float _MainColor;
    };
  3. GPU Instancing :单个drawcall一次渲染相同的网格(meshes)。需要把带渲染的数据包装成数组,一次性发送给GUP,GPU会遍历这个数组按照次序渲染所有的物体。当然shader的编写结构上会更加严格。在顶点和片元着色器上会多增加一个UNITY_VERTEX_INPUT_INSTANCE_ID,用来对应数据块的内存位置。下面我写了个例子看渲染1000+个物体,使用GPU Instancing只需要3个drawcall。