【Unity Shaders】Transparency —— 使用渲染隊列進行深度排序,unity渲染
本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書作者),同時會加上一點個人理解或拓展。
這裡是本書所有的插圖。這裡是本書所需的代碼和資源(當然你也可以從官網下載)。
========================================== 分割線 ==========================================
寫在前面
為了讓我們真正明白透明度,我們需要瞭解一下深度排序,或者說,對象的繪製順序。Unity允許我們控制一個特定對象繪製到螢幕上的順序,因此我們可以更好地控制哪些對象應該覆蓋在其他對象上。你可以把繪製順序理解成Photoshop中的圖層的概念。在處理透明度或者類似介面對象的元素時,繪製順序尤其重要。
本篇將會講解如何使用Unity內建的標籤(tags)來利用這個分層化的方法去渲染你的對象。這是非常重要的,因為你將會更好地控制你的對象是如何被繪製到遊戲介面的。
準備工作
實現
Shader部分的代碼實際上很簡單;它僅僅需要兩行新代碼就可以了。
最後,完整代碼如下:
Shader "Custom/Depth001" {Properties {_MainTex ("Base (RGB)", 2D) = "white" {}}SubShader {Tags { "Queue"="Geometry-20" }ZWrite OffLOD 200CGPROGRAM#pragma surface surf Lambertsampler2D _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"}
解釋
預設情況下,Unity會基於對象距離攝像機的遠近來排序你的對象。因此,當一個對象離攝像機越近,它就會優先繪製在其他更遠的對象上面。對於大多數情況這是有效併合適的,但是在一些特殊情況下,你可能想要自己控制對象的繪製順序。而使用Tags{}塊我們就可以得到這樣的控制。
Unity提供給我們一些預設的渲染隊列,每一個對應一個唯一的值,來指導Unity繪製對象到螢幕上。這些內建的渲染隊列被稱為
Background, Geometry, AlphaTest, Transparent, Qverlay。這些隊列不是隨便建立的,它們是為了讓我們更容易地編寫Shader並處理即時渲染的。下面的表格描述了這些渲染隊列的用法:
| 渲染隊列 |
渲染隊列描述 |
渲染隊列值 |
| Background |
這個隊列被最先渲染。它被用於skyboxes等。 |
1000 |
| Geometry |
這是預設的渲染隊列。它被用於絕大多數對象。不透明幾何體使用該隊列。 |
2000 |
| AlphaTest |
通道檢查的幾何體使用該隊列。它和Geometry隊列不同,對於在所有立體物體繪製後渲染的通道檢查的對象,它更有效。 |
2450 |
| Transparent |
該渲染隊列在Geometry和AlphaTest隊列後被渲染。任何通道混合的(也就是說,那些不寫入深度緩衝的Shaders)對象使用該隊列,例如玻璃和粒子效果。 |
3000 |
| Overlay |
該渲染隊列是為覆蓋物效果服務的。任何最後被渲染的對象使用該隊列,例如鏡頭光暈。 |
4000 |
因此,一旦你知道你的對象屬於哪一個渲染隊列,你就可以指定它的內建渲染隊欄標籤。我們的Shader使用了Geometry隊列,因此我們這樣寫:Tags { "Queue"="Geometry" }。但是,我們希望告訴我們的對象在我們的Geometry隊列中的所有對象後面、Background隊列對象的前面被繪製,因此我們修改為Tags { "Queue"="Geometry-20" }。這樣就告訴Unity,我們想要把這個對象當成一個立體物體,但是請在所有其他不透明對象後面渲染。
注意:Geometry對應的隊列值是2000,所以"Geometry-20"意味著使用隊列值為1980的隊列,而數值越小意味著越先被渲染,也就會被後面渲染的對象遮擋。
最後,我們還要在SubShader塊中聲明ZWrite標籤。這告訴Unity,我們想要重寫對象的深度排序,並且我們將會為它指定一個新的渲染隊列。因此,我們就簡單的把ZWrite值設為Off。(不設就沒有效果)