加減翻譯,給需要的人快速瀏覽用,某些專有名詞我就保留原文好讓大夥辨識~~
原文:Shaders: ShaderLab & Fixed Function shaders
這個教學將要教你如何製作你自己的shader並讓你的遊戲看起來更棒!
Unity備有一個稱作"ShaderLab“關於shader和material的語言。他很類似CgFX和D3D Efect(.FX)語言,他使用來告訴Material如何呈現。
shader裡記載的properties也會顯示在Unity’s Material的Inspector。針對不同的硬體效能,眾多的shader會根據繪圖硬體描述的render state去修正pipeline設定或是vertex/fragment的使用。Vertex/fragment都是使用高階的Cg/HLSL程式語言。
在這篇教學裡,我們會描述如何撰寫shader去使用 fixed function和 programmable piepline。我們假設讀者對OpenGL或Direct3D的render state, fixed function & programmable pipeline有基礎的認識以及一些Cg, HLSL或OpenGL的知識。在NVIDIA和AMD的開發者網站可以找到一些shader教學和文件。
Getting started
首先創建一個新shader,可選擇"Assets->Create->Shader"或"複製一個現有的shader"。在Project view裡點擊剛才創見出來的shader檔進行編輯。
Shader "Tutorial/Basic" { Properties { _Color ("Main Color", Color) = (1,0.5,0.5,1) } SubShader { Pass { Material { Diffuse [_Color] } Lighting On } } }
這個簡單的shader展示一個最基本的shader。它定義了一個顏色屬性"Main Color"並將之設定為類玫瑰色(r=100% g=50% b=50% a=100%)。然後會調用一個"Pass",在那個Pass裡設定diffuse material為_Color並開啟pre-vertex lighting。
測試一下這個shader。創建一個新的material,從下拉式選單裡選擇這個shader(Tutorial->Basic),然後將這個material丟到某個物件上。調整Material Inspector裡的顏色並觀察變化。接著來弄個更複雜的吧!
Basic Vertex Lighting
如果你是用現成的且頗複雜的shader,那可能會比較難以閱讀理解。接著我們會來分析Unity內建的"VertexLit"shader。這個shader使用fixed function去做基本的pre-lighting。
Shader "VertexLit" { Properties { _Color ("Main Color", Color) = (1,1,1,0.5) _SpecColor ("Spec Color", Color) = (1,1,1,1) _Emission ("Emmisive Color", Color) = (0,0,0,0) _Shininess ("Shininess", Range (0.01, 1)) = 0.7 _MainTex ("Base (RGB)", 2D) = "white" { } } SubShader { Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeparateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant } } } }
所有的shader都是從關鍵字"Shader"並且後面帶著一個這個shader名稱的字串的地方開始。這個名稱是會出現在Inspector裡的。這shader的所有的程式碼都應該放在大括弧({})裡面。(稱之為一個block)。
這名稱應該是簡短易懂的。它並不會/不需要去符合".shader"的檔案名稱。
要讓shader放在子選單內的話,使用斜線(slashes)。e.g. “MyShaders/Test"會在"MyShaders"的子選單裡顯示為"Test"(MyShaders->Test)。
Properties
在shader一開始的部分你可以定應一些porperties讓美術(unity使用者)在Material Inspector裡面編輯。以"VertexLit"範例的properites會看起來像是這樣:
在Properties區塊裡的properties會個別列出。每個property都會使用內置名稱(Color, MainTex)。緊接著的刮弧內是該property在Inspector裡的名稱以及類型。再來就是該值的預設值:
可使用的type列在 Properties Reference 裡。預設值會根據type而設定。以顏色來說,它的預設值應該會是Vector4。
現在我們有定義好的properties,也準備好開始撰寫shader的主體了!
The Shader Body
在我們開始之前,先來定義幾個基本的structure。
不同的繪圖硬體都有不同的效能。例如,某些繪圖卡支援fragment grograms而其他繪圖卡無法;某些可以一次丟4個texture給pass,但某些只能2個甚至1個。為了讓你的使用者可以在任何硬體上執行,一個shader應該包含多個"SubShaders“。當Unity繪製shader時,它會依序走訪每個subshader,並且執行第一個可執行的。
Shader "Structure Example" { Properties { /* ...shader properties... } SubShader { // ...subshader that uses vertex/fragment programs... } SubShader { // ...subshader that uses four textures per pass... } SubShader { // ...subshader that uses two textures per pass... } SubShader { // ...subshader that might look ugly but runs on anything 🙂 } }
這套系統可以讓Unity支援現有的所有硬體,並保有最大限度的質量。但是會變成一個冗長的shader就是…
在subshader裡的任何render state設定都會和所有的pass共享;但是會有各自的rendering pass。完整的可使用指令可在SubShader Reference裡找到。
Passes
每個subshader都是pass的一個集合。對於每個pass來說,幾何物件是要被繪製的,所以在pass內至少要有一個subpass。我們的VertexLit"shaer只有一個subshader:
// ...snip... Pass { Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeparateSpecular On SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant } } // ...snip...
任何一個在pass中的指令都會設定graphics硬體用特定的方式繪製幾何體。
在前面的範例裡,我們將Material的區塊綁上我們property的設定值給fixed function lighting material 的設定。指令"Lightint On"會開啟標準的vertex lighting。"SeparateSpecular On"會去啟用specular highlight 的 separate color。
上述的所有指令都可以很直接的對應到OpenGl/Direct3D硬體模組(hardware model)。參考OpenGL red book可以得到更多相關的資訊。
接下來的指令"SetTexture"非常重要。這些指令定義我們要如何去使用如何混合這個texture,組合以及應用他們在我們的rendering。SetTexture指令根據我們給予texture的名稱使用(這裡是"_MainTex"),在後面的中括弧內的內容是定義該texture要如何去apply。括弧內的設定是會apply在要繪製在screen上的每個pixel。
在這個block內我們設定了一個常數color值,也就是Material的Color"_Color"。我們會在下面用到。
下個指令我們指定如何使用color值去混合texture。使用"Combine"指令去定義texture如何和其他texture或color混合。通會像是這樣:
Combine ColorPart, AlphaPart
這裡的"ColorPart"和"AlphaPart"定義混合時的color(RGB)和alpha(A)。如果省略"AlphaPart",就會直接使用和"ColorPart"。
在"VertexLit"範例中:
Combine texture * primary DOUBLE, texture * constant
這裡的"texture"是來自目前使用中的texture的color(這裡是"_MainTex")。它會乘上"primary"的vertex color。Primary color是只vertex lighting color,是在處理Material時被計算的。最後,這個結果會在乘上2來增加亮度(DOUBLE)。這個alpha值(在逗號之後的部分)是把"texture"乘上"constant"值(在前面設定的"constantColor")。另一個常用到的組合模式叫做"previous"(沒有在這個shader使用到)。這是代表任何一個先前使用"SetTexture"後的結果值,可以用再組合其他多個texuture和/或color。
Summary
在"VertexLit"shader設定了標準的vertex lighting和設定texture組合器讓光照強度變為2倍。
我們可以放入更多pass到shader中,他們會依序繪製。就目前來說是非必要的,因為我們已經達到期望的效果。我們只需要一個SubShader(像是我們做的),並沒有用到更進階的東西,這個特別的shader可以在任何Unity支援的顯卡上執行。
這個"VertexLit"shader是我們所能想到的最為基本的。我們沒有使用任何硬體設定的操作,也沒用到任何ShaderLab和Cg提供的更特殊更酷炫指令。
在下一個章節,我們將會解說如何使用Cg撰寫自訂vertex & fragment programs。
——
如果有何錯誤或用詞詭異的話,請留言給我修改~3Q!!