到現在為止,我們見到的着色器都有一個共同點—都用在實心材質上。如果你想提升遊戲視覺效果,某些時候透明材質是個不錯的選擇,比如火焰效果或者窗戶玻璃等。透明材質的制作相對複雜一點。在渲染實心物體之前,unity會按照各個物體距離鏡頭的距離(z排序)對它們進行排列,然後跳過所有沒有朝着鏡頭的三角形(剔除)。而如果是渲染透明幾何體,這兩個步驟可能就會受影響。這一節我們會講解在建立透明的表面着色器時如何解決這些可能出現的問題。這部分内容會在第6章中進一步回顧,因為到時候需要模拟玻璃和水相關的場景。
這一節需要一個新的着色器transparent,還需要一個新的材質來将着色器的效果呈現到物體上。我們需要做一個透明的玻璃窗,最好準備一個四邊形或者一個平面。還需要幾個不透明的物體來測試透明效果。在這個例子中,給玻璃紋理使用一個png圖像,圖像的alpha通道用來決定玻璃的透明度。建立這樣一個圖像需要一些其他的圖像處理軟體。你需要按照下面這些步驟來做:
找到一個你想添加給玻璃窗的圖像。
用圖像編輯軟體如gimp或者photoshop打開該圖像。
在圖像中選擇你想使之半透明的部分。
給圖像添加一層白色遮罩(完全不透明)。
使用之前選擇的内容以及一種比較深的顔色填充遮罩層。
儲存圖像,然後将其導入unity。

前面已經提過,在使用透明着色器時有幾個地方需要注意:
在着色器的subshader{}部分,添加下面的标簽來表示着色器是一個透明着色器:
因為着色器是用二維材質設計的,確定模型背後的幾何體是沒有畫過的,代碼如下:
告訴着色器材質應該是透明的,需要與螢幕上之前畫好的東西混合在一起:
使用表面着色器來計算最終顔色和玻璃的透明度:
這個着色器引入了幾個新概念。首先tags是用來添加物體的渲染資訊的。這裡最有趣的部分是queue。unity預設會根據物體到鏡頭的距離來對物體進行排序,是以距離鏡頭近的物體會渲染在距離鏡頭較遠的物體之上。在大部分情況下這麼做都是沒有問題的,但在某些時候你想要自己來控制這個排序過程以達到某種需要的效果。unity還提供了某些預設渲染序列,序列中的每一個元素包含一個唯一的序列号來告訴unity其出現順序。這個内建的渲染序列稱為背景(background)、幾何結構(geometry)、alpha檢查(alphatest)、透明(transparent)和覆寫(overlay)。這些序列不是随便建立的,設定這些序列是為了讓開發着色器和實時渲染的過程更加簡便。關于不同渲染序列的使用描述,請參照下表:
渲染序列 渲染序列描述 渲染序列值
背景(background) 這個渲染序列會最先渲染,一般用作天空盒或者其他大的環境渲染 1000
幾何結構(geometry) 這是個預設的渲染序列,适用于大部分物體,不透明幾何體都是使用這個序列 2000
alpha檢查(alphatst) alpha檢查幾何結構使用這個序列,與幾何結構序列不同的是,在渲染完所有實體之後,使用該序列在渲染半透明的物體時更加高效 2450
透明(transparent) 這個渲染序列在幾何結構序列和alpha檢查序列之後渲染,任何混色(也就是着色器并不寫入深度緩存)都在這個序列中,例如玻璃和粒子效果 3000
覆寫(overlay) 這個渲染序列用來制作覆寫遮罩效果的,任何最後渲染的東西都應該在這個序列中,比如鏡頭光斑 4000
是以隻要知道了物體應該屬于哪個渲染序列,就可以相應地指定其内建的渲染序列标簽。我們的着色器使用transparent序列,是以代碼是這樣的:tags{"queue"="trasparent"}。
代碼中的ignoreprojector标簽用來確定該物體不受unity的投影影響。最後rendertype扮演了一個着色器置換的角色,關于這部分内容會在第9章中進一步介紹。
最後一個概念是alpha:fade。這部分代碼表示這種材質上的每一個像素需要與螢幕上之前的顔色根據其alpha值進行混色。如果沒有這個指令,像素會按照正常的順序顯示,但是不會有任何透明效果。