<轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者
(1)什么是深度?
?深度其實(shí)就是該像素點(diǎn)在3d世界中距離攝像機(jī)的距離。離攝像機(jī)越遠(yuǎn),則深度值(Z值)越大。
(2)什么是深度緩存?
深度緩存中存儲(chǔ)著準(zhǔn)備要繪制在屏幕上的像素點(diǎn)的深度值。如果啟用了深度緩沖區(qū),在繪制每個(gè)像素之前,OpenGL會(huì)把該像素的深度值和深度緩存的深度值進(jìn)行比較。如果新像素深度值<深度緩存深度值,則新像素值會(huì)取代原先的;反之,新像素值被遮擋,其顏色值和深度將被丟棄。(深度主要起的是比較的作用)
(3)什么是深度測(cè)試?
在深度測(cè)試中,默認(rèn)情況是將要繪制的新像素的z值與深度緩沖區(qū)中對(duì)應(yīng)位置的z值進(jìn)行比較,如果比深度緩存中的值小,那么用新像素的顏色值更新深度緩存中對(duì)應(yīng)像素的顏色值。
(4)為什么需要深度?
在不使用深度測(cè)試的時(shí)候,如果我們先繪制一個(gè)距離較近的物體,再繪制距離較遠(yuǎn)的物體,則距離遠(yuǎn)的物體因?yàn)楹罄L制,會(huì)把距離近的物體覆蓋掉,這樣的效果并不是我們所希望的。而有了深度緩沖以后,繪制物體的順序就不那么重要了,都能按照遠(yuǎn)近(Z值)正常顯示,這很關(guān)鍵。
那么,在unity中,如果知道了渲染隊(duì)列,ZWrite,ZTest,如何確定哪個(gè)物體先顯示呢?
首先,unity先將渲染隊(duì)列中較前的進(jìn)行渲染,然后再執(zhí)行ZWrite,ZTest
ZWrite可以取的值為:On/Off,默認(rèn)值為On,代表是否要將像素的深度寫入深度緩存中(同時(shí)還要看ZTest是否通過(guò))。
ZTest可以取的值為:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默認(rèn)值為L(zhǎng)Equal,代表通過(guò)比較深度來(lái)更改顏色緩存的值。例如當(dāng)取默認(rèn)值的情況下,如果將要繪制的新像素的z值小于等于深度緩存中的值,則將用新像素的顏色值更新深度緩存中對(duì)應(yīng)像素的顏色值。需要注意的是,當(dāng)ZTest取值為Off時(shí),表示的是關(guān)閉深度測(cè)試,等價(jià)于取值為Always,而不是Never!Always指的是直接將當(dāng)前像素顏色(不是深度)寫進(jìn)顏色緩沖區(qū)中;而Never指的是不要將當(dāng)前像素顏色寫進(jìn)顏色緩沖區(qū)中,相當(dāng)于消失。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
那么,重點(diǎn)來(lái)了:
1.當(dāng)ZWrite為On時(shí),ZTest通過(guò)時(shí),該像素的深度才能成功寫入深度緩存,同時(shí)因?yàn)閆Test通過(guò)了,該像素的顏色值也會(huì)寫入顏色緩存。
2.當(dāng)ZWrite為On時(shí),ZTest不通過(guò)時(shí),該像素的深度不能成功寫入深度緩存,同時(shí)因?yàn)閆Test不通過(guò),該像素的顏色值不會(huì)寫入顏色緩存。
3.當(dāng)ZWrite為Off時(shí),ZTest通過(guò)時(shí),該像素的深度不能成功寫入深度緩存,同時(shí)因?yàn)閆Test通過(guò)了,該像素的顏色值會(huì)寫入顏色緩存。
4.當(dāng)ZWrite為Off時(shí),ZTest不通過(guò)時(shí),該像素的深度不能成功寫入深度緩存,同時(shí)因?yàn)閆Test不通過(guò),該像素的顏色值不會(huì)寫入顏色緩存。
可以看到,像素的深度能否成功寫入深度緩存,條件是ZWrite為On,ZTest通過(guò);
寫入深度緩存的作用就是為ZTest的比較做準(zhǔn)備。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
因?yàn)閆Write默認(rèn)值為On,ZTest默認(rèn)值為L(zhǎng)Equal,所以這很好地解釋了為什么在unity中,距離相機(jī)近的東西會(huì)阻擋住距離相機(jī)遠(yuǎn)的東西。如果我們先繪制一個(gè)距離較近的物體,再繪制距離較遠(yuǎn)的物體,則距離遠(yuǎn)的物體因?yàn)楹罄L制,會(huì)把距離近的物體覆蓋掉,這時(shí)我們可以通過(guò)修改ZWrite和ZTest來(lái)改變物體的遮擋關(guān)系!
測(cè)試環(huán)境(藍(lán)色方塊距離相機(jī)較近,注意這個(gè)不是Game視圖):
測(cè)試的Shader代碼(兩個(gè)方塊的shader代碼起始都是一樣的,測(cè)試時(shí)修改的是測(cè)試區(qū)里的代碼):
Shader?"Custom/ZTest"?{??
????Properties?{??
????????_MainTex?("Base?(RGB)",?2D)?=?"white"?{}??
????}??
????SubShader?{??
????????Tags?{?"RenderType"="Opaque"?}??
????????LOD?200??
/////////////////////////////////////////測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////測(cè)試區(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)色方塊再白色方塊(以下簡(jiǎn)稱藍(lán),白)
注意ZWrite默認(rèn)值為On,ZTest默認(rèn)值為L(zhǎng)Equal,沒(méi)有渲染物體時(shí),深度緩存中的深度可以理解為無(wú)限大
1.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
結(jié)果:白在前面
分析:藍(lán)沒(méi)有將像素寫進(jìn)深度緩存中,ZTest通過(guò)了,顏色緩存中存放了藍(lán)的顏色值
白將像素寫進(jìn)深度緩存中,ZTest通過(guò)了,顏色緩存的值變?yōu)榘椎模燥@示白
2.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
結(jié)果:藍(lán)在前面
分析:藍(lán)將像素寫進(jìn)深度緩存中,ZTest通過(guò)了,顏色緩存中存放了藍(lán)的顏色值
而白的像素深度大于藍(lán)的,既沒(méi)有成功將像素寫進(jìn)深度緩存,同時(shí)ZTest不通過(guò),像素被舍棄,所以顯示藍(lán)
3.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
結(jié)果:白在前面
分析:藍(lán)沒(méi)有將像素寫進(jìn)深度緩存中,ZTest通過(guò)了,顏色緩存中存放了藍(lán)的顏色值
白將像素寫進(jìn)深度緩存中,ZTest通過(guò)了,顏色緩存中存放為白的顏色值
4.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????//ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進(jìn)了深度緩存中
白將像素寫進(jìn)了深度緩存中,ZTest通過(guò)了,白將顏色緩存中的藍(lán)的像素顏色值替換了。
5.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????//ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+300"?}??
????????ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////白色方塊測(cè)試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進(jìn)了深度緩存中
白沒(méi)能將像素寫進(jìn)了深度緩存中(ZWrite為off),但ZTest通過(guò)了,此時(shí)顏色緩存的值變?yōu)榘椎模巧疃染彺娴闹凳撬{(lán)的
6.
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
????????Tags{?"Queue"?=?"Geometry+200"?}??
????????//ZWrite?Off??
????????ZTest?Off??
/////////////////////////////////////////藍(lán)色方塊測(cè)試區(qū)??
結(jié)果:白在前面
分析:藍(lán)將像素寫進(jìn)了深度緩存中
白將像素寫進(jìn)了深度緩存中,ZTest通過(guò)了,此時(shí)顏色緩存的值變?yōu)榘椎?/p>
7.
結(jié)果:白在前面
分析:白、藍(lán)都沒(méi)有將像素寫入深度緩存中,所以深度緩存中的深度值為無(wú)窮大,最后因?yàn)榘字衂Test默認(rèn)值的原因,所以顯示白
8.
結(jié)果:白在前面
分析:與7類似