照明

不同的光照模型被选择的顺序
渲染路径和pass的LightMode标签
Unity支持3种RenderingPath,分别是VertexLit,Forward,和Deferred Lighting。Pass中使用的LightMode标签Vertex,ForwardBase,ForwardAdd,PrepassBase,PrepassFinal,表示当前Pass是为在哪一个RenderingPath下设计使用的。
设计一个只会在摄像机单位渲染路径为Deferred模式下才会输出红色的Shader

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
    }

照明_第1张图片

再就是Deferred_Forward.Shader,包含可以适应Deferred以及Forward渲染路径的材质,适应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
    }

照明_第2张图片
然后是Deferred_Forward_Vertex.Shader,这个Shader添加了可以适应VertexLit渲染路径的pass会输出蓝色,如果三个都执行就是混合色白色。

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
    }

照明_第3张图片
最后还有Deferred_Vertex.Shader与上面的类似不过去掉了Forward渲染路径的部分,还有去掉Deferred部分的Forward_Vertex.Shader。以上的Shader所有针对Deferred渲染路径的Pass最终都会输出红色,Forward的Pass输出绿色,VertexLit最终输出蓝色。
总结:Unity在VertexLst渲染路径下,只会寻找可在VertexLit渲染模式下的Pass然后返回。在Deferred渲染路径下,则先寻找可在Deferred渲染模式下的Pass并返回,如果找不到,则会寻找Forward模式下的Pass并返回,如果依然没找到,则会寻找VertexLit模式下的Pass并返回。在Forward渲染路径下,会优先寻找Forward模式下可渲染的Pass,如果找不到寻找VertexLit模式下可渲染的Pass。
除了传统的3个渲染路径之外,Pass的LightMode标签还可以设置为Always或者不设置。
下面代码用于输出绿色

SubShader {
        pass{
        Tags{ "LightMode"="Always"}
        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
    }

然后是Deferred_Always,有一个针对Deferred渲染路径的表面着色器,其次是一个Always Pass,混合模式是Blend One Zero。如果Always在Surface Shader之后执行,就会只显示自己输出的绿色,反之输出混合之后的黄色

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

        pass{
        Tags{ "LightMode"="Always"}
        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,1,0,1);
            return o;
        }
        float4 frag(vertOut i):COLOR
        {
            return i.color;
        }
        ENDCG
        }//end pass
    }

针对VertexLit渲染路径的Shader中,Always Pass的执行和在代码中的位置有关系,在代码中靠前,则先执行,然后被混合模式为Blend One One的Vertex Pass中输出红色混合为黄色,在代码中靠后则后执行,混合模式为Blend One Zero所以输出是绿色。到Forward模式下,Always Pass也是按照在代码中位置来执行。而Deferred模式下,Always pass不执行现实的结果就是表面着色器的结果。如果没有设置光照模型,跟Always的一样。

你可能感兴趣的:(unity3d)