Unity內(nèi)置Shader解讀11——VertexLit

1.Shader在什么情況下使用

VertexLit作為大部分shader的FallBack,實現(xiàn)了基礎的光照斩披、Lightmapped和陰影三個Pass。

2.Shader的價值(用的多不多),Shader的難度

直接用的可能不多厕氨,但絕大部分shader最終都FallBack到了這里坝辫,難度中篷就,陰影部分還沒搞清楚

3.代碼詳細注釋

Shader "Legacy Shaders/VertexLit" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)//鏡面反射
        _Emission ("Emissive Color", Color) = (0,0,0,0)//自發(fā)光
        [PowerSlider(5.0)] _Shininess ("Shininess", Range (0.01, 1)) = 0.7//光澤度
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100

        // Non-lightmapped
        Pass {
            Tags { "LightMode" = "Vertex" }
            //使用最基礎的渲染模式Fixed Shader實現(xiàn)基礎效果
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On
            SeparateSpecular On
            SetTexture [_MainTex] {
                constantColor (1,1,1,1)
                Combine texture * primary DOUBLE, constant // UNITY_OPAQUE_ALPHA_FFP
            }
        }

        // Lightmapped
        Pass
        {
            Tags{ "LIGHTMODE" = "VertexLM" "RenderType" = "Opaque" }

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #include "UnityCG.cginc"
            #pragma multi_compile_fog
            #define USING_FOG (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))

            float4 unity_Lightmap_ST;
            float4 _MainTex_ST;

            struct appdata
            {
                float3 pos : POSITION;
                float3 uv1 : TEXCOORD1;
                float3 uv0 : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float2 uv2 : TEXCOORD2;
                #if USING_FOG
                    fixed fog : TEXCOORD3;
                #endif
                float4 pos : SV_POSITION;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert(appdata IN)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(IN);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

                //獲取Lightmap的UV
                //將模型頂點的uv和Tiling、Offset兩個變量進行運算近忙,計算出實際顯示用的頂點uv
                //乘以Tiling再加Offset
                o.uv0 = IN.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
                //o.uv1完全沒有使用到竭业,不知道這里寫了有啥用智润,知道大佬麻煩告知下
                o.uv1 = IN.uv1.xy * unity_Lightmap_ST.xy + unity_Lightmap_ST.zw;
                //獲取主紋理的UV
                o.uv2 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;

                #if USING_FOG
                    //轉到View空間下
                    float3 eyePos = UnityObjectToViewPos(IN.pos);
                    //length返回輸入向量的長度,離view點越近的點霧效越淡
                    float fogCoord = length(eyePos.xyz);
                    //計算霧濃度
                    //具體可參考:https://blog.csdn.net/zengjunjie59/article/details/112346424
                    UNITY_CALC_FOG_FACTOR_RAW(fogCoord);
                    //限制o.fog值從0-1
                    o.fog = saturate(unityFogFactor);
                #endif

                //MVP轉換
                o.pos = UnityObjectToClipPos(IN.pos);
                return o;
            }

            sampler2D _MainTex;
            fixed4 _Color;

            fixed4 frag(v2f IN) : SV_Target
            {
                fixed4 col;

                //采樣Lightmap
                fixed4 tex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv0.xy);
                //DecodeLightmap解碼光照貼圖 
                half4 bakedColor = half4(DecodeLightmap(tex), 1.0);

                //將烘焙結果和_Color混合
                col = bakedColor * _Color;

                //采樣主紋理
                tex = tex2D(_MainTex, IN.uv2.xy);
                //將col和主紋理顏色混合
                col.rgb = tex.rgb * col.rgb;

                //alpha控制為1
                col.a = 1.0f;

                #if USING_FOG
                    //混合霧效
                    col.rgb = lerp(unity_FogColor.rgb, col.rgb, IN.fog);
                #endif

                return col;
            }

            ENDCG
        }

        //VertexLit作為所有需要陰影的shader的FallBack未辆,其實所有的陰影都是走的這個Pass
        // Pass to render object as a shadow caster 傳遞以將對象渲染為陰影投射器
        Pass {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #pragma multi_compile_shadowcaster
            #pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders允許大多數(shù)著色器使用實例化shadow pass
            #include "UnityCG.cginc"

            struct v2f {
                //陰影宏定義窟绷,主要定義了float4 pos:SV_POTISION;
                V2F_SHADOW_CASTER;
                //INSTANCE_ID
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert( appdata_base v )
            {
                v2f o;
                //INSTANCE_ID
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

                //Unity提供的陰影計算方法,搜不到解釋咐柜,只有這篇解釋了一半https://blog.csdn.net/yanyangxu01/article/details/81987064
                //既然大家都不求甚解只管用兼蜈,我也先放一放吧能力還不夠-。-拙友,后面有能力了再開專篇講吧
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }

            float4 frag( v2f i ) : SV_Target
            {
                //同上
                SHADOW_CASTER_FRAGMENT(i)
            }
            ENDCG

        }
    }
}

4.Shader編寫思路为狸,用到的知識點

第一個Pass使用Fixed Shader實現(xiàn)基礎的光照,第二個實現(xiàn)Lightmapped遗契,最后一個實現(xiàn)陰影辐棒,作為絕大部分shader的FallBack終點,其實很多陰影都是用的這邊的pass姊途。知識點不太多涉瘾,主要是陰影部分還沒搞明白,也搜不到太多的資料捷兰,后面再更吧立叛。


Legacy Shaders基本已經(jīng)討論完了,同類型相似的不再贅述贡茅。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秘蛇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子顶考,更是在濱河造成了極大的恐慌赁还,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驹沿,死亡現(xiàn)場離奇詭異艘策,居然都是意外死亡,警方通過查閱死者的電腦和手機渊季,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門朋蔫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人却汉,你說我怎么就攤上這事驯妄。” “怎么了合砂?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵青扔,是天一觀的道長。 經(jīng)常有香客問我,道長微猖,這世上最難降的妖魔是什么谈息? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮励两,結果婚禮上黎茎,老公的妹妹穿的比我還像新娘。我一直安慰自己当悔,他們只是感情好傅瞻,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盲憎,像睡著了一般嗅骄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饼疙,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天溺森,我揣著相機與錄音,去河邊找鬼窑眯。 笑死屏积,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的磅甩。 我是一名探鬼主播炊林,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卷要!你這毒婦竟也來了渣聚?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤僧叉,失蹤者是張志新(化名)和其女友劉穎奕枝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓶堕,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡隘道,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了郎笆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谭梗。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖题画,靈堂內(nèi)的尸體忽然破棺而出默辨,到底是詐尸還是另有隱情德频,我是刑警寧澤苍息,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響竞思,放射性物質(zhì)發(fā)生泄漏表谊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一盖喷、第九天 我趴在偏房一處隱蔽的房頂上張望爆办。 院中可真熱鬧,春花似錦课梳、人聲如沸距辆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跨算。三九已至,卻和暖如春椭懊,著一層夾襖步出監(jiān)牢的瞬間诸蚕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工氧猬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留背犯,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓盅抚,卻偏偏與公主長得像漠魏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泉哈,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容