Unity ZTest 深度測試 & ZWrite 深度寫入


    初學Shader,一開始對於渲染隊列,ZTest 和 ZWrite一頭霧水,經過多方查閱和實驗,有了一些自己的理解。發此文與初學Shader的朋友分享,也算是為自己做個筆記。不對或不足之處歡迎指正。

    不說廢話,直接進入正題。 

    首先是實驗場景,一藍一紅兩個Cube。藍在紅前。

     

 

    兩個方塊所使用的Shader都是最簡單的 V&F 着色程序,不同的是藍色方塊alpha返回值為0.6,紅色為1。

     

 

     但是藍色方塊並沒有絲毫透明的效果,這時我們在藍色方塊的Shader內加上這樣一行代碼 : 

     Blend SrcAlpha OneMinusSrcAlpha 。

     

 

     稍微解釋一下,這行指令意思就是將本 Shader 計算出的顏色值(源顏色值,即藍色) * 源Alpha值(0.6) + 目標顏色值(可以理解為背景色) * (1-0.6),從而讓藍色方塊展示出了40%的透明度。

    然后我們看到了這樣的效果:

    

 

    似乎有些透明的樣子了,但是紅色方塊還是顯示不出來。我們再加上這樣一行代碼:

     Tags {"Queue" = "Transparent"}

     

 

    意思是設置它在渲染隊列中的值為 Transparent (透明) = 3000,值越小越先渲染,而后渲染( Queue 值大)的物體會覆蓋先渲染的物體(紅塊未設置 Queue 值,默認為 Geometry(幾何體) = 2000)。在理想的世界中,我們應該讓遠處的物體先渲染,近處的物體后渲染,這樣遠處的物體就不會遮擋住近的物體。

    接下來我們看到了正確的結果:

    

   

    Queue 其他預定義的值為:Background = 1000 , AlphaTest = 2450,Overlay = 4000。默認值是Geometry 。

    例如:如果我們想讓遠處的紅色方塊遮擋住近處的藍色方塊,即讓藍色的先渲染,紅色的后渲染,只需將紅塊的Queue 也設置為 Transparent ,藍塊的Queue值-1。

    

 

    然后我們看看效果:

    

 

    好像並沒有什么卵用。。。這是為什么呢?

    原因在於這樣兩條指令:

    

    雖然我們的代碼里並沒有這兩行,但它們是默認存在的。

 

     ZTest ,深度測試;LEqual ,小於等於。

     ZWrite ,深度寫入,On ,打開。

 

     ZTest 可取值為:Greater , GEqual , Less , LEqual , Equal , NotEqual , Always , Never , Off,默認是 LEqual,ZTest Off 等同於 ZTest Always。

     ZWrite 可取值為:On , Off,默認是 On。

 

    系統中存在一個顏色緩沖區和一個深度緩沖區,分別存儲顏色值和深度值,來決定畫面上應該顯示什么顏色。

    深度值是物體在世界空間中距離攝像機的遠近。距離越近,深度值越小;距離越遠,深度值越大。

    例如在我們的場景中,藍色方塊比紅色更靠近相機,藍塊的深度值就比紅塊小。

    假設藍塊的深度值為 0.5,紅塊為 0.7。還記得在上面的例子中,我們讓藍塊在渲染隊列中排在紅塊前面,系統就先將藍色值存入了顏色緩沖區中對應的區域,將深度值 0.5 存入了深度緩沖區中對應的區域。接下來渲染紅塊,系統會將紅塊的深度值與深度緩沖區中的值進行比較(這個過程就是深度測試),由於默認的 ZTest 深度測試的方式是 LEqual 小於等於,即深度值小於等於 0.5 的顏色才會通過測試。如果通過了測試,且 ZWirte 處於 On 的狀態,該顏色的深度值就會替代深度緩沖區中的值,顏色值也會替代顏色緩沖區中的值,從而顯示出新顏色。

    很顯然,0.7 > 0.5,所以紅色並不能通過測試,紅塊也就不能顯示在藍塊前面。

    如果我們硬要遠處的紅塊遮擋住近處的藍塊,很顯然,我們應該改變或關閉深度測試,或者關閉深度寫入(關閉了深度測試或者深度寫入之后,物體顏色的遮擋關系就會和渲染隊列一致,即排在后面的會擋住前面的)。

 

    接下來我們試試關閉藍塊的深度寫入:

    

    得到了想要的結果:

    

   

    再試試單獨關閉紅塊的深度測試,注釋藍塊的深度寫入:

     

    

    結果還是一樣。但如果我們改變紅塊深度測試的方式呢:

    

 

    即深度值大於深度緩沖區中的值就能通過測試,還記得我們假設紅塊深度值為 0.7,藍塊為 0.5。理論上會得到我們想要的結果:

    

    

    奇怪的是,紅塊的另一半去哪了?

    答案是被背景擋住了。

    按照距離相機的遠近,我們可以假設背景的深度值為 1。在消失的另一半的深度緩沖區中的深度值應該是背景的深度值 1。而我們設置了 ZTest Greater,0.7 < 1,所以紅塊另一半沒有通過深度測試。

 

 

 

     本文到此結束,由於是第一次寫博客,還希望大家能多多指正!

    

   

 

    

   

    

 

    

    

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM