渲染順序一般是先渲染不透明物體,然後才到透明物體。Depth Test沒有通過的片元,會被捨棄,通過了Depth Test的片元,進行混合計算,且不將深度寫進z-buffer中。假設寫入了z-buffer,那麼在下一次渲染的物體是在該深度後但在不透明物體前時,就會因為深度測試,導致被捨棄。所要z-buffer中保存的只有不透明物體的深度。因為這個原因,也導致渲染順序非常重要。
即使場景中都只有透明物體,渲染順序也非常重要,愈後的物體應被先渲染,不然可能出現物體前後出現反轉的效果。基於這個問題,渲染引擎一般都會先對物體進行排序,再渲染。常用的方法是
第2項在電腦中並不好做,因為有一些交叉的物體,可能有一端是在另一個物體的前面,但在另一端卻在另一個物體的後面。也就是說,兩個物體之間同時存在: 在另一個物體的前與後的狀態下。
像圖中的物體的遠近是不可判斷的。這種問題的解決方法通常也是分割網格。
Unity為了解決渲染順序的問題提供了渲染隊列 (render queue)。可以使用SubShader的Queue標簽來決定歸於哪個渲染隊列。Queue愈小愈早被渲染。
Name | Index | Description |
---|---|---|
Background | 1000 | 會在任何其他隊列之前被渲染,通常使用該隊列淶渲染那些需要繪制在背景上的物體。 |
Geometry | 2000 | 默認的渲染隊列,大多數物體都使用這個隊列。 |
AlphaTest | 2450 | 需要透明度測試的物體使用這個隊列。在Unity 5中它從Geometry隊列中被單獨分出來,這是因為在所有不透明物體渲染之後再渲染它們會更加高效。 |
Transparent | 3000 | 這個隊列中的物體會在所有Geometry和AlphaTest物體渲染後,再按從後往前的順序進行渲染。任何使用了透明度混合(例如關閉深度寫入的Shader)的物體都應該使用該隊列。 |
Overlay | 4000 | 用於實現一些疊加效果。 |
SubShader {
Tags { "Queue" = "AlphaTest" }
Pass {
...
}
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
ZWrite Off
...
}
}