Unite 2016|Unity 5.4的GPU Instancing功能简介
Instancing能做什么:
通过减少Draw Call数量来降低CPU开销。
Instancing不能做什么:
减少GPU的负载。实际上,Instancing还会在GPU上带来一些额外的开销。
有大量使用相同材质和相同网格的物体
性能受制于过多的Draw Call (图形驱动在CPU上负载过大)
类似于Static / Dynamic Batching,Instancing是一种新的合并Draw Call的方式
适用于MeshRenderer组件和Graphics.DrawMesh()
需要使用相同的Material和Mesh
需要把Shader改成Instanced的版本
当所有前提条件都满足时,Instancing是自动进行的,并且比Static/Dynamic Batching有更高的优先级
Instancing的实现步骤如下:
将Per-Instance Data(世界矩阵、颜色等自定义属性)打包成Uniform Array,存储在Instance Constant Buffers中
对于可以使用Instancing的Batch,调用各平台图形API的Instanced Draw Call,这样会为每一个Instance生成一个不同的SV_InstanceID
在Shader中使用SV_InstanceID作为Uniform Array的索引获取当前Instance的Per-Instance Data
“multi_compile_instancing”会使你的Shader生成两个Variant,其中一个定义了Shader关键字INSTANCING_ON,另外一个没有定义此关键字。 除了这个#pragma指令,下面所列其他的修改都是使用了在UnityInstancing.cginc里定义的宏(此cginc文件位于Unity_Install_Dir\Editor\Data\CGIncludes)。取决于关键字INSTANCING_ON是否被定义,这些宏将展开为不同的代码。 UNITY_INSTANCE_ID
用于在Vertex Shader输入 / 输出结构中定义一个语义为SV_InstanceID的元素。 UNITY_INSTANCING_CBUFFER_START(name) / UNITY_INSTANCING_CBUFFER_END
每个Instance独有的属性必须定义在一个遵循特殊命名规则的Constant Buffer中。使用这对宏来定义这些Constant Buffer。“name”参数可以是任意字符串。 UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
定义一个具有特定类型和名字的每个Instance独有的Shader属性。这个宏实际会定义一个Uniform数组。 UNITY_SETUP_INSTANCE_ID(v)
这个宏必须在Vertex Shader的最开始调用,如果你需要在Fragment Shader里访问Instanced属性,则需要在Fragment Shader的开始也用一下。这个宏的目的在于让Instance ID在Shader函数里也能够被访问到。 UNITY_TRANSFER_INSTANCE_ID(v, o)
在Vertex Shader中把Instance ID从输入结构拷贝至输出结构中。只有当你需要在Fragment Shader中访问每个Instance独有的属性时才需要写这个宏。 UNITY_ACCESS_INSTANCED_PROP(_Color)
访问每个Instance独有的属性。这个宏会使用Instance ID作为索引到Uniform数组中去取当前Instance对应的数据。 最后我们需要提一下UnityObjectToClipPos:
在写Instanced Shader时,通常情况下你并不用在意顶点空间转换,因为所有内建的矩阵名字在Instanced Shader中都是被重定义过的。比如unity_ObjectToWorld实际上会变成unity_ObjectToWorldArray[unity_InstanceID];UNITY_MATRIX_MVP会变成mul(UNITY_MATRIX_VP, unity_ObjectToWorldArray[unity_InstanceID])。注意到如果直接使用UNITY_MATRIX_MVP,我们会引入一个额外的矩阵乘法运算,所以推荐使用UnityObjectToClipPos / UnityObjectToViewPos函数,它们会把这一次额外的矩阵乘法优化为向量-矩阵乘法。
使用Lightmap的物体
受不同Light Probe / Reflection Probe影响的物体
使用包含多个Pass的Shader的物体,只有第一个Pass可以Instancing
前向渲染时,受多个光源影响的物体只有Base Pass可以instancing,Add Passes不行
最后需要再次强调的是,Instancing在Shader上有额外的开销,并不是总能提高帧率。永远要以实际Profiling的结果为准!
Windows: DX11 / DX12 with SM 4.0 and up
OS X & Linux: OpenGL 4.1 and up
PlayStation 4
移动平台和其他主机平台会在后续版本支持
到这里下载:http://unity3d.com/unity/beta
所有人都可以使用(包括Personal Edition用户)
反馈意见请到:http://forum.unity3d.com/forums/5-4-beta-forum.97/
关于Instancing的详尽文档:https://docs.google.com/document/d/1RS6cVjE8mBVOKqQUuXbaZcPW3kmw3ZWySJwr-5rDwSs/edit?usp=sharing
Unite 2016|Unity 5.x编辑器新功能Frame Debugger
Unite 2016|Asset Store流行插件之“实用小工具”
关于GPU Instancing的简单介绍及使用就分享到这里,感兴趣的朋友可以点击[阅读原文]查看详尽文档。