1, 概念:
GPUInstasncing 是优化drawcall的方法,它可以在单独的drawcall中渲染多个具有相同材质的网格副本。每个网格的副本称为一个实例。这在一个场景中绘制出现多次的物体非常有用。 比如,树木或灌木。
GPU instancing 在一个相同的Drawcall中渲染相同的网格。为了增加变化减少重复,每个示例可以有不同的属性,比如颜色或缩放。在frameDebugger中渲染多个实例的drawcall称为drawmesh.
2,平台限制
除了WebGL 1.0外,GPUinstancing在每个平台都可用。
Note:只有当Shader和SRPBatcher不兼容时:
3,SRP Batcher
GPU instancing和SRPBatcher不兼容,SRP Batcher优先于GPU instancing。如果某个物体符合SRPBatcher的兼容条件,unity将使用SRPBatcher而非SRP Batcher来渲染它. 如果你的项目使用了SRPBatcher,而你针对某个物体使用GPU instancing,你可以按照下面的方法去做:
1,使用Graphics.DrawMeshInstanced。这个API会绕过物体本身用的方式,并使用具体的参数直接在屏幕上绘制一个网格。
2,手动去掉SRPBatcher的兼容。关于这个怎么做的信息,请参看Intentionally removeing compatibility.
4,使用 GPU instancing
unity针对那些共享了相同网格和材质的物体使用GPU instancing. 下面举例说明这样的网格和材质:
1,这个材质的Shader必须支持GPU instancing。unity的Standard Shader支持GPU instancing, 所有的suerface shader也一样。为了让任何其他Shader都添加GPU instancing的支持。
参见Create Shaders that Support GPU instancing[后续加链接]
2, 网格必须来自如下来源之一,通过行为分组:
(1),通过meshrender或者Graphics.RenderMesh调用的。行为机制:unity会把这些mesh添加到一个列表然后检测符合实例化条件的对象。
unity不支持GPU instancing的情况:
SkinnedMeshRenderers
已兼容SRPBather的物体上的MeshRenderer组件
(2), 通过Graphics.RenderMeshInstanced或Graphics.RenderMeshIndirect方法调用的。这些方法对使用相同Shader的同一网格渲染了多次。每次对这些方法的调用都会产生独立的DrawCall。
unity不会合并这些drawcall。
针对一个材质使用GPU instancing,选择Enable GPU instancing来开启。
5,光照
GPU instancing 支持unity的烘焙全局光照系统。unity Standard Shaders和Surface Shaders支持GPU instancing 并且默认支持unity的烘焙全局光照。
每个GPU instancing 都支持下列来源之一的全局光照:
1,任何数量的Light Probes
2, 光照贴图
Note:单个实例可以引用光照贴图的多个实例
3,Light Probe Proxy Volume(LPPV)组件
Note:必须为包含所有实例的空间体积烘焙LPPV
GPU instancing自动兼容以下内容:
1,被light probe影响的动态Mesh Renderers
2,static Mesh renderer 可被烘焙到同一张光照贴图上去。此文中提到的MeshRenderer是static 指的是在Static Editor flags中包含了Contribute GI 选项。如下图所示:
6,性能影响因素:
那些有少量顶点的网格在使用GPU instancing时不是很有效果的。因为GPU不能以充分使用GPU资源的方式来分配工作。这种低效的处理方式可能对性能有不利影响。低效开始的阈值取决于GPU。
一般来说,对于顶点数少于256的网格来说就不使用GPU instancing了。
如果你想多次渲染一个低顶点数的网格,最好的做法是创建一个包含所有网格信息的缓冲区,并使用它来绘制网格。