本篇unity3d教程我們來看下Unity渲染隊列、ZWrite和ZTest相關介紹,首先我們來了解幾個概念
(1)什么是深度?
深度其實就是該像素點在3d世界中距離攝象機的距離,深度值Zbuffer(Z值)越大,則離攝像機越遠。
(2)什么是深度緩存?
深度緩存中存儲著每個像素點(繪制在屏幕上的)的深度值!如果啟用了深度緩沖區,在繪制每個像素之前,OpenGL會把它的深度值和已經存儲在這個像素的深度值進行比較。新像素深度值<原先像素深度值,則新像素值會取代原先的;反之,新像素值被遮擋,其顏色值和深度將被丟棄,最終屏幕顯示的就是深度緩存中深度對應的像素點的顏色!(深度主要起的是比較的作用)
(3)什么是深度測試?
在深度測試中,默認情況是將要繪制的新像素的z值與深度緩沖區中對應位置的z值進行比較,如果比深度緩存中的值小,那么用新像素的顏色值更新深度緩存中對應像素的顏色值。
(4)為什么需要深度?
在不使用深度測試的時候,如果我們先繪制一個距離較近的物體,再繪制距離較遠的物體,則距離遠的物體因為后繪制,會把距離近的物體覆蓋掉,這樣的效果并不是我們所希望的。而有了深度緩沖以后,繪制物體的順序就不那么重要了,都能按照遠近(Z值)正常顯示,這很關鍵。(越后繪制的東西,距離相機就越近)
那么,在unity中,如果知道了渲染隊列,ZWrite,ZTest,如何確定哪個物體先顯示呢?
首先,unity先將渲染隊列中較前的進行渲染,然后再執行ZWrite,ZTest
ZWrite可以取的值為:On/Off,默認值為On,代表是否要將像素的深度寫入深度緩存中ZTest可以取的值為:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默認值為LEqual,代表如何將像素的顏色寫入深度緩存中,例如當取默認值的情況下,如果將要繪制的新像素的z值小于等于深度緩存中的值,則將用新像素的顏色值更新深度緩存中對應像素的顏色值。需要注意的是,當ZTest取值為Off時,表示的是關閉深度測試,等價于取值為Always,而不是Never!Always指的是直接將當前像素顏色(不是深度)寫進顏色緩沖區中;而Never指的是不要將當前像素顏色寫進顏色緩沖區中,相當于消失。
因為ZWrite默認值為On,ZTest默認值為LEqual,所以這很好地解釋了為什么在unity中,距離相機近的東西會阻擋住距離相機遠的東西。如果我們先繪制一個距離較近的物體,再繪制距離較遠的物體,則距離遠的物體因為后繪制,會把距離近的物體覆蓋掉,這時我們可以通過修改ZWrite和ZTest來改變物體的遮擋關系!
測試的Shader代碼(兩個方塊的shader代碼起始都是一樣的,測試時修改的是測試區里的代碼):
Shader "Custom/ZTest"
{
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags {"RenderType"="Opaque" }
LOD 200
}
/////////////////////////////////////////測試區Tags{ "Queue" = "Geometry"
//ZWrite Off
//ZTest Off
/////////////////////////////////////////測試區
CGPROGRAM
#pragma surface surf Lambert
sampler2D _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"
}
渲染順序:先藍色方塊再白色方塊(以下簡稱藍,白)注意ZWrite默認值為On,ZTest默認值為LEqual,沒有渲染物體時,深度緩存中的深度可以理解為無限大1.
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面分析:藍沒有將像素寫進深度緩存中,顏色緩沖區中存放了藍的顏色值;而白將像素寫進深度緩存中,深度緩存被替換了,深度緩存中深度對應的顏色也被舍棄了,所以顯示白
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:藍在前面分析:藍將像素寫進深度緩存中;而白將像素寫進深度緩存時,因為像素深度大于藍的,被遮擋的像素被舍棄,所以顯示藍
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
ZWrite OffZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面分析:與1類似
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面
分析:藍將像素寫進了深度緩存中;白沒有成功將像素寫進了深度緩存中,但因為ZTest Off,白將顏色緩存中的藍的像素顏色值替換了。也就是深度緩存中是藍像素的深度,顏色緩沖中是白像素的顏色
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面
分析:與4類似
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面
分析:與5類似
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面
分析:白、藍都沒有將像素寫入深度緩存中,所以深度緩存中的深度值為無窮大,最后因為白中ZTest默認值的原因,所以顯示白
/////////////////////////////////////////藍色方塊測試區
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
ZTest Off
/////////////////////////////////////////藍色方塊測試區
/////////////////////////////////////////白色方塊測試區
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
ZTest Off
/////////////////////////////////////////白色方塊測試區
結果:白在前面
分析:與7類似