<轉(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)場(chǎng)景覆享,一藍(lán)一紅兩個(gè)Cube佳遂。藍(lán)在紅前。
? ? 兩個(gè)方塊所使用的Shader都是最簡(jiǎn)單的 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 ,深度測(cè)試不撑;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)饿序,深度值越大。
? ? 例如在我們的場(chǎng)景中羹蚣,藍(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è)過程就是深度測(cè)試)闹蒜,由于默認(rèn)的 ZTest 深度測(cè)試的方式是 LEqual 小于等于寺枉,即深度值小于等于 0.5 的顏色才會(huì)通過測(cè)試。如果通過了測(cè)試绷落,且 ZWirte 處于 On 的狀態(tài)姥闪,該顏色的深度值就會(huì)替代深度緩沖區(qū)中的值,顏色值也會(huì)替代顏色緩沖區(qū)中的值砌烁,從而顯示出新顏色筐喳。
? ? 很顯然,0.7 > 0.5函喉,所以紅色并不能通過測(cè)試避归,紅塊也就不能顯示在藍(lán)塊前面。
? ? 如果我們硬要遠(yuǎn)處的紅塊遮擋住近處的藍(lán)塊管呵,很顯然梳毙,我們應(yīng)該改變或關(guān)閉深度測(cè)試,或者關(guān)閉深度寫入(關(guān)閉了深度測(cè)試或者深度寫入之后撇寞,物體顏色的遮擋關(guān)系就會(huì)和渲染隊(duì)列一致,即排在后面的會(huì)擋住前面的)堂氯。
? ? 接下來我們?cè)囋囮P(guān)閉藍(lán)塊的深度寫入:
? ? 得到了想要的結(jié)果:
? ? 再試試單獨(dú)關(guān)閉紅塊的深度測(cè)試蔑担,注釋藍(lán)塊的深度寫入:
? ? 結(jié)果還是一樣。但如果我們改變紅塊深度測(cè)試的方式呢:
? ? 即深度值大于深度緩沖區(qū)中的值就能通過測(cè)試咽白,還記得我們假設(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届搁,所以紅塊另一半沒有通過深度測(cè)試。