Shader "Tut/Lighting/FirstLight/Lab_1/Deferred" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } Blend One One CGPROGRAM #pragma surface surf MyDeferred half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light) { half4 c; c.rgb = s.Albedo; c.a = s.Alpha; return c; } struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutput o) { o.Albedo=float3(1,0,0); } ENDCG } }再就是Deferred_Forward.shader,这是一个包含可以适应Deferred以及Forward渲染路径的材 质,其中适应Deferred的部分输出(1 ,0, 0, 1)的红色,而适应Forward的部分只会输出的(0, 1, 0, 1)绿色;两个部分都使用了Blend One One混合模式,也就是说如果两部分都执行的话, 应该会输出(1, 1, 0, 1)的黄色,反之则只会输出被执行的那一个的输出颜色,也就是红色或 者绿色。其代码如下:
Shader "Tut/Lighting/FirstLight/Lab_1/Deferred_Forward" { SubShader { Blend One One //.1 pass{ Tags{ "LightMode"="ForwardBase"} Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct vertOut{ float4 pos:SV_POSITION; float4 color:COLOR; }; vertOut vert(appdata_base v) { vertOut o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.color=float4(0,1,0,1); return o; } float4 frag(vertOut i):COLOR { return i.color; } ENDCG }//end pass //.2 CGPROGRAM #pragma surface surf MyDeferred half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light) { half4 c; c.rgb = s.Albedo; c.a = s.Alpha; return c; } struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutput o) { o.Albedo=float3(1,0,0); } ENDCG } }然后是Deferred_Forward_Vertex.shader,这个Shader和上面的Deferred_Forward.shader类似, 不同的是添加了可以适应VertexLit渲染路径的Pass,会输出蓝色。也就是说,如果3个都执行, 则会输出白色(1,1,1,1),否则会输出红、绿、蓝3个颜色的一个或两个的组合。其代码如一下:
Shader "Tut/Lighting/FirstLight/Lab_1/Deferred_Forward_Vertex" { SubShader { Blend One One //.1 pass{ Tags{ "LightMode"="Vertex"} Blend One Zero CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct vertOut{ float4 pos:SV_POSITION; float4 color:COLOR; }; vertOut vert(appdata_base v) { vertOut o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.color=float4(0,0,1,1); return o; } float4 frag(vertOut i):COLOR { return i.color; } ENDCG }//end pass //.2 pass{ Tags{ "LightMode"="ForwardBase"} Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct vertOut{ float4 pos:SV_POSITION; float4 color:COLOR; }; vertOut vert(appdata_base v) { vertOut o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.color=float4(0,1,0,1); return o; } float4 frag(vertOut i):COLOR { return i.color; } ENDCG }//end pass //.3 CGPROGRAM #pragma surface surf MyDeferred half4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light) { half4 c; c.rgb = s.Albedo; c.a = s.Alpha; return c; } struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutput o) { o.Albedo=float3(1,0,0); } ENDCG } }最后还有Deferred_Vertex.shader,这是一个含有可以适应Deferred和VertexLit模式的材质。 和Deferred_Forward_Vertex.shader类似,只不过去掉了适应Forward渲染路径的部分。还有 Forwardes_Vertex.shader,这个Shader去掉了适应Deferred模式的部分,还有单独适应Forward渲 染路径的Forward.shader,以及单独适应VertexLit渲染路径的Vertex.shader。其具体实现都很简单, 但是所有针对Deferred渲染路径的Pass最终都会输出红色(1, 0, 0, 1),所有针对Forward渲 染路径的Pass最终都会输出绿色(0, 1, 1, 1),所有针对VertexLit渲染路径的Pass最终都会输 出蓝色(0, 0, 1, 1)。
首先切换Camera到VertexLit模式下,如图所示。可以看到只有含LightMode = Vertex的Pass会被执行,并输出蓝色,其他的都没有被执行。
5.1.5 Forward渲染路径下Pass的执行切换相机到Forward渲染路径,可以看到如图所示的结果。凡是包含了针对Forward渲染路径的Pass都会被执行,并输出相应的绿色。如果没有包含针对Forward渲染路径的Pass,但是包含了针对VertexLit渲染路径的Pass,则也会被执行,并输出相应的蓝色。但是如果有Forward渲染路径的Pass可执行,就不会执行VertexLit渲染路径的Pass。针对Deferred渲染路径的Pass不会被执行。
5.1.6 Deferred渲染路径下Pass的执行再切换相机到Deferred渲染路径下,可以看到如图所示的结果。所有材质,凡是包含了针对Deferred的Pass可执行,则执行Deferred的Pass,并输出红色,其他Pass不会被执行。如果不包含针对Deferred的Pass,而且材质包含了Forward的Pass,则执行针对Forward设计的Pass输出相应的绿色。如果材质既没有针对Deferred的Pass,也没有针对Forward的Pass,则会执行Vertex的Pass,并输出蓝色。
5.1.7不同渲染路径下的Pass执行规则总结