UnityShader-透明效果
在Unity中我們通常用兩種方式來(lái)實(shí)現(xiàn)透明效果,第一種為Alpha Test(透明度測(cè)試),第二種為Alpha Blending(透明度混合)。在介紹這兩種方式之前我們需要簡(jiǎn)單了解一下渲染的順序
深度緩沖(深度測(cè)試與深度寫(xiě)入)
當(dāng)場(chǎng)景中存在很多模型時(shí),我們并不需要考慮先渲染A或者B或者C,渲染的順序并不會(huì)影響最終的渲染結(jié)果,正是因?yàn)樯疃染彌_的作用,它的基本思想是根據(jù)深度緩存中的值來(lái)判斷該片元距離攝像機(jī)的距離,當(dāng)渲染一個(gè)片元時(shí),需要把他的深度值和已經(jīng)存于深度緩沖中的值進(jìn)行比較(開(kāi)啟了深度測(cè)試的前提),如果它的值距離攝像機(jī)更遠(yuǎn),則說(shuō)明有物體擋住了它不需要渲染到屏幕上,否則就覆蓋此時(shí)顏色緩沖當(dāng)中的像素值,并且更新到深度緩沖中(深度寫(xiě)入)但是如果要實(shí)現(xiàn)透明效果,尤其是透明度混合時(shí),將會(huì)關(guān)閉深度寫(xiě)入。
????透明度測(cè)試
????????當(dāng)一個(gè)片元的透明度不滿足條件時(shí)(例如小于某個(gè)閾值),則舍棄這個(gè)片元,這種方法產(chǎn)生的效果非常極端,要么完全透明,要么完全不透明。
????透明度混合
????????可以得到真正的半透明效果,使用當(dāng)前片元的透明度作為混合因子,和已經(jīng)存在顏色緩沖中的顏色值進(jìn)行混合得到新的顏色。但是透明度混合需要關(guān)閉深度寫(xiě)入,如果不關(guān)閉深度寫(xiě)入,則會(huì)出現(xiàn)當(dāng)半透明物體擋在不透明物體前時(shí),由于沒(méi)有關(guān)閉深度寫(xiě)入而將半透明物體的深度值寫(xiě)入,不透明物體深度測(cè)試時(shí),會(huì)認(rèn)為自己不需要被渲染,那么就會(huì)出現(xiàn)半透明物體完全擋住了不透明物體的奇怪現(xiàn)象。在這種情況下,渲染的順序就十分重要了。
渲染引擎一般都會(huì)對(duì)物體進(jìn)行排序之后再渲染,常用的方法是:
先渲染所有的不透明物體,并開(kāi)啟它們的深度測(cè)試和深度寫(xiě)入。
把半透明物體按他們的距離攝像機(jī)的遠(yuǎn)近排序,按照從后往前的順序渲染這些半透明物體,并且開(kāi)啟深度測(cè)試,關(guān)閉深度寫(xiě)入。
同樣的半通明物體從前往后的順序也存在一定問(wèn)題,通常情況下,我們默認(rèn)物體A全部都在B前面或者全部都在B后面,但是不可避免的會(huì)出現(xiàn)物體AB交錯(cuò)的情況,部分在前,部分在后,這個(gè)時(shí)候我們可以選擇把物體拆分為兩個(gè)部分在進(jìn)行正確的排序。

透明度測(cè)試
大致部分與之前漫發(fā)射紋理差不多,其中Cutoff系數(shù)作為控制透明度的閾值,紋理上小于Cufoff的片元將被直接舍棄,使用的Cilp方法。

透明度混合
當(dāng)然,由于上述的關(guān)閉深度寫(xiě)入帶來(lái)的各種問(wèn)題,當(dāng)模型本身具有復(fù)雜的遮擋關(guān)系就會(huì)因?yàn)楦鞣N排序錯(cuò)誤而產(chǎn)生錯(cuò)誤的透明效果。如圖

接下來(lái)我們將會(huì)實(shí)現(xiàn)開(kāi)啟深度寫(xiě)入的半透明效果,其中一種解決辦法為,使用兩個(gè)Pass來(lái)渲染模型,第一個(gè)Pass開(kāi)啟深度寫(xiě)入,但不輸出顏色,第二個(gè)Pass進(jìn)行正常的透明度混合。缺點(diǎn)為多一個(gè)Pass會(huì)對(duì)性能造成一定的影響。

雙面渲染的透明效果

如果一個(gè)物體是透明的,意味著我們不僅可以透過(guò)他看到其他物體,當(dāng)然也可以看到這個(gè)物體的內(nèi)部結(jié)構(gòu),在之前的實(shí)現(xiàn)的透明效果中,我們都無(wú)法觀察到正方體的內(nèi)部結(jié)構(gòu),導(dǎo)致物體看起來(lái)好像只有半個(gè),原因是因?yàn)殇秩疽婺J(rèn)剔除了物體背面的渲染圖元,如果我們想要得到雙面的渲染效果,可以使用Cull指令來(lái)控制剔除那個(gè)面的渲染圖元
Cull Back|Front|Off? ?分別表示剔除背面,剔除正面,全部渲染
例如在之前透明度測(cè)試的代碼中,我們可以在Pass中加入Cull Off就能得到雙面渲染的結(jié)果

然而透明度混合中實(shí)現(xiàn)雙面渲染會(huì)跟更復(fù)雜一些,還是因?yàn)槲覀冴P(guān)閉了深度寫(xiě)入,我們希望渲染順序是從后往前渲染,關(guān)閉深度寫(xiě)入導(dǎo)致無(wú)法通過(guò)按逐像素的力度進(jìn)行深度排序,因此為了保證同一物體的背面圖元先渲染,我們將雙面渲染的Pass分為兩個(gè),第一個(gè)只渲染背面,第二個(gè)只渲染正面,因?yàn)殇秩緯r(shí)會(huì)依次執(zhí)行Subshader中的Pass,就保證了背面總是在正面之前被渲染。代碼如下

本節(jié)學(xué)習(xí)成果
