1. 程式人生 > >【ShaderLab學習】RenderType理解

【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”對應的數值匹配)。

參考: