【ShaderLab學習】RenderType理解
RenderType
在Unity Shader中會經常在SubShader中使用Tags,其中就會涉及RenderType。
SubShader{
Tags{ "RenderType" = "Opaque" }
...
}
內建的RenderType標籤:
- Opaque: most of the shaders (Normal, Self Illuminated, Reflective, terrain shaders). 用於大多數著色器(法線著色器、自發光著色器、反射著色器以及地形的著色器)。
- Transparent: most semitransparent shaders (Transparent, Particle, Font, terrain additive pass shaders). 用於半透明著色器(透明著色器、粒子著色器、字型著色器、地形額外通道的著色器)。
- TransparentCutout: masked transparency shaders (Transparent Cutout, two pass vegetation shaders).
- 蒙皮透明著色器(Transparent Cutout,兩個通道的植被著色器)。
- Background: Skybox shaders. 天空盒著色器。
- Overlay: GUITexture, Halo, Flare shaders. 光暈著色器、閃光著色器。
- TreeOpaque: terrain engine tree bark. 地形引擎中的樹皮。
- TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的樹葉。
- TreeBillboard: terrain engine billboarded trees. 地形引擎中的廣告牌樹。
- Grass: terrain engine grass. 地形引擎中的草。
- GrassBillboard: terrain engine billboarded grass. 地形引擎何中的廣告牌草。
功能說明
Unity可以執行時替換符合特定RenderType的Shader。主要通過Camera.RenderWithShader或者Camera.SetReplacementShader這兩個介面來實現。
Camera.RenderWithShader
public void RenderWithShader(Shader shader, string replacementTag);
Camera.SetReplacementShader
public void SetReplacementShader(Shader shader, string replacementTag);
兩個介面的區別
RenderWithShader與SetReplacementShader的區別是RenderWithShader是 當前幀 用指定的Shader渲染,SetReplacementShader是替換後的 每一幀 用指定的Shader渲染。
當把程式碼SetReplacementShader換成RenderWithShader發現沒什麼效果,主要是因為RenderWithShader是當前幀用指定的Shader渲染,要與SetReplacementShader同樣的效果,必須每幀都呼叫RenderWithShader。注意必須在OnGUI
函式裡呼叫。
功能驗證
呼叫Camera.SetReplacementShader(Shader,"RenderType")
時,相機會使用指定的Shader來替代場景中的其他Shader來對場景進行渲染。
比如現在有以下幾個Shader:
Shader "Shader1"{
Properties(···)
SubShader{
Tags{ "RenderType"="Opaque" }
Pass = {···}
}
SubShader{
Tags{ "RenderType"="Transparent" }
Pass = {···}
}
}
場景中一部分物體使用的是Shader2:
Shader "Shader2"{
Properties(···)
SubShader{
Tags{ "RenderType"="Opaque" }
Pass = {···}
}
}
另一部分物體使用的是Shader3:
Shader "Shader3"{
Properties(···)
SubShader{
Tags{ "RenderType"="Transparent" }
Pass = {···}
}
}
用法1
呼叫以下方法(引數2為""):
Camera.SetPlacementShader(Shader1, "");
執行程式碼之後,場景中的所有物體都使用Shader1進行渲染。
用法2
如果第二個引數不為空,如:
Camera.SetPlacementShader(Shader1, "RenderType");
這種情況下,首先在場景中找到標籤中包含該字串(這裡為“RenderType”)的Shader,再去看該字串對應的數值是否與Shader1中該字串的值一致,如果一致,則替代渲染,否則不渲染。
上面幾個Shader的程式碼,由於Shader2中包含"RenderType"=“Opaque”,而且Shader1中的第一個SubShader中包含"RenderType"=“Opaque”,因此將Shader1中的第一個SubShader替換場景中的所有Shader2,同理,將Shader1中的第二個SubShader替換場景中的所有的Shader3。
用法3
另外,也可以自定義第二個引數,Shader程式碼如下:
Shader "Shader1"{
Properties(···)
SubShader{
Tags{ "RenderType"="Opaque" "CheckRenderTypeTag="On" }
Pass = {···}
}
SubShader{
Tags{ "RenderType"="Transparent" "CheckRenderTypeTag="Off" }
Pass = {···}
}
}
Shader "Shader2"{
Properties(···)
SubShader{
Tags{ "RenderType"="Opaque" "CheckRenderTypeTag="On" }
Pass = {···}
}
}
Shader "Shader3"{
Properties(···)
SubShader{
Tags{ "RenderType"="Transparent" "CheckRenderTypeTag="Off" }
Pass = {···}
}
}
呼叫以下方法:
Camera.SetReplacementShader(Shader1, "CheckRenderTypeTag");
最後的結果是,Shader1的第一個SubShader將會替換Shader2和Shader3(因為“CheckRenderTypeTag”對應的數值匹配)。