天天看點

Unity Shader 二 發光Shader

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

          不多說了,先上圖:

Unity Shader 二 發光Shader

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

Unity 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,哈哈哈哈哈哈



繼續閱讀