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

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

初學(xué)Shader,一開始對(duì)于渲染隊(duì)列,ZTest 和 ZWrite一頭霧水,經(jīng)過多方查閱和實(shí)驗(yàn),有了一些自己的理解。發(fā)此文與初學(xué)Shader的朋友分享,也算是為自己做個(gè)筆記。不對(duì)或不足之處歡迎指正。

? ? 不說廢話,直接進(jìn)入正題。?

? ? 首先是實(shí)驗(yàn)場景,一藍(lán)一紅兩個(gè)Cube。藍(lán)在紅前。

? ? 兩個(gè)方塊所使用的Shader都是最簡單的 V&F 著色程序,不同的是藍(lán)色方塊alpha返回值為0.6,紅色為1。

? ? ?但是藍(lán)色方塊并沒有絲毫透明的效果,這時(shí)我們?cè)谒{(lán)色方塊的Shader內(nèi)加上這樣一行代碼 :?

? ? ?Blend SrcAlpha OneMinusSrcAlpha 。

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

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

? ? 似乎有些透明的樣子了,但是紅色方塊還是顯示不出來。我們?cè)偌由线@樣一行代碼:

? ? ?Tags {"Queue" = "Transparent"}

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

? ? 接下來我們看到了正確的結(jié)果:

? ? Queue 其他預(yù)定義的值為:Background = 1000 , AlphaTest = 2450,Overlay = 4000。默認(rèn)值是Geometry 。

? ? 例如:如果我們想讓遠(yuǎn)處的紅色方塊遮擋住近處的藍(lán)色方塊,即讓藍(lán)色的先渲染,紅色的后渲染,只需將紅塊的Queue 也設(shè)置為?Transparent ,藍(lán)塊的Queue值-1。

? ? 然后我們看看效果:

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

? ? 原因在于這樣兩條指令:

? ? 雖然我們的代碼里并沒有這兩行,但它們是默認(rèn)存在的。

? ? ?ZTest ,深度測試;LEqual ,小于等于。

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

? ? ?ZTest 可取值為:Greater , GEqual , Less , LEqual , Equal , NotEqual , Always , Never , Off,默認(rèn)是 LEqual,ZTest Off 等同于 ZTest Always。

? ???ZWrite 可取值為:On , Off,默認(rèn)是 On。

? ??系統(tǒng)中存在一個(gè)顏色緩沖區(qū)和一個(gè)深度緩沖區(qū),分別存儲(chǔ)顏色值和深度值,來決定畫面上應(yīng)該顯示什么顏色。

? ? 深度值是物體在世界空間中距離攝像機(jī)的遠(yuǎn)近。距離越近,深度值越??;距離越遠(yuǎn),深度值越大。

? ? 例如在我們的場景中,藍(lán)色方塊比紅色更靠近相機(jī),藍(lán)塊的深度值就比紅塊小。

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

? ? 很顯然,0.7 > 0.5,所以紅色并不能通過測試,紅塊也就不能顯示在藍(lán)塊前面。

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

? ? 接下來我們?cè)囋囮P(guān)閉藍(lán)塊的深度寫入:

? ? 得到了想要的結(jié)果:

? ? 再試試單獨(dú)關(guān)閉紅塊的深度測試,注釋藍(lán)塊的深度寫入:

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

? ? 即深度值大于深度緩沖區(qū)中的值就能通過測試,還記得我們假設(shè)紅塊深度值為 0.7,藍(lán)塊為 0.5。理論上會(huì)得到我們想要的結(jié)果:

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

? ? 答案是被背景擋住了。

? ? 按照距離相機(jī)的遠(yuǎn)近,我們可以假設(shè)背景的深度值為 1。在消失的另一半的深度緩沖區(qū)中的深度值應(yīng)該是背景的深度值 1。而我們?cè)O(shè)置了 ZTest Greater,0.7 < 1,所以紅塊另一半沒有通過深度測試。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容