Unity shader教程-第三課:實踐!同一個shader,多個material。
更多更及時的文章請關於98教育
這節課我們開始利用我們學到的Properties知識來改動程式碼,用一個shader實現如下圖的幾個不同的球體:
步驟:
- 使用MonoDevelop開啟shader檔案
- 保證Properties裡面是如下內容
_EmissiveColor ("Emissive Color", Color) = (1, 1, 1, 1) _AmbientColor ("Ambient Color", Color) = (1, 1, 1, 1) _SomeValue ("Coefficient", Range(0, 10)) = 2.5
- 找到程式碼中的#pragma surface surf Lambert
float4 _EmissiveColor; float4 _AmbientColor; float _SomeValue;
- 清除原來在這個地方的
sampler2D _MainTex;
- 找到方法 void surf(Input IN, inout SurfaceOutput o),把裡面的內容改成
float4 c = pow((_EmissiveColor + _AmbientColor), _SomeValue); o.Albedo = c.rgb; o.Alpha = c.a;
為保證你做成的最後內容跟我的一樣,這裡是最後的shader程式碼
Shader "myDiffuse" { Properties { _EmissiveColor ("Emissive Color", Color) = (1, 1, 1, 1) _AmbientColor ("Ambient Color", Color) = (1, 1, 1, 1) _SomeValue ("Coefficient", Range(0, 10)) = 2.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert float4 _EmissiveColor; float4 _AmbientColor; float _SomeValue; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c = pow((_EmissiveColor + _AmbientColor), _SomeValue); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
到這裡,我們就可以儲存shader。回到Unity中。
回到Unity後,選中名字為myDiffuse的material,然後按下鍵盤上的Ctrl+D,複製出material,把它改名為myDiffuse2。同樣的方式,複製出myDiffuse3, myDiffuse4。這個方式,能讓我們製作出使用同一個shader的不同的四個material出來。
在Scene面板中,如果你沒有加滿4個sphere,可以現在新增。然後分別給這四個球拖入我們的myDiffuse、myDiffuse2、myDiffuse3、myDiffuse4這幾個material。
選中任意一個material,你可以在Inspector上選擇Emissive Color或者Ambient Color,也可以通過拖動滑動條來改動數值,改動的過程中可以看到Scene中的物體會隨你的改動而變化顯示。同時,雖然我們只寫了一個shader用到4個物體上,改動一個物體的material並不會影響到跟它使用不一樣的material的物體。也就是說,我們屬性裡的值,其實是存在於material中。在我們改變相關的值的時候,unity會把值存到material對應的檔案中,並在執行的時候,作為shader需要的引數送到shader中。由此,雖然我們只寫了一個shader,但是因為送入的引數不同,因此物體的表現也就不同(為那些好奇的人,這節課的附錄部分介紹了怎麼開啟material檔案的方式,可以看到儲存的內容)。
對於我們上面改動的程式碼的解釋
當你在Properties塊宣告一個新的屬性值的時候,你也就給shader提供了一種讓使用者通過Inspector面板調整內部值的方式。每個變數都會儲存下最後使用者修正的結果。但是,如果程式碼需要在SubShader{}這個塊中用到這些值,必須在這個塊中同時宣告同樣名字的變數,這個方式把我們在Inspector上的值和最後程式碼的值連結起來,形成一個整體。
一旦你在SubShader{}塊中宣告這些變數後,你就可以在surf()方法中使用到這些變量了。surf()方法中,我們用到的pow()方法是NVidia的cg語言提供的一個方法,unity shader可以用cg中的方法,這個方法跟其他語言中的pow類似,是“返回指定數字的指定次冪”。
附錄:
Unity提供了把一些檔案存成文字型的方式,我們可以利用這個方式來檢視material檔案的內容。
步驟:
- 選單 Edit | Project Settings | Editor,會開啟如下的面板
- 該面板的Asset Serialization中,Mode點開,選擇 Force Text
- 等進度條完成任務
- 硬碟上找到我們的myDiffuse材質(material)檔案(以.mat)結尾,用可以開啟文字檔案的軟體開啟(寫字本、Ultraedit、Notepad++都可以)
- 檢視裡面的內容,我這裡的如下圖
圖中高亮的地方可以看到我們選擇的顏色值。