<轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者
(1)什么是深度现斋?
?深度其實就是該像素點在3d世界中距離攝像機的距離转唉。離攝像機越遠(yuǎn)劝堪,則深度值(Z值)越大贬墩。
(2)什么是深度緩存呀闻?
深度緩存中存儲著準(zhǔn)備要繪制在屏幕上的像素點的深度值精肃。如果啟用了深度緩沖區(qū)秤涩,在繪制每個像素之前,OpenGL會把該像素的深度值和深度緩存的深度值進行比較司抱。如果新像素深度值<深度緩存深度值筐眷,則新像素值會取代原先的;反之习柠,新像素值被遮擋匀谣,其顏色值和深度將被丟棄。(深度主要起的是比較的作用)
(3)什么是深度測試资溃?
在深度測試中武翎,默認(rèn)情況是將要繪制的新像素的z值與深度緩沖區(qū)中對應(yīng)位置的z值進行比較,如果比深度緩存中的值小溶锭,那么用新像素的顏色值更新深度緩存中對應(yīng)像素的顏色值宝恶。
(4)為什么需要深度?
在不使用深度測試的時候趴捅,如果我們先繪制一個距離較近的物體垫毙,再繪制距離較遠(yuǎn)的物體,則距離遠(yuǎn)的物體因為后繪制拱绑,會把距離近的物體覆蓋掉露久,這樣的效果并不是我們所希望的。而有了深度緩沖以后欺栗,繪制物體的順序就不那么重要了毫痕,都能按照遠(yuǎn)近(Z值)正常顯示征峦,這很關(guān)鍵。
那么消请,在unity中栏笆,如果知道了渲染隊列,ZWrite臊泰,ZTest蛉加,如何確定哪個物體先顯示呢?
首先缸逃,unity先將渲染隊列中較前的進行渲染针饥,然后再執(zhí)行ZWrite,ZTest
ZWrite可以取的值為:On/Off需频,默認(rèn)值為On丁眼,代表是否要將像素的深度寫入深度緩存中(同時還要看ZTest是否通過)。
ZTest可以取的值為:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off昭殉,默認(rèn)值為LEqual苞七,代表通過比較深度來更改顏色緩存的值。例如當(dāng)取默認(rèn)值的情況下挪丢,如果將要繪制的新像素的z值小于等于深度緩存中的值蹂风,則將用新像素的顏色值更新深度緩存中對應(yīng)像素的顏色值。需要注意的是乾蓬,當(dāng)ZTest取值為Off時惠啄,表示的是關(guān)閉深度測試,等價于取值為Always任内,而不是Never礁阁!Always指的是直接將當(dāng)前像素顏色(不是深度)寫進顏色緩沖區(qū)中;而Never指的是不要將當(dāng)前像素顏色寫進顏色緩沖區(qū)中族奢,相當(dāng)于消失。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
那么丹鸿,重點來了:
1.當(dāng)ZWrite為On時越走,ZTest通過時,該像素的深度才能成功寫入深度緩存靠欢,同時因為ZTest通過了廊敌,該像素的顏色值也會寫入顏色緩存。
2.當(dāng)ZWrite為On時门怪,ZTest不通過時骡澈,該像素的深度不能成功寫入深度緩存,同時因為ZTest不通過掷空,該像素的顏色值不會寫入顏色緩存肋殴。
3.當(dāng)ZWrite為Off時囤锉,ZTest通過時,該像素的深度不能成功寫入深度緩存护锤,同時因為ZTest通過了官地,該像素的顏色值會寫入顏色緩存。
4.當(dāng)ZWrite為Off時烙懦,ZTest不通過時驱入,該像素的深度不能成功寫入深度緩存,同時因為ZTest不通過氯析,該像素的顏色值不會寫入顏色緩存亏较。
可以看到,像素的深度能否成功寫入深度緩存掩缓,條件是ZWrite為On雪情,ZTest通過;
寫入深度緩存的作用就是為ZTest的比較做準(zhǔn)備拾因。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
因為ZWrite默認(rèn)值為On旺罢,ZTest默認(rèn)值為LEqual,所以這很好地解釋了為什么在unity中绢记,距離相機近的東西會阻擋住距離相機遠(yuǎn)的東西扁达。如果我們先繪制一個距離較近的物體,再繪制距離較遠(yuǎn)的物體蠢熄,則距離遠(yuǎn)的物體因為后繪制跪解,會把距離近的物體覆蓋掉,這時我們可以通過修改ZWrite和ZTest來改變物體的遮擋關(guān)系签孔!
測試環(huán)境(藍(lán)色方塊距離相機較近叉讥,注意這個不是Game視圖):
測試的Shader代碼(兩個方塊的shader代碼起始都是一樣的,測試時修改的是測試區(qū)里的代碼):
Shader?"Custom/ZTest"?{??
????Properties?{??
????????_MainTex?("Base?(RGB)",?2D)?=?"white"?{}??
????}??
????SubShader?{??
????????Tags?{?"RenderType"="Opaque"?}??
????????LOD?200??
/////////////////////////////////////////測試區(qū)??
????????Tags{?"Queue"?=?"Geometry"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////測試區(qū)??
????????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"??
}??
渲染順序:先藍(lán)色方塊再白色方塊(以下簡稱藍(lán)饥追,白)
注意ZWrite默認(rèn)值為On图仓,ZTest默認(rèn)值為LEqual,沒有渲染物體時但绕,深度緩存中的深度可以理解為無限大
1.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
/////////////////////////////////////////白色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測試區(qū)??
結(jié)果:白在前面
分析:藍(lán)沒有將像素寫進深度緩存中救崔,ZTest通過了,顏色緩存中存放了藍(lán)的顏色值
白將像素寫進深度緩存中捏顺,ZTest通過了六孵,顏色緩存的值變?yōu)榘椎模燥@示白
2.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
/////////////////////////////////////////白色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測試區(qū)??
結(jié)果:藍(lán)在前面
分析:藍(lán)將像素寫進深度緩存中幅骄,ZTest通過了劫窒,顏色緩存中存放了藍(lán)的顏色值
而白的像素深度大于藍(lán)的,既沒有成功將像素寫進深度緩存拆座,同時ZTest不通過主巍,像素被舍棄冠息,所以顯示藍(lán)
3.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
/////////////////////////////////////////白色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測試區(qū)??
結(jié)果:白在前面
分析:藍(lán)沒有將像素寫進深度緩存中,ZTest通過了煤禽,顏色緩存中存放了藍(lán)的顏色值
白將像素寫進深度緩存中铐达,ZTest通過了,顏色緩存中存放為白的顏色值
4.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
/////////////////////////////////////////白色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////白色方塊測試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進了深度緩存中
白將像素寫進了深度緩存中檬果,ZTest通過了瓮孙,白將顏色緩存中的藍(lán)的像素顏色值替換了。
5.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
/////////////////////////////////////////白色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////白色方塊測試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進了深度緩存中
白沒能將像素寫進了深度緩存中(ZWrite為off)选脊,但ZTest通過了杭抠,此時顏色緩存的值變?yōu)榘椎模巧疃染彺娴闹凳撬{(lán)的
6.
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進了深度緩存中
白將像素寫進了深度緩存中恳啥,ZTest通過了偏灿,此時顏色緩存的值變?yōu)榘椎?/p>
7.
結(jié)果:白在前面
分析:白、藍(lán)都沒有將像素寫入深度緩存中钝的,所以深度緩存中的深度值為無窮大翁垂,最后因為白中ZTest默認(rèn)值的原因,所以顯示白
8.
結(jié)果:白在前面
分析:與7類似