渲染隊列、ZWrite和ZTest

<轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者

(1)什么是深度?

?深度其實就是該像素點在3d世界中距離攝像機的距離。離攝像機越遠(yuǎn),則深度值(Z值)越大。


(2)什么是深度緩存?

深度緩存中存儲著準(zhǔn)備要繪制在屏幕上的像素點的深度值。如果啟用了深度緩沖區(qū),在繪制每個像素之前,OpenGL會把該像素的深度值和深度緩存的深度值進(jìn)行比較。如果新像素深度值<深度緩存深度值,則新像素值會取代原先的;反之,新像素值被遮擋,其顏色值和深度將被丟棄。(深度主要起的是比較的作用)


(3)什么是深度測試

在深度測試中,默認(rèn)情況是將要繪制的新像素的z值與深度緩沖區(qū)中對應(yīng)位置的z值進(jìn)行比較,如果比深度緩存中的值小,那么用新像素的顏色值更新深度緩存中對應(yīng)像素的顏色值。


(4)為什么需要深度?

在不使用深度測試的時候,如果我們先繪制一個距離較近的物體,再繪制距離較遠(yuǎn)的物體,則距離遠(yuǎn)的物體因為后繪制,會把距離近的物體覆蓋掉,這樣的效果并不是我們所希望的。而有了深度緩沖以后,繪制物體的順序就不那么重要了,都能按照遠(yuǎn)近(Z值)正常顯示,這很關(guān)鍵。



那么,在unity中,如果知道了渲染隊列,ZWrite,ZTest,如何確定哪個物體先顯示呢?

首先,unity先將渲染隊列中較前的進(jìn)行渲染,然后再執(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)前像素顏色(不是深度)寫進(jìn)顏色緩沖區(qū)中;而Never指的是不要將當(dāng)前像素顏色寫進(jìn)顏色緩沖區(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)沒有將像素寫進(jìn)深度緩存中,ZTest通過了,顏色緩存中存放了藍(lán)的顏色值

白將像素寫進(jì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)將像素寫進(jìn)深度緩存中,ZTest通過了,顏色緩存中存放了藍(lán)的顏色值

而白的像素深度大于藍(lán)的,既沒有成功將像素寫進(jì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)沒有將像素寫進(jìn)深度緩存中,ZTest通過了,顏色緩存中存放了藍(lán)的顏色值

白將像素寫進(jì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)將像素寫進(jìn)了深度緩存中

白將像素寫進(jì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)將像素寫進(jìn)了深度緩存中

白沒能將像素寫進(jìn)了深度緩存中(ZWrite為off),但ZTest通過了,此時顏色緩存的值變?yōu)榘椎模巧疃染彺娴闹凳撬{(lán)的


6.

/////////////////////////////////////////藍(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)將像素寫進(jìn)了深度緩存中

    白將像素寫進(jìn)了深度緩存中,ZTest通過了,此時顏色緩存的值變?yōu)榘椎?/p>


    7.

  • /////////////////////////////////////////藍(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默認(rèn)值的原因,所以顯示白


    8.

  • /////////////////////////////////////////藍(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é)果:白在前面

    分析:與7類似

    最后編輯于
    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

    推薦閱讀更多精彩內(nèi)容

    • 本篇unity3d教程我們來看下Unity渲染隊列、ZWrite和ZTest相關(guān)介紹,首先我們來了解幾個概念(1)...
      JumboWu閱讀 5,291評論 1 8
    • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
      卡卡羅2017閱讀 134,908評論 18 139
    • 一.Tags(標(biāo)簽)通過使用tags來告訴渲染引擎在什么時候該如何渲染他們所期望的效果。注意的是,SubShade...
      karma085閱讀 5,383評論 1 4
    • 李希貴說,“從來就沒有意義上任何培訓(xùn),所謂的培訓(xùn)只是讓你遇到某個人,經(jīng)歷某件事。” 春暖花開的三月,有幸跟楊校長一...
      董余蘭閱讀 592評論 0 2
    • 是五月的橙紅柳綠 喚醒早初的夏滿 每個人都在忙忙碌碌尋寶藏 我只想記得家在哪里 夜里的熏燈 院子里的燈籠微微在閃 ...
      白箋閱讀 308評論 0 2