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