1. 程式人生 > >Unity Shaders and Effects Cookbook (3-3) 建立 BlinnPhong 光照模型

Unity Shaders and Effects Cookbook (3-3) 建立 BlinnPhong 光照模型

BlinnPhong 是另一種估算鏡面高光的方式,相比於 上一次學習的 Phong 光照模型,更簡單 高效。

BlinnPhong 是通過視線方向 和 光線方向 所形成的半形向量 來完成的。

Phong 和 BlinnPhong 演算法圖 對比如下:

  

可以看出 BlinnPhong 計算過程 比 Phong 簡單了很多。

而且通過實驗結果來說,兩種演算法得到的效果是差不多的。

簡單描述下過程:

1、首先 燈光方向向量 和 視角方向向量 相加,得到 半形向量。

2、對 半形向量 和 法線向量 求 Cos 值,得到高光強度。

轉自http://blog.csdn.net/huutu  http://www.thisisgame.com.cn


依據上面的 BlinnPhong 公式來碼程式碼:

CustomBlinnPhong.shader

Shader "CookBookShaders/CustomBlinnPhong" 
{
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_MainTint("Main Tint",Color)=(1,1,1,1)
		_SpecularColor("Specular Color",Color)=(1,1,1,1)
		_SpecularPower("Specular Power",Range(0.1,120))=1
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf CustomBlinnPhong

		sampler2D _MainTex;
		float4 	  _MainTint;
		float4    _SpecularColor;
		float     _SpecularPower;

		struct Input 
		{
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) 
		{
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}


		fixed4 LightingCustomBlinnPhong(SurfaceOutput s,fixed3 lightDir,fixed3 viewDir,fixed atten)
		{
			float3 diffuse = max(0,dot(s.Normal , lightDir));

			float3 halfVector=normalize(lightDir + viewDir);
			float specular=max(0, dot( s.Normal , halfVector ));
			float finalSpecular=pow(specular,_SpecularPower);

			float4 c;
			c.rgb = (s.Albedo * _LightColor0.rgb * diffuse) +( _LightColor0.rgb * _SpecularColor.rgb * finalSpecular)*(atten*2);
			c.a=s.Alpha;
			return c;
		}

		ENDCG
	} 
	FallBack "Diffuse"
}

效果圖

和 Phong 的效果並沒有什麼差異。

示例工程下載:

http://pan.baidu.com/s/1dEMU5OX


這一節對應 Unity著色器和螢幕特效開發祕籍的 3.4 節 --- 建立BlinnPhong高光型別 。這一節中書上程式碼出現了錯誤。務必參照隨書程式碼進行修正!