案例-通過積雪效果更深入的了解shader

之前的預(yù)備知識能讓我們掌握shader的基本用法搏明,并且寫出一些簡單的shader鼠锈。這次我們通過積雪效果來更進(jìn)一步的了解shader是如何結(jié)合數(shù)學(xué)闪檬,實(shí)現(xiàn)效果星著。
另外注意,關(guān)注有強(qiáng)烈光照需求的shader才使用surface shader粗悯,否則使用VF shader就可虚循。

Shader "Custom/SnowEffect" {   //定義shader的路徑
    Properties{
    
       _MainTex("Albedo (RGB)", 2D) = "white" {}       //要使用的紋理

    //定義了默認(rèn)值為“bump”的2D類型的紋理_Bump,初始值為空样傍。
      _Bump("Bump",2D) = "bump"{}

      _Snow("Snow Level",Range(0,1)) = 0            
      _SnowColor("Snow Color",Color) = (1,1,1,1)
      _SnowDirection("Snow Direction",Vector) = (0,1,0)  //默認(rèn)水平方向横缔,值為1,而不是-1
      _SnowDepth("Snow Depth",Range(0,0.3)) = 0.1        //積雪厚度
    }
        SubShader{
            //在腳本中可以通過判斷rendertype來做一些處理衫哥,比如shader替換茎刚、shader關(guān)閉
            //參考:  https://blog.csdn.net/nnsword/article/details/17840439   類型
            //        https://blog.csdn.net/zmafly/article/details/51141011    作用
            //       http://lib.csdn.net/article/unity3d/44793                解析
            Tags { "RenderType" = "Opaque" }

            CGPROGRAM        //shader的正文

            //聲明surface shader 函數(shù)名,光照類型撤逢,使用的頂點(diǎn)函數(shù)(自定頂點(diǎn)函數(shù)名為vert)
            #pragma surface surf Lambert vertex:vert  

          //添加對PROPERTIES的引用
          sampler2D _MainTex;
          sampler2D _Bump;
          float _Snow;
          float4 _SnowColor;
          float4 _SnowDirection;
          float _SnowDepth;

          struct Input {
              float2 uv_MainTex;

              //添加一個(gè)變量float2 uv_Bump來獲得_Bump紋理的uv坐標(biāo)膛锭。
              float2 uv_Bump;
              //獲取世界坐標(biāo)下的法向值
              float3 worldNormal;
              INTERNAL_DATA
          };

          void surf(Input IN, inout SurfaceOutput o) {
              //tex2D對紋理進(jìn)行采樣
              half4 c = tex2D(_MainTex, IN.uv_MainTex);
              o.Albedo = c.rgb;
              o.Alpha = c.a;

              //tex2D根據(jù)輸入?yún)?shù)的類型,獲取對應(yīng)含義的值蚊荣,此處從_Bump紋理中提取法向信息
              //UnpackNormal函數(shù)的作用就是將tex2D函數(shù)獲取到的fixed4類型值轉(zhuǎn)換成fixed3類型的值
              o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));

              //得到世界坐標(biāo)系下的真正法向量(而非凹凸貼圖產(chǎn)生的法向量初狰,要做一個(gè)凹凸貼圖法向值到世界坐標(biāo)系法向值的轉(zhuǎn)化)和雪落
              //下相反方向的點(diǎn)乘結(jié)果,即兩者余弦值互例,并和_Snow(積雪程度)比較
              if (dot(WorldNormalVector(IN, o.Normal), _SnowDirection.xyz) > lerp(1, -1, _Snow))
              {
                  /*
                  我們知道奢入,余弦值是-1和1之間的一個(gè)數(shù),越接近于1媳叨,說明該點(diǎn)法向與雪落下相反方向越一致腥光,當(dāng)為-1時(shí),說明兩者方向相反糊秆。
                 此處我們可以看出_Snow參數(shù)只是一個(gè)插值項(xiàng)柴我,當(dāng)上述夾角余弦值大于
                  lerp(1,-1,_Snow)=1-2*_Snow時(shí),即表示此處積雪覆蓋扩然,所以此值越大

                  多講一點(diǎn)艘儒,lerp的第三個(gè)參數(shù)是一個(gè)(0,1)之間的比例因子夫偶,代表所處前兩個(gè)參數(shù)范圍的位置
                  注意為了符合正常的自然現(xiàn)象界睁,我們_Snow一般只取0~0.5,因?yàn)榇笥?.5時(shí)兵拢,插值的結(jié)果將小于0翻斟,會造成雪好像穿過了巖石,落到了巖石的后面说铃。這個(gè)道理和光照的道理一樣访惜,物體背面是見不到陽光的嘹履。
                  */

                  //積雪程度程度越大。此時(shí)給覆蓋積雪的區(qū)域填充雪的顏色
                  o.Albedo = _SnowColor.rgb;
              }

              else      //否則表示未覆蓋
              {
                  o.Albedo = c.rgb;
              }

              o.Alpha = 1;

          }
          //自定義頂點(diǎn)函數(shù)
          /*
             參數(shù)appdata_full v债热,參數(shù)的類型為appdata_full(Unity內(nèi)置類型)砾嫉,該類型包含了紋理坐標(biāo),法向量窒篱,頂點(diǎn)位置焕刮,以及切線信息
          */
          void vert(inout appdata_full v)
          {
              //將_SnowDirection從世界坐標(biāo)系轉(zhuǎn)換到模型的局部坐標(biāo)系下
              /*
                  將_SnowDirection乘以Unity內(nèi)置矩陣 – UNITY_MATRIX_IT_MV
                  (IT表示Inverse Transpose逆轉(zhuǎn)置矩陣,MV表示 ModelView矩陣墙杯,該矩陣表示是ModelView的逆轉(zhuǎn)置矩陣)配并。
                現(xiàn)在我們得到了該頂點(diǎn)的法向量。
                _Snow*2/3高镐,這表示只有那些更接近雪落下方向的區(qū)域才會增加雪的厚度溉旋,更符合自然現(xiàn)象。
                而這些通過測試的區(qū)域嫉髓,沿著(sn.xyz+v.normal)方向進(jìn)行加厚观腊,也就是將其頂點(diǎn)沿此方向伸展一定距離。
                注意到增厚的程度取決于_SnowDepth和_Snow岩喷,而增厚的方向是由物體法向和雪落的方向綜合作用的恕沫,這也符合自然現(xiàn)象。
              */
               float4 sn = mul(UNITY_MATRIX_IT_MV, _SnowDirection);

               if (dot(v.normal, sn.xyz) >= lerp(1, -1, (_Snow * 2) / 3))
                   v.vertex.xyz += (sn.xyz + v.normal) * _SnowDepth * _Snow;
           }
               ENDCG
      }
          FallBack "Diffuse"      //shader失敗時(shí)回滾
}

調(diào)節(jié)箭頭所指落雪方向可以改變落雪效果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纱意,一起剝皮案震驚了整個(gè)濱河市婶溯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偷霉,老刑警劉巖迄委,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異类少,居然都是意外死亡叙身,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門硫狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來信轿,“玉大人,你說我怎么就攤上這事残吩〔坪觯” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵泣侮,是天一觀的道長即彪。 經(jīng)常有香客問我,道長活尊,這世上最難降的妖魔是什么隶校? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任漏益,我火速辦了婚禮,結(jié)果婚禮上深胳,老公的妹妹穿的比我還像新娘绰疤。我一直安慰自己,他們只是感情好稠屠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布峦睡。 她就那樣靜靜地躺著翎苫,像睡著了一般权埠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上煎谍,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天攘蔽,我揣著相機(jī)與錄音,去河邊找鬼呐粘。 笑死满俗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的作岖。 我是一名探鬼主播唆垃,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痘儡!你這毒婦竟也來了辕万?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沉删,失蹤者是張志新(化名)和其女友劉穎渐尿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矾瑰,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砖茸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了殴穴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凉夯。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖采幌,靈堂內(nèi)的尸體忽然破棺而出劲够,到底是詐尸還是另有隱情,我是刑警寧澤植榕,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布再沧,位于F島的核電站,受9級特大地震影響尊残,放射性物質(zhì)發(fā)生泄漏炒瘸。R本人自食惡果不足惜淤堵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顷扩。 院中可真熱鬧拐邪,春花似錦、人聲如沸隘截。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婶芭。三九已至东臀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犀农,已是汗流浹背惰赋。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呵哨,地道東北人赁濒。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像孟害,于是被迫代替她去往敵國和親拒炎。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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