Unity Shader 二 發光Shader

          哈哈,我又回來了,自從上篇的特效Shader之後,這是這個系列的第二彈。老實說這次想寫的內容,我也考慮了很久,最終還是將內容暫定爲使用的頻率較多的外發光。其實外發光可以說是一個爛大街的Shader了,網上也有很多的例子。但是例子多不就從側面說明了,這種類別的Shader的重要性嗎?作爲一個學習爲主,內容爲主的系列Shader,那麼這次的主題就定爲它了。。。。。。哈哈哈哈哈哈哈哈哈哈哈

          不多說了,先上圖:


          從這個圖片上面,大家也可以看出來,這個其實不是單純的外發光效果,而是既有內發光也有外發光的效果。根據我的設定調整,這個shader的內發光是黃色的,外發光是白色的。調整係數如下所示:

        

         接下來就到上代碼的階段,這纔是最重要的,不過博主還想在這裏差個題外話(哈哈,就是這麼的囉嗦,來打我啊)。斷斷續續學習Shader也快有半年,老實說這半年裏面在學習的道路上面一直有迷茫,有困惑。最近遇到的一個問題是程序員爲什麼要學習Shader ? 老實說一直到現在,我還是有些疑惑。但是,我覺得這並不應該成爲妨礙我們廣大猿猴類學習新技術的理由。(哈哈哈哈哈哈哈哈哈) 我個人的想法是學習Shader可以讓我們更好地理解計算機圖形學和渲染管線,學習Shader可以讓我們更加深層次的理解Unity底層那些我們看不到的東西。比較渲染是每個大型引擎的重中之中,我們不應該只知其然而不知所以然。

         而且從現實的層面上來說,目前流行的手機端,暫時限制於性能,一些特別的效果如果能夠良好的使用shader來實現會節約很多的效率。

        

Shader "Custom/LightShader" 
{
	Properties {
		_RimColor ("Rim Color", Color) = (1,1,1,0.5)
		_InnerColor ("Inner Color", Color) = (1,1,1,0.5)
		_InnerColorPower ("Inner Color Power", Range(0.0,1.0)) = 0.5
		_RimPower ("Rim Power", Range(0.0,5.0)) = 2.5
		_AlphaPower ("Alpha Rim Power", Range(0.0,8.0)) = 4.0
		_AllPower ("All Power", Range(0.0, 10.0)) = 1.0
	}
	SubShader {
		Tags { "Queue" = "Transparent" }

		CGPROGRAM
		#pragma surface surf Lambert alpha
		struct Input {
		float3 viewDir;
		INTERNAL_DATA
		};
		float4 _RimColor;
		float _RimPower;
		float _AlphaPower;
		//float _AlphaMin;
		float _InnerColorPower;
		float _AllPower;
		float4 _InnerColor;
		void surf (Input IN, inout SurfaceOutput o) {
		half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
		o.Emission = _RimColor.rgb * pow (rim, _RimPower)*_AllPower+(_InnerColor.rgb*2*_InnerColorPower);
		o.Alpha = (pow (rim, _AlphaPower))*_AllPower;
		}
		ENDCG
	}
	Fallback "VertexLit"
} 

          這個發光Shader是使用的Unity的surface shader編寫的其實老實說看起來並不是很直觀,因爲裏面的很多代碼都是經過封裝的。所以,代碼封裝是把雙刃劍啊。那麼還是老規矩,代碼解析開始。

          Properties {
             _RimColor ("Rim Color", Color) = (1,1,1,0.5)              //這個屬性的意思是外發光的顏色
             _InnerColor ("Inner Color", Color) = (1,1,1,0.5)                     //這個屬性的意思是內發光的顏色
             _InnerColorPower ("Inner Color Power", Range(0.0,1.0)) = 0.5             //這個值表示的意思是內發光的強度
             _RimPower ("Rim Power", Range(0.0,5.0)) = 2.5                                  //這個值表示的意思是外發光的強度
             _AlphaPower ("Alpha Rim Power", Range(0.0,8.0)) = 4.0                    //這個值的意思是外發光的透明度的值
             _AllPower ("All Power", Range(0.0, 10.0)) = 1.0                               //這個值的意思是控制所有的發光效果的強度
 }

          Tags { "Queue" = "Transparent" }

           因爲要使用透明通道,所以這裏要聲明使用透明隊列。

 

           #pragma surface surf Lambert alpha   

           這句話的意思是使用surface裏面封裝好的Lambert alpha光照模型,老實說要把Lambert光照模型拆開將的話需要花費很長的時間,這裏麪包含了很多的內容,如果想要詳細瞭解的話可以看我們的樂樂大神的講解http://blog.csdn.net/candycat1992/article/details/39994049  (再次無情甩鍋,哈哈哈哈哈哈哈哈哈)

           float3 viewDir;    

           INTERNAL_DATA

           通過聲明INTERNAL_DATA,unity會幫你拿到的視向量,詳細的可以再次看我們的樂樂大神的博客http://blog.csdn.net/candycat1992/article/details/24541623 (不要拿西瓜皮丟我,哈哈哈哈哈哈)

  float4 _RimColor;
  float _RimPower;
  float _AlphaPower;
  //float _AlphaMin;
  float _InnerColorPower;
  float _AllPower;
  float4 _InnerColor;

           這些屬性值,都是用來獲得我們上面定義的那些在shader面板裏面的值。

           half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));

           這是通過拿該點標準化過的視向量和法向量做點擊,由此來算出該點的相應的光照值。

           o.Emission = _RimColor.rgb * pow (rim, _RimPower)*_AllPower+(_InnerColor.rgb*2*_InnerColorPower);

           o.Emission的代表的含義是該點的自發光強度,這個值是unity封裝好的,詳細可以看Unity官方API。這裏是拿我們上面定義的外發光的rgb顏色值和rim的_RimPower次方和AllPower相乘,另外再加上InnerColor.rgb乘2再乘_InnerColorPower。

           o.Alpha = (pow (rim, _AlphaPower))*_AllPower;

           o.Alpha代表的含義是該點的透明度的值,通過rim的_AlphaPower次方的值再乘以_AllPower得到結果。

           Fallback "VertexLit"

           這個話的意思類似於備胎,就是在當前着色器不能用的時候,就使用這個(有點慘啊。。。。。)

           其實可能大家覺得上面的運算看起來不直觀,不明白是什麼意思,在這裏我想說一句名言:計算機圖形學其實在某種程度上是用來欺騙眼睛的一門學科,這裏很多的公式運算很多可能過多的是出於經驗而不是純科學理論。(纔不是博主不知道而亂講呢,嘻嘻嘻嘻嘻嘻嘻嘻嘻)

           這次的Shader講解就先到這裏了,因爲一些資料沒有帶回來,所以這次講解的有點少,下次補上。

           歡迎大家來和我交流,我的郵箱是[email protected] , 大家也可以來羣裏面找我344682050,哈哈哈哈哈哈


          

        


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章