官网:https://docs.unity3d.com/Manual/GPUInstancing.html.
原文:http://hololens8.cn/thread-7463-1-1.html
Unity在5.4 Beta版本中引入了一种新的Draw Call Batching方式——GPU Instancing。当场景中有大量使用相同材质和网格的物体时,通过GPU Instancing可以大幅降低Draw Call数量。本文将由Unity官方开发工程师蔡元星,为大家简单介绍GPU Instancing的原理并引导读者修改已有的Shader来开启Instancing。
multi_compile_instancing”会使你的Shader生成两个Variant,其中一个定义了Shader关键字INSTANCING_ON,另外一个没有定义此关键字。
除了这个#pragma指令,下面所列其他的修改都是使用了在UnityInstancing.cginc里定义的宏(此cginc文件位于Unity_Install_Dir\Editor\Data\CGIncludes)。取决于关键字INSTANCING_ON是否被定义,这些宏将展开为不同的代码。
使用Instancing的限制
· 下列情况不能使用Instancing:
· 使用Lightmap的物体
· 受不同Light Probe / Reflection Probe影响的物体
· 使用包含多个Pass的Shader的物体,只有第一个Pass可以Instancing前向渲染时,受多个光源影响的物体只有Base Pass可以instancing,Add Passes不行
另外,由于Constant Buffer的尺寸限制,一个Instanced Draw Call能画的物体数量是有上限的(参见UnityInstancing.cginc中的UNITY_MAX_INSTANCE_COUNT)
最后需要再次强调的是,Instancing在Shader上有额外的开销,并不是总能提高帧率。永远要以实际Profiling的结果为准!
Shader "SimplestInstancedShader"
{
Properties
{
_Color ("Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
UNITY_INSTANCE_ID //用于在Vertex Shader输入 / 输出结构中定义一个语义为SV_InstanceID的元素。
};
struct v2f
{
float4 vertex : SV_POSITION;
UNITY_INSTANCE_ID
};
//UNITY_INSTANCING_CBUFFER_START(name) / UNITY_INSTANCING_CBUFFER_END
//每个Instance独有的属性必须定义在一个遵循特殊命名规则的Constant Buffer中。使用这对宏来定义这些Constant Buffer。“name”参数可以是任意字符串。
UNITY_INSTANCING_CBUFFER_START (MyProperties)
//定义一个具有特定类型和名字的每个Instance独有的Shader属性。这个宏实际会定义一个Uniform数组。
UNITY_DEFINE_INSTANCED_PROP (float4, _Color)
UNITY_INSTANCING_CBUFFER_END
v2f vert (appdata v)
{
v2f o;
//Instance ID在Shader函数里也能够被访问到
UNITY_SETUP_INSTANCE_ID (v);
//Vertex Shader中把Instance ID从输入结构拷贝至输出结构中
UNITY_TRANSFER_INSTANCE_ID (v, o);
o.vertex = UnityObjectToClipPos (v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID (i);
//访问每个Instance独有的属性。这个宏会使用Instance ID作为索引到Uniform数组中去取当前Instance对应的数据。
return UNITY_ACCESS_INSTANCED_PROP (_Color);
}
ENDCG
}
}
}