本節書摘來自華章計算機《unity着色器和螢幕特效開發秘笈(原書第2版)》一書中的第1章,第1.4節,作者 [英]艾倫朱科尼(alan zucconi)[美]肯尼斯拉默斯(kenneth lammers),譯 占紅來,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
着色器的屬性非常重要,可以通過着色器的屬性來讓美工或者使用者給着色器指定紋理或者對着色器進行微調。通過屬性你可以在材質inspector标簽頁中展示一些gui元素,而不用另外再開一個編輯器,是一種可視化的調試方法。
在monodevelop中打開之前的着色器代碼,看看第2行到第7行。這部分被稱為properties(屬性)代碼塊。目前着色器中隻有一個屬性,名為_maintex。如果檢視之前應用了該着色器的材質,你會發現inspector标簽頁中有一個texture(紋理)gui元素。這一段屬性代碼塊為我們建立了這個gui元素。
再重申一次,unity可以讓編碼和屬性生效的過程非常高效。
下面我們将試着建立一些自己的屬性,同時學習一些着色器的文法來幫助我們了解standarddiffuse着色器是如何工作的。在下面這個例子中,我們會對之前的着色器進行一些修改。我們不再使用紋理,而是使用一些顔色和其他一些可以在inspector标簽頁中直接修改的屬性。我們首先拷貝一份standarddiffuse着色器,步驟是在inspector标簽頁中選中,然後按ctrl + d,這樣會自動拷貝一份,并且命名為standarddiffuse2。
可以通過修改着色器中的第一行代碼來給着色器重新起個名字,例如“cookbookshaders/standarddiffuse”,unity會知道需要将這個名為standarddiffuse的着色器放到cookbookshaders組下。如果是用ctrl + d來拷貝的,新的檔案會共用被拷貝檔案的名字。為了避免混淆,可以通過修改第一行代碼來給每一個着色器指定一個唯一的名字。
一旦standarddiffuse2準備好了,可以按照如下步驟來修改其屬性:
在着色器的properties代碼塊中,通過删除下面代碼來移除目前屬性:

現在因為已經把最基本的屬性給移除了,在删除_maintex的引用之前,着色器代碼不會被編譯。再删除下面這一行:
原來的着色器使用了_maintex來給模型上色,可以通過修改surf()函數的第一行代碼來進行替換:
儲存檔案并回到unity中,着色器代碼會被編譯,然後就可以看到材質的inspector标簽頁現在沒有紋理樣本了。要完成這個着色器的替代,可以再多添加一點屬性看看會怎麼樣,接着上面輸入下述代碼:
我們已經給inspector标簽頁添加了另外一個顔色樣本,現在再試試添加另一種屬性,将下述代碼添加到properties代碼塊中:
現在已經建立了另外一個可視化的gui元素,通過這個gui元素我們可以與着色器進行一些視覺互動。這次我們建立了一個名為this is a slider的滑塊,如下圖所示:
通過屬性,可以可視化地對着色器進行微調,而不用深入修改着色器的代碼。下一節會講解如何将這些屬性真正地用起來。
屬性屬于着色器所有,但是屬性的值确實存儲在材質中。同樣一個着色器可以用在不同的材質上。另一方面,修改材質的屬性會影響到所有應用了這種材質的物體的外觀。
每個unity着色器都會有一種查詢自身代碼的内建結構。properties代碼塊就屬于這種unity會查找的函數。這背後的原因是給着色器程式員提供一種快速建立與着色器代碼進行綁定的gui元素的方法。在properties代碼塊中聲明的屬性可以用在着色器代碼中來修改着色器的值、顔色和紋理。定義屬性的文法如下所示:
我們一起看一下這個文法。在你開始寫一個新的屬性的時候,需要賦給屬性一個變量名(variable name),着色器代碼可以通過這個變量名來擷取gui元素的值。這一設定為我們節省了很多時間,因為這樣一來我們不用自己準備系統。
屬性的下一個元素是審查器gui名(inspector gui name)和屬性的類型(type),也就是括号中的兩個。審查器gui名是調試的時候出現在材質的inspector标簽頁中的名字。類型是該屬性将會控制的資料類型。在unity着色器中可用的類型有很多,下表列出了所有我們在着色器中應用的類型:
最後是預設值(default value),顧名思義就是預設情況下該屬性在代碼中的值。是以在前面的示例圖檔中,名為_ambientcolor的屬性的預設值是(1,1,1,1)。這是一個color類型的值,表示的是一種4位浮點的rgba顔色(r, g, b, a = x, y, z, w)。這個顔色屬性首次建立的時候是白色的。