【Unity Shader入門(mén)精要學(xué)習(xí)】復(fù)雜的光照(二)

Unity的光源類(lèi)型

Unity一共支持4種光源類(lèi)型:平行光(directional light)貌虾、點(diǎn)光源(point light)限煞、聚光燈(spot light)撮抓、面光源(area light)棋电。而面光源僅在烘焙時(shí)才可以發(fā)揮作用

1、光源類(lèi)型有什么影響

一般經(jīng)常使用的光源屬性有:位置椎组、方向油狂、顏色、強(qiáng)度寸癌,衰減
(1)平行光专筷,只有方向,顏色灵份,強(qiáng)度仁堪,沒(méi)有衰減
(2)點(diǎn)光源,位置、方向带欢、顏色黄娘、強(qiáng)度,衰減全有
(3)聚光燈朴上,位置、方向、顏色枪眉、強(qiáng)度,衰減全有

2再层、在Unity中使用前向渲染處理多光源

image.png
Shader "Unlit/ForwardRenderingMat"
{
    Properties
    {
        _Diffuse("Diffuse",Color)=(1,1,1,1)
        _Specular("Specular",Color)=(1,1,1,1)
        _Gloss("Gloss",Range(8.0,256))=20
    }

    SubShader
    {
        Pass //第一個(gè)Pass使用Base用來(lái)逐像素平行光光照
        {
            Tags{"LightModel"="ForwardBase"}
            CGPROGRAM
            #include "Lighting.cginc"
            #pragma vertex vert
            #pragma fragment frag

            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct a2v
            {
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float3 worldPos:TEXCOORD0;
                float3 worldNormal:TEXCOORD1;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);

                return o;
            }

            fixed4 frag(v2f i):SV_TARGET
            {
                float3 worldPos = i.worldPos;
                float3 worldNormal = normalize(i.worldNormal);
                float3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
                float3 halfNormal = normalize(worldLightDir+worldViewDir);

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;  
                //_LightColor0已經(jīng)是顏色和強(qiáng)度相乘之后的結(jié)果了
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,halfNormal)),_Gloss);

                fixed atten = 1.0; //光的衰減贸铜,平行光是沒(méi)有衰減的
                
                return fixed4(ambient+(diffuse+specular)*atten,1.0);
            }

            ENDCG
        }
        
        Pass  //第二個(gè)Pass用來(lái)計(jì)算其他光源的逐像素光照,可能是平行光聂受,也可能是點(diǎn)光源蒿秦,聚光燈
        {
            Tags{"LightModel"="ForwardAdd"}
            Blend One One

            CGPROGRAM
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            //為了得到正確的衰減因子
          //  #pragma multi_compile_fwadd  
            #pragma multi_compile_fwadd_fullshadows
            #pragma vertex vert
            #pragma fragment frag
            
            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct a2v
            {
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float3 worldPos:TEXCOORD0;
                float3 worldNormal:TEXCOORD1;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                o.worldNormal = UnityObjectToWorldNormal(v.normal);

                return o;
            }

            fixed4 frag(v2f i):SV_TARGET
            {
                fixed3 worldPos = i.worldPos;
                fixed3 worldNormal = normalize(i.worldNormal);

                #ifdef USING_DIRECTIONAL_LIGHT
                    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                #else
                    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz-i.worldPos);
                #endif
                fixed3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos);
                fixed3 halfNormal = normalize(worldViewDir+worldLightDir);

                //因?yàn)橐呀?jīng)在第一個(gè)Pass中計(jì)算了環(huán)境光,所以這里就不需要再次計(jì)算了
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,halfNormal)),_Gloss);
                
                #ifdef USING_DIRECTIONAL_LIGHT
                    fixed atten = 1.0;
                #else
                    //Unity提供了衰減因子的查找表蛋济,并存在了一個(gè)圖片中棍鳖,我們只要采樣就可以
                    //但這樣也會(huì)有精度的問(wèn)題
                    #if defined(POINT)
                        float3 lightCoord = mul(unity_WorldToLight,float4(i.worldPos,1)).xyz;
                        //A.rr操作相當(dāng)于是取了兩個(gè)一樣的值(A,A)
                        fixed atten = tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;
                    #elif defined(SPOT)
                        float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));
                        fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL; 
                    #else
                        fixed atten = 1.0;
                    #endif
                #endif

                return fixed4((diffuse+specular)*atten,1.0);
            }

            ENDCG
        }
    }
    
}

image.png

image.png

從Frame Debug中可以看出第一個(gè)Pass使用了BasePass并執(zhí)行了一次,而第二個(gè)Pass使用了Addtional Pass執(zhí)行了4次碗旅,因?yàn)閳?chǎng)景中除了一個(gè)平行光之外還有一個(gè)4個(gè)其他可以逐像素的光源渡处。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末镜悉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子医瘫,更是在濱河造成了極大的恐慌侣肄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醇份,死亡現(xiàn)場(chǎng)離奇詭異稼锅,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)被芳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)缰贝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人畔濒,你說(shuō)我怎么就攤上這事剩晴。” “怎么了侵状?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵赞弥,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我趣兄,道長(zhǎng)绽左,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任艇潭,我火速辦了婚禮拼窥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蹋凝。我一直安慰自己鲁纠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布鳍寂。 她就那樣靜靜地躺著改含,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迄汛。 梳的紋絲不亂的頭發(fā)上捍壤,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音鞍爱,去河邊找鬼鹃觉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛硬霍,可吹牛的內(nèi)容都是我干的帜慢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼粱玲!你這毒婦竟也來(lái)了躬柬?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抽减,失蹤者是張志新(化名)和其女友劉穎允青,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卵沉,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颠锉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了史汗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琼掠。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖停撞,靈堂內(nèi)的尸體忽然破棺而出瓷蛙,到底是詐尸還是另有隱情,我是刑警寧澤戈毒,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布艰猬,位于F島的核電站,受9級(jí)特大地震影響埋市,放射性物質(zhì)發(fā)生泄漏冠桃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一道宅、第九天 我趴在偏房一處隱蔽的房頂上張望食听。 院中可真熱鬧,春花似錦污茵、人聲如沸碳蛋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至玷室,卻和暖如春零蓉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背穷缤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工敌蜂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人津肛。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓章喉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秸脱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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