Unity Shader-渲染隊(duì)列,ZTest逞怨,ZWrite者疤,Early-Z(轉(zhuǎn))

Unity Shader-渲染隊(duì)列,ZTest叠赦,ZWrite驹马,Early-Z

簡(jiǎn)介

在渲染階段革砸,引擎所做的工作是把所有場(chǎng)景中的對(duì)象按照一定的策略(順序)進(jìn)行渲染。最早的是畫(huà)家算法糯累,顧名思義算利,就是像畫(huà)家畫(huà)畫(huà)一樣,先畫(huà)后面的物體泳姐,如果前面還有物體效拭,那么就用前面的物體把物體覆蓋掉,不過(guò)這種方式由于排序是針對(duì)物體來(lái)排序的胖秒,而物體之間也可能有重疊缎患,所以效果并不好。所以目前更加常用的方式是z-buffer算法阎肝,類似顏色緩沖區(qū)緩沖顏色挤渔,z-buffer中存儲(chǔ)的是當(dāng)前的深度信息,對(duì)于每個(gè)像素存儲(chǔ)一個(gè)深度值风题,這樣判导,我們屏幕上顯示的每個(gè)像素點(diǎn)都會(huì)進(jìn)行深度排序,就可以保證繪制的遮擋關(guān)系是正確的沛硅。而控制z-buffer就是通過(guò)ZTest眼刃,和ZWrite來(lái)進(jìn)行。但是有時(shí)候需要更加精準(zhǔn)的控制不同類型的對(duì)象的渲染順序稽鞭,所以就有了渲染隊(duì)列鸟整。今天就來(lái)學(xué)習(xí)一下渲染隊(duì)列,ZTest朦蕴,ZWrite的基本使用以及分析一下Unity為了Early-Z所做的一些優(yōu)化篮条。

Unity中的幾種渲染隊(duì)列

首先看一下Unity中的幾種內(nèi)置的渲染隊(duì)列,按照渲染順序吩抓,從先到后進(jìn)行排序涉茧,隊(duì)列數(shù)越小的,越先渲染疹娶,隊(duì)列數(shù)越大的伴栓,越后渲染。

Background(1000) 最早被渲染的物體的隊(duì)列雨饺。
Geometry   (2000) 不透明物體的渲染隊(duì)列钳垮。大多數(shù)物體都應(yīng)該使用該隊(duì)列進(jìn)行渲染,也是Unity Shader中默認(rèn)的渲染隊(duì)列额港。
AlphaTest   (2450) 有透明通道饺窿,需要進(jìn)行Alpha Test的物體的隊(duì)列,比在Geomerty中更有效移斩。
Transparent(3000) 半透物體的渲染隊(duì)列肚医。一般是不寫(xiě)深度的物體绢馍,Alpha Blend等的在該隊(duì)列渲染。
Overlay      (4000) 最后被渲染的物體的隊(duì)列肠套,一般是覆蓋效果舰涌,比如鏡頭光暈,屏幕貼片之類的你稚。

Unity中設(shè)置渲染隊(duì)列也很簡(jiǎn)單瓷耙,我們不需要手動(dòng)創(chuàng)建,也不需要寫(xiě)任何腳本入宦,只需要在shader中增加一個(gè)Tag就可以了哺徊,當(dāng)然,如果不加乾闰,那么就是默認(rèn)的渲染隊(duì)列Geometry落追。比如我們需要我們的物體在Transparent這個(gè)渲染隊(duì)列中進(jìn)行渲染的話,就可以這樣寫(xiě):

Tags { "Queue" = "Transparent"}

我們可以直接在shader的Inspector面板上看到shader的渲染隊(duì)列:


另外涯肩,我們?cè)趯?xiě)shader的時(shí)候還經(jīng)常有個(gè)Tag叫RenderType轿钠,不過(guò)這個(gè)沒(méi)有Render Queue那么常用,這里順便記錄一下:
Opaque: 用于大多數(shù)著色器(法線著色器病苗、自發(fā)光著色器疗垛、反射著色器以及地形的著色器)。
Transparent:用于半透明著色器(透明著色器硫朦、粒子著色器贷腕、字體著色器、地形額外通道的著色器)咬展。
TransparentCutout: 蒙皮透明著色器(Transparent Cutout泽裳,兩個(gè)通道的植被著色器)。
Background: 天空盒著色器破婆。
Overlay: GUITexture涮总,鏡頭光暈,屏幕閃光等效果使用的著色器祷舀。
TreeOpaque: 地形引擎中的樹(shù)皮瀑梗。
TreeTransparentCutout: 地形引擎中的樹(shù)葉。
TreeBillboard: 地形引擎中的廣告牌樹(shù)裳扯。
Grass: 地形引擎中的草抛丽。
GrassBillboard: 地形引擎何中的廣告牌草。

相同渲染隊(duì)列中不透明物體的渲染順序

拿出Unity饰豺,創(chuàng)建三個(gè)立方體亿鲜,都使用默認(rèn)的bump diffuse shader(渲染隊(duì)列相同),分別給三個(gè)不同的材質(zhì)(相同材質(zhì)的小頂點(diǎn)數(shù)的物體引擎會(huì)動(dòng)態(tài)合批)哟忍,用Unity5帶的Frame Debug工具查看一下Draw Call狡门。(Unity5真是好用得多了,如果用4的話锅很,還得用NSight之類的抓幀)


可以看出其馏,Unity中對(duì)于不透明的物體,是采用了從前到后的渲染順序進(jìn)行渲染的爆安,這樣叛复,不透明物體在進(jìn)行完vertex階段,進(jìn)行Z Test扔仓,然后就可以得到該物體最終是否在屏幕上可見(jiàn)了褐奥,如果前面渲染完的物體已經(jīng)寫(xiě)好了深度,深度測(cè)試失敗翘簇,那么后面渲染的物體就直接不會(huì)再去進(jìn)行fragment階段撬码。(不過(guò)這里需要把三個(gè)物體之間的距離稍微拉開(kāi)一些,本人在測(cè)試時(shí)發(fā)現(xiàn)版保,如果距離特別近呜笑,就會(huì)出現(xiàn)渲染次序比較亂的情況晌梨,因?yàn)槲覀儾恢繳nity內(nèi)部具體排序時(shí)是按照什么標(biāo)準(zhǔn)來(lái)判定的哪個(gè)物體離攝像機(jī)更近悄晃,這里我也就不妄加猜測(cè)了)

相同渲染隊(duì)列中半透明物體的渲染順序

透明物體的渲染一直是圖形學(xué)方面比較蛋疼的地方击奶,對(duì)于透明物體的渲染铭乾,就不能像渲染不透明物體那樣多快好省了锡宋,因?yàn)橥该魑矬w不會(huì)寫(xiě)深度盟猖,也就是說(shuō)透明物體之間的穿插關(guān)系是沒(méi)有辦法判斷的州藕,所以半透明的物體在渲染的時(shí)候一般都是采用從后向前的方法進(jìn)行渲染纽门,由于透明物體多了森篷,透明物體不寫(xiě)深度输钩,那么透明物體之間就沒(méi)有所謂的可以通過(guò)深度測(cè)試來(lái)剔除的優(yōu)化,每個(gè)透明物體都會(huì)走像素階段的渲染疾宏,會(huì)造成大量的Over Draw张足。這也就是粒子特效特別耗費(fèi)性能的原因。

我們實(shí)驗(yàn)一下Unity中渲染半透明物體的順序坎藐,還是上面的三個(gè)立方體为牍,我們把材質(zhì)的shader統(tǒng)一換成粒子最常用的Particle/Additive類型的shader,再用Frame Debug工具查看一下渲染的順序:


半透明的物體渲染的順序是從后到前岩馍,不過(guò)由于半透相關(guān)的內(nèi)容比較復(fù)雜碉咆,就先不在這篇文章中說(shuō)了,打算另起一篇蛀恩。

自定義渲染隊(duì)列

Unity支持我們自定義渲染隊(duì)列疫铜,比如我們需要保證某種類型的對(duì)象需要在其他類型的對(duì)象渲染之后再渲染,就可以通過(guò)自定義渲染隊(duì)列進(jìn)行渲染双谆。而且超級(jí)方便壳咕,我們只需要在寫(xiě)shader的時(shí)候修改一下渲染隊(duì)列中的Tag即可席揽。比如我們希望我們的物體要在所有默認(rèn)的不透明物體渲染完之后渲染,那么我們就可以使用Tag{“Queue” = “Geometry+1”}就可以讓使用了這個(gè)shader的物體在這個(gè)隊(duì)列中進(jìn)行渲染谓厘。

還是上面的三個(gè)立方體幌羞,這次我們分別給三個(gè)不同的shader,并且渲染隊(duì)列不同竟稳,通過(guò)上面的實(shí)驗(yàn)我們知道属桦,默認(rèn)情況下,不透明物體都是在Geometry這個(gè)隊(duì)列中進(jìn)行渲染的他爸,那么不透明的三個(gè)物體就會(huì)按照cube1,cube2,cube3進(jìn)行渲染聂宾。這次我們希望將渲染的順序反過(guò)來(lái),那么我們就可以讓cube1的渲染隊(duì)列最大诊笤,cube3的渲染隊(duì)列最小系谐。貼出其中一個(gè)的shader:

Shader "Custom/RenderQueue1" {
 
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue" = "Geometry+1"}
    
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct v2f
            {
                float4 pos : SV_POSITION;
            };
 
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                return o;
            }
 
            fixed4 frag(v2f i) : SV_Target
            {
                return fixed4(0,0,1,1);
            }
            ENDCG
        }
    }
    //FallBack "Diffuse"
}

其他的兩個(gè)shader類似,只是渲染隊(duì)列和輸出顏色不同盏混。


通過(guò)渲染隊(duì)列蔚鸥,我們就可以自由地控制使用該shader的物體在什么時(shí)機(jī)渲染。比如某個(gè)不透明物體的像素階段操作較費(fèi)许赃,我們就可以控制它的渲染隊(duì)列止喷,讓其渲染更靠后,這樣可以通過(guò)其他不透明物體寫(xiě)入的深度剔除該物體所占的一些像素混聊。

PS:這里貌似發(fā)現(xiàn)了個(gè)問(wèn)題弹谁,我們?cè)谛薷膕hader的時(shí)候一般不需要什么其他操作就可以直接看到修改后的變化,但是本人改完渲染隊(duì)列后句喜,有時(shí)候會(huì)出現(xiàn)從shader的文件上能看到渲染隊(duì)列的變化预愤,但是從渲染結(jié)果以及Frame Debug工具中并沒(méi)有看到渲染結(jié)果的變化,重啟Unity也沒(méi)有起到作用咳胃,直到我把shader重新賦給材質(zhì)之后植康,變化才起了效果...(猜測(cè)是個(gè)bug,因?yàn)榭吹骄W(wǎng)上還有和我一樣的倒霉蛋被這個(gè)坑了展懈,本人的版本是5.3.2销睁,害我差點(diǎn)懷疑昨天是不是喝了,剛實(shí)驗(yàn)完的結(jié)果就完全不對(duì)了...)

**ZTest(深度測(cè)試)和ZWrite(深度寫(xiě)入) **

上一個(gè)例子中存崖,雖然渲染的順序反了過(guò)來(lái)冻记,但是物體之間的遮擋關(guān)系仍然是正確的,這就是z-buffer的功勞来惧,不論我們的渲染順序怎樣冗栗,遮擋關(guān)系仍然能夠保持正確。而我們對(duì)z-buffer的調(diào)用就是通過(guò)ZTest和ZWrite來(lái)實(shí)現(xiàn)的。

首先看一下ZTest隅居,ZTest即深度測(cè)試钠至,所謂測(cè)試,就是針對(duì)當(dāng)前對(duì)象在屏幕上(更準(zhǔn)確的說(shuō)是frame buffer)對(duì)應(yīng)的像素點(diǎn)胎源,將對(duì)象自身的深度值與當(dāng)前該像素點(diǎn)緩存的深度值進(jìn)行比較棕洋,如果通過(guò)了,本對(duì)象在該像素點(diǎn)才會(huì)將顏色寫(xiě)入顏色緩沖區(qū)乒融,否則否則不會(huì)寫(xiě)入顏色緩沖。ZTest提供的狀態(tài)較多摄悯。ZTest Less(深度小于當(dāng)前緩存則通過(guò)赞季, ZTest Greater(深度大于當(dāng)前緩存則通過(guò)),ZTest LEqual(深度小于等于當(dāng)前緩存則通過(guò))奢驯,ZTest GEqual(深度大于等于當(dāng)前緩存則通過(guò))申钩,ZTest Equal(深度等于當(dāng)前緩存則通過(guò)),ZTest NotEqual(深度不等于當(dāng)前緩存則通過(guò))瘪阁,ZTest Always(不論如何都通過(guò))撒遣。注意,ZTest Off等同于ZTest Always管跺,關(guān)閉深度測(cè)試等于完全通過(guò)义黎。

下面再看一下ZWrite,ZWrite比較簡(jiǎn)單豁跑,只有兩種狀態(tài)廉涕,ZWrite On(開(kāi)啟深度寫(xiě)入)和ZWrite Off(關(guān)閉深度寫(xiě)入)。當(dāng)我們開(kāi)啟深度寫(xiě)入的時(shí)候艇拍,物體被渲染時(shí)針對(duì)物體在屏幕(更準(zhǔn)確地說(shuō)是frame buffer)上每個(gè)像素的深度都寫(xiě)入到深度緩沖區(qū)狐蜕;反之,如果是ZWrite Off卸夕,那么物體的深度就不會(huì)寫(xiě)入深度緩沖區(qū)层释。但是,物體是否會(huì)寫(xiě)入深度快集,除了ZWrite這個(gè)狀態(tài)之外贡羔,更重要的是需要深度測(cè)試通過(guò),也就是ZTest通過(guò)碍讨,如果ZTest都沒(méi)通過(guò)治力,那么也就不會(huì)寫(xiě)入深度了。就好比默認(rèn)的渲染狀態(tài)是ZWrite On和ZTest LEqual勃黍,如果當(dāng)前深度測(cè)試失敗宵统,說(shuō)明這個(gè)像素對(duì)應(yīng)的位置,已經(jīng)有一個(gè)更靠前的東西占坑了,即使寫(xiě)入了马澈,也沒(méi)有原來(lái)的更靠前瓢省,那么也就沒(méi)有必要再去寫(xiě)入深度了。所以上面的ZTest分為通過(guò)和不通過(guò)兩種情況痊班,ZWrite分為開(kāi)啟和關(guān)閉兩種情況的話勤婚,一共就是四種情況:

1.深度測(cè)試通過(guò),深度寫(xiě)入開(kāi)啟:寫(xiě)入深度緩沖區(qū)涤伐,寫(xiě)入顏色緩沖區(qū)馒胆;
2.深度測(cè)試通過(guò),深度寫(xiě)入關(guān)閉:不寫(xiě)深度緩沖區(qū)凝果,寫(xiě)入顏色緩沖區(qū)祝迂;
3.深度測(cè)試失敗,深度寫(xiě)入開(kāi)啟:不寫(xiě)深度緩沖區(qū)器净,不寫(xiě)顏色緩沖區(qū)型雳;
4.深度測(cè)試失敗,深度寫(xiě)入關(guān)閉:不寫(xiě)深度緩沖區(qū)山害,不寫(xiě)顏色緩沖區(qū)纠俭;

Unity中默認(rèn)的狀態(tài)(寫(xiě)shader時(shí)什么都不寫(xiě)的狀態(tài))是ZTest LEqual和ZWrite On,也就是說(shuō)默認(rèn)是開(kāi)啟深度寫(xiě)入浪慌,并且深度小于等于當(dāng)前緩存中的深度就通過(guò)深度測(cè)試冤荆,深度緩存中原始為無(wú)限大,也就是說(shuō)離攝像機(jī)越近的物體會(huì)更新深度緩存并且遮擋住后面的物體权纤。如下圖所示匙赞,前面的正方體會(huì)遮擋住后面的物體:


寫(xiě)幾個(gè)簡(jiǎn)單的小例子來(lái)看一下ZTest,ZWrite以及Render Queue這幾個(gè)狀態(tài)對(duì)渲染結(jié)果的控制妖碉。

讓綠色的對(duì)象不被前面的立方體遮擋涌庭,一種方式是關(guān)閉前面的藍(lán)色立方體深度寫(xiě)入:


通過(guò)上面的實(shí)驗(yàn)結(jié)果,我們知道欧宜,按照從前到后的渲染順序坐榆,首先渲染藍(lán)色物體,藍(lán)色物體深度測(cè)試通過(guò)冗茸,顏色寫(xiě)入緩存席镀,但是關(guān)閉了深度寫(xiě)入,藍(lán)色部分的深度緩存值仍然是默認(rèn)的Max夏漱,后面渲染的綠色立方體豪诲,進(jìn)行深度測(cè)試仍然會(huì)成功,寫(xiě)入顏色緩存挂绰,并且寫(xiě)入了深度屎篱,因此藍(lán)色立方體沒(méi)有起到遮擋的作用。
另一種方式是讓綠色強(qiáng)制通過(guò)深度測(cè)試:


這個(gè)例子中其他立方體的shader使用默認(rèn)的渲染方式,綠色的將ZTest設(shè)置為Always交播,也就是說(shuō)不管怎樣重虑,深度測(cè)試都通過(guò),將綠色立方體的顏色寫(xiě)入緩存秦士,如果沒(méi)有其他覆蓋了缺厉,那么最終的輸出就是綠色的了。

那么如果紅色的也開(kāi)了ZTest Always會(huì)怎么樣隧土?


在紅色立方體也用了ZTest Always后提针,紅色遮擋了綠色的部分顯示為了紅色。如果我們換一下渲染隊(duì)列曹傀,讓綠色在紅色之前渲染关贵,結(jié)果就又不一樣了:


更換了渲染隊(duì)列,讓綠色的渲染隊(duì)列+1卖毁,在默認(rèn)隊(duì)列Geometry之后渲染,最終重疊部分又變回了綠色落萎『ダ玻可見(jiàn),當(dāng)ZTest都通過(guò)時(shí)练链,上一個(gè)寫(xiě)入顏色緩存的會(huì)覆蓋上一個(gè)翔脱,也就是說(shuō)最終輸出的是最后一個(gè)渲染的對(duì)象顏色。

再看一下Greater相關(guān)的部分有什么作用媒鼓,這次我們其他的都使用默認(rèn)的渲染狀態(tài)届吁,綠色的立方體shader中ZTest設(shè)置為Greater:


這個(gè)效果就比較好玩了,雖然我們發(fā)現(xiàn)在比較深度時(shí)绿鸣,前面被藍(lán)色立方體遮擋的部分疚沐,綠色的最終覆蓋了藍(lán)色,是想要的結(jié)果潮模,不過(guò)其他部分哪里去了呢亮蛔?簡(jiǎn)單分析一下,渲染順序是從前到后擎厢,也就是說(shuō)藍(lán)色最先渲染究流,默認(rèn)深度為Max,藍(lán)色立方體的深度滿足LEqual條件动遭,就寫(xiě)入了深度緩存芬探,然后綠色開(kāi)始渲染,重疊的部分的深度緩存是藍(lán)色立方體寫(xiě)入的厘惦,而綠色的深度值滿足大于藍(lán)色深度的條件偷仿,所以深度測(cè)試通過(guò),重疊部分顏色更新為綠色;而與紅色立方體重合的部分炎疆,紅色立方體最后渲染卡骂,與前面的部分進(jìn)行深度測(cè)試,小于前面的部分形入,深度測(cè)試失敗全跨,重疊部分不會(huì)更新為紅色,所以重疊部分最終為綠色亿遂。而綠色立方體沒(méi)有與其他部分重合的地方為什么消失了呢浓若?其實(shí)是因?yàn)榫G色立方體渲染時(shí),除了藍(lán)色立方體渲染的地方是有深度信息的蛇数,其他部分的深度信息都為Max挪钓,藍(lán)色部分用Greater進(jìn)行判斷,肯定會(huì)失敗耳舅,也就不會(huì)有顏色更新碌上。
有一個(gè)好玩的效果其實(shí)就可以考ZTest Greater來(lái)實(shí)現(xiàn),就是游戲里面經(jīng)常出現(xiàn)的浦徊,當(dāng)玩家被其他場(chǎng)景對(duì)象遮擋時(shí)馏予,遮擋的部分會(huì)呈現(xiàn)出X-光的效果;其實(shí)是在渲染玩家時(shí)盔性,增加了一個(gè)Pass霞丧,默認(rèn)的Pass正常渲染,而增加的一個(gè)Pass就使用Greater進(jìn)行深度測(cè)試冕香,這樣蛹尝,當(dāng)玩家被其他部分遮擋時(shí),遮擋的部分才會(huì)顯示出來(lái)悉尾,用一個(gè)描邊的效果渲染突那,其他部分仍然使用原來(lái)的Pass即可。

Early-Z技術(shù)

傳統(tǒng)的渲染管線中构眯,ZTest其實(shí)是在Blending階段陨收,這時(shí)候進(jìn)行深度測(cè)試,所有對(duì)象的像素著色器都會(huì)計(jì)算一遍鸵赖,沒(méi)有什么性能提升务漩,僅僅是為了得出正確的遮擋結(jié)果,會(huì)造成大量的無(wú)用計(jì)算它褪,因?yàn)槊總€(gè)像素點(diǎn)上肯定重疊了很多計(jì)算饵骨。因此現(xiàn)代GPU中運(yùn)用了Early-Z的技術(shù),在Vertex階段和Fragment階段之間(光柵化之后茫打,fragment之前)進(jìn)行一次深度測(cè)試居触,如果深度測(cè)試失敗妖混,就不必進(jìn)行fragment階段的計(jì)算了,因此在性能上會(huì)有很大的提升轮洋。但是最終的ZTest仍然需要進(jìn)行制市,以保證最終的遮擋關(guān)系結(jié)果正確。前面的一次主要是Z-Cull為了裁剪以達(dá)到優(yōu)化的目的弊予,后一次主要是Z-Check祥楣,為了檢查,如下圖:


Early-Z

Early-Z的實(shí)現(xiàn)汉柒,主要是通過(guò)一個(gè)Z-pre-pass實(shí)現(xiàn)误褪,簡(jiǎn)單來(lái)說(shuō),對(duì)于所有不透明的物體(透明的沒(méi)有用碾褂,本身不會(huì)寫(xiě)深度)兽间,首先用一個(gè)超級(jí)簡(jiǎn)單的shader進(jìn)行渲染,這個(gè)shader不寫(xiě)顏色緩沖區(qū)正塌,只寫(xiě)深度緩沖區(qū)嘀略,第二個(gè)pass關(guān)閉深度寫(xiě)入,開(kāi)啟深度測(cè)試乓诽,用正常的shader進(jìn)行渲染帜羊。其實(shí)這種技術(shù),我們也可以借鑒问裕,在渲染透明物體時(shí),因?yàn)殛P(guān)閉了深度寫(xiě)入孵坚,有時(shí)候會(huì)有其他不透明的部分遮擋住透明的部分粮宛,而我們其實(shí)不希望他們被遮擋,僅僅希望被遮擋的物體半透卖宠,這時(shí)我們就可以用兩個(gè)pass來(lái)渲染巍杈,第一個(gè)pass使用Color Mask屏蔽顏色寫(xiě)入,僅寫(xiě)入深度扛伍,第二個(gè)pass正常渲染半透筷畦,關(guān)閉深度寫(xiě)入。

關(guān)于Early-Z技術(shù)可以參考ATI的論文Applications of Explicit Early-Z Culling以及PPT刺洒,還有一篇Intel的文章鳖宾。

Unity渲染順序總結(jié)

如果我們先繪制后面的物體,再繪制前面的物體逆航,就會(huì)造成over draw鼎文;而通過(guò)Early-Z技術(shù),我們就可以先繪制較近的物體因俐,再繪制較遠(yuǎn)的物體(僅限不透明物體)拇惋,這樣周偎,通過(guò)先渲染前面的物體,讓前面的物體先占坑撑帖,就可以讓后面的物體深度測(cè)試失敗蓉坎,進(jìn)而減少重復(fù)的fragment計(jì)算,達(dá)到優(yōu)化的目的胡嘿。Unity中默認(rèn)應(yīng)該就是按照最近距離的面進(jìn)行繪制的蛉艾,我們可以看一下Unity官方的文檔中顯示的:


從文檔給出的流程來(lái)看,這個(gè)Depth-Test發(fā)生在Vertex階段和Fragment階段之間灶平,也就是上面所說(shuō)的Early-Z優(yōu)化伺通。
簡(jiǎn)單總結(jié)一下Unity中的渲染順序:先渲染不透明物體,順序是從前到后逢享;再渲染透明物體罐监,順序是從后到前

Alpha Test(Discard)在移動(dòng)平臺(tái)消耗較大的原因

從本人剛剛開(kāi)始接觸渲染瞒爬,就開(kāi)始聽(tīng)說(shuō)移動(dòng)平臺(tái)Alpha Test比較費(fèi)弓柱,當(dāng)時(shí)比較納悶,直接discard了為什么會(huì)費(fèi)呢侧但,應(yīng)該更省才對(duì)笆缚铡?這個(gè)問(wèn)題困擾了我好久禀横,今天來(lái)刨根問(wèn)底一下屁药。還是跟我們上面講到的Early-Z優(yōu)化。正常情況下柏锄,比如我們渲染一個(gè)面片酿箭,不管是否是開(kāi)啟深度寫(xiě)入或者深度測(cè)試,這個(gè)面片的光柵化之后對(duì)應(yīng)的像素的深度值都可以在Early-Z(Z-Cull)的階段判斷出來(lái)了趾娃;而如果開(kāi)啟了Alpha Test(Discard)的時(shí)候缭嫡,discard這個(gè)操作是在fragment階段進(jìn)行的,也就是說(shuō)這個(gè)面片光柵化之后對(duì)應(yīng)的像素是否可見(jiàn)抬闷,是在fragment階段之后才知道的妇蛀,最終需要靠Z-Check進(jìn)行判斷這個(gè)像素點(diǎn)最終的顏色。其實(shí)想象一下也能夠知道笤成,如果我們開(kāi)了Alpha Test并且還用Early-Z的話评架,一塊本來(lái)應(yīng)該被剃掉的地方,就仍然寫(xiě)進(jìn)了深度緩存炕泳,這樣就會(huì)造成其他部分被一個(gè)完全沒(méi)東西的地方遮擋古程,最終的渲染效果肯定就不對(duì)了。所以喊崖,如果我們開(kāi)啟了Alpha Test挣磨,就不會(huì)進(jìn)行Early-Z雇逞,Z Test推遲到fragment之后進(jìn)行,那么這個(gè)物體對(duì)應(yīng)的shader就會(huì)完全執(zhí)行vertex shader和fragment shader茁裙,造成over draw塘砸。有一種方式是使用Alpha Blend代替Alpha Test,雖然也很費(fèi)晤锥,但是至少Alpha Blend雖然不寫(xiě)深度掉蔬,但是深度測(cè)試是可以提前進(jìn)行的,因?yàn)椴粫?huì)在fragment階段再?zèng)Q定是否可見(jiàn)矾瘾,因?yàn)槎际强梢?jiàn)的女轿,只是透明度比較低罷了。不過(guò)這樣只是權(quán)宜之計(jì)壕翩,Alpha Blend并不能完全代替Alpha Test蛉迹。

關(guān)于Alpha Test對(duì)于Power VR架構(gòu)的GPU性能的影響,簡(jiǎn)單引用一下官方的鏈接以及一篇討論帖:


PowerVR alpha test/discard pipeline

最后再附上兩篇參考文章

http://blog.csdn.net/candycat1992/article/details/41599167
http://blog.csdn.net/arundev/article/details/7895839

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末放妈,一起剝皮案震驚了整個(gè)濱河市北救,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芜抒,老刑警劉巖珍策,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宅倒,居然都是意外死亡攘宙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)拐迁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蹭劈,“玉大人,你說(shuō)我怎么就攤上這事唠亚×捶剑” “怎么了持痰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵灶搜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我工窍,道長(zhǎng)割卖,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任患雏,我火速辦了婚禮鹏溯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘淹仑。我一直安慰自己丙挽,他們只是感情好肺孵,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著颜阐,像睡著了一般平窘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凳怨,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天瑰艘,我揣著相機(jī)與錄音,去河邊找鬼肤舞。 笑死紫新,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的李剖。 我是一名探鬼主播芒率,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼杖爽!你這毒婦竟也來(lái)了敲董?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤慰安,失蹤者是張志新(化名)和其女友劉穎腋寨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體化焕,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萄窜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撒桨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片查刻。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凤类,靈堂內(nèi)的尸體忽然破棺而出穗泵,到底是詐尸還是另有隱情,我是刑警寧澤谜疤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布佃延,位于F島的核電站,受9級(jí)特大地震影響夷磕,放射性物質(zhì)發(fā)生泄漏履肃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一坐桩、第九天 我趴在偏房一處隱蔽的房頂上張望尺棋。 院中可真熱鬧,春花似錦绵跷、人聲如沸膘螟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荆残。三九已至闷叉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脊阴,已是汗流浹背握侧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘿期,地道東北人品擎。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像备徐,于是被迫代替她去往敵國(guó)和親萄传。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359