1. 程式人生 > >Unity Shaders and Effects Cookbook (1-1) 基本的表面著色器 (Surface Shader)

Unity Shaders and Effects Cookbook (1-1) 基本的表面著色器 (Surface Shader)

1、建立基本的表面著色器

在Assets 中建立資料夾 ,命名為 Materials 。 在 Materials 裡面 Create 一個 Shader 。再建立一個 Material 。都命名為 BasicDiffuse 。

開啟BasicDiffuse.shader 。裡面預設已經添加了 基本的漫反射著色器 程式碼,這個Shader 接受一個 紋理資訊 。

把自動建立的 Shader 改名,如下:

Shader "CookBookShaders/BasicDiffuse" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		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;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

選擇上面建立的 Material ( BasicDiffuse.mat ) , 在 Inspector 中,點選下拉框,選擇上面建立的 Shader ( CookBookShaders/BasicDiffuse ) ,這樣就將著色器 賦給了 材質

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

然後建立一個 Cube ,把 BasisDiffuse.mat 拖到 Cube 上。


這樣就完成了 著色器開發環境 的設定。

對於表面著色器來說,很多元素都在後臺完成了,Unity採用 CG 作為著色語言,CG讓程式碼編寫更加高效。

表面著色器語言大多 基於 元件

 的方式 寫入著色器。

Unity內建了大量的 CG 功能,在 Editor/Data/CGIncludes 這個目錄中可以看到幾個 CG 檔案。

我們剛才建立的 基本的表面著色器 ,用到了 其中的 UnityCG.cginc 、Lighting.cginc、UnityShaderVariables.cginc 這三個CG檔案。

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

2、為表面著色器 新增屬性

著色器的屬性,是讓我們可以在編輯器或者在程式碼中去調整著色器的值。

2.1 、Properties 區域 著色器中的屬性

在 Shader 中的 Properties ,對應著 同名的變數,這就類似於 Properties 中的是 變數的 名字字串。Unity 通過讀取 Properties 中的屬性 來建立對應的編輯器控制元件,顯示在 Inspector 視窗上,讓我們很方便的去編輯這個屬性的值。

Properties 中屬性的格式如下:

_EmissiveColor : 變數名

"Emissive Color" : 編輯器中 Inspector面板上顯示的名稱

Color : 變數型別

(1,1,1,1) :預設值


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

我們來新增一個著色器屬性

修改預設的 Shader程式碼,刪除預設的 _MainTex 屬性

修改 Properties 塊如下:

	Properties {
		_EmissiveColor("Emissive Color",Color) = (1,1,1,1) //設定預設值
	}

返回 Unity 檢視,現在能在編輯器中看到 Emissive Color 這個設定

再新增一個 Range 屬性

Properties {
		_EmissiveColor("Emissive Color",Color) = (1,1,1,1) //設定預設值
		_EmissivePowValue("EmissivePow Value",Range(0,10)) = 1
	}

Range 是一個範圍,在編輯器中是一個滑動條


好,已經添加了屬性,下面來使用這兩個屬性。

2.2 、在著色器中使用屬性

首先刪除原來的程式碼 ,這句程式碼中聲明瞭一個變數 _MainTex  ,對應我們之前刪除的 _MainTex 屬性。我們刪掉它  新增我們自己的變數

sampler2D _MainTex;

然後下面的 surf 函式中用到 _MainTex 的程式碼也刪除

half4 c = tex2D (_MainTex, IN.uv_MainTex);

對應上面新增的兩個屬性,新增我們的同名變數。
float4 _EmissiveColor
float _EmissivePowValue


然後在 surf 函式中使用這兩個新增的變數

		void surf (Input IN, inout SurfaceOutput o) {
			float4 c;
			c=pow(_EmissiveColor,_EmissivePowValue);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}


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

完整的 BasicDiffuse.shader

Shader "CookBookShaders/BasicDiffuse" {
	Properties {
		_EmissiveColor("Emissive Color",Color) = (1,1,1,1) //設定預設值
		_EmissivePowValue("EmissivePow Value",Range(0,10)) = 1
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		float4 _EmissiveColor;
		float _EmissivePowValue;

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			float4 c;
			c=pow(_EmissiveColor,_EmissivePowValue);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

Pow :求冪函式,例如 Pow(2,3) = 8

修改完程式碼之後,再到 Unity中檢視。調解 滑動條,就能看到不同的效果。

在 Shader 中,對指定的 _EmissiveColor 進行了 以 _EmissivePowValue 為指數的求冪。

在編輯器中對 EmissiveColor   指定的值是 0-255 範圍的,這個值在 Shader 中被 規格化為 0-1 。

所以隨著 EmissivePowValue 的值越來越大,c=pow(_EmissiveColor,_EmissivePowValue); 這個求的值裡面的 RGBA 是越來越小,逼近 0 ,所以慢慢得,方塊就變成了黑色。

示例工程下載:

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