[Shader筆記]透明物體(Z-Test、Z-Write、Z-Buffer、Alpha Blending)

“ shader development using Unity” + Unity shader 入門精要筆記

詹閔翔
Eric’s publication
7 min readAug 8, 2019

--

漸層效果

目錄:

  1. 專有名詞介紹
  2. 專有名詞彼此之間的關西
  3. 透明Shader實作
  4. 漸變色實作shader

本次學習重點:

  1. 知道渲染透明物體的原理
  2. 知道電腦裡面要怎麼渲染透明物體
  3. 搞懂每個專有名詞
    1)Z-Test(深度測試)
    2)Z-Write(深度寫入)
    3)Z-Buffer(深度緩衝)
    4)Alpha Blending(透明度混合)
    5)RenderQueue(渲染序列)
  4. 知道如何修改現成Shader (改成透明材質)

RenderQueue(渲染序列)

渲染序列的運作原則就是比大小,數字越大的會越晚被渲染而視覺上最直接影響到的就是誰在前面誰在後面。

而寫法也非常簡單

Background 1000
Geometry 2000
AlphaTest 2450
Transparent 3000
Overlay 4000

但我們馬上就會遇到第一個問題,在3D渲染的世界裡我們不能完全依靠這種權重的方式來決定每個物件的渲染,試著想想看假如今天指示靜態的鏡頭以權重的方式來處理當然沒有問題,但當你稍微旋轉一點情況就完全不同了,等於我們每一幀都要重新處理一次權重,而且如果場景裡面有成千上萬的物體,那是不是也代表我們也需要成千上萬的權重!?

所以事實上電腦會更依靠“深度”來決定一個物件的渲染順序,也就是我們待會要提到的ZWrite、ZTest。

Z-Write(深度寫入):

是一個可選擇的動作(預設是ZWrite on),會根據條件決定是否執行

ZWrite 是否執行有兩個條件
1. Zwrite是否有打開
2. ZTest是否有通過(預設是LEqual即小於等於)

當ZWrite被執行時(ZTest也通過),物體渲染會把每個畫素的深度都寫入到深度緩衝區

Shader中的寫法:
ZWrite On(開啟深度寫入)
ZWrite Off(關閉深度寫入)

Z-Buffer(深度緩衝):

深度緩衝區保存:“深度值”
物體在世界空間中距離攝像機的遠近。
距離越近,深度值越小;距離越遠,深度值越大。

深度緩衝的使用可以解決不透明物體的渲染順序,即使渲染順序不同也不會決定視覺上誰在前誰在後

不過如果當場景中不只限於不透明物體時,就不能使用深度緩衝,而應該使用Alpha Blending(透明度混合)

Z-Test(深度測試):

每次都會測試Shader附著物體對應的片元,比對物件的深度值與深度緩衝目前的值進行比較(以下列出比較種類),如果通過則該物件那點像素才會將顏色寫入顏色緩衝區(Color buffer)。

!!!注意,ZTest Off等同於ZTest Always,關閉深度測試等於完全通過。

Alpha Blending(透明度混合):

透明度混合使用當前片元的透明度作為混合因子,與已經存儲在顏色緩衝中的顏色進行混合,得到新的顏色,不過透明度混合必須要關閉深度寫入(Zwrite)

需要特別注意的是,透明度混合只會關閉深度寫入不會關閉深度測試(ZTest),這意味著當透明度混合渲染一個片元時,還是會比較他的深度與深度緩存中的深度值,如果深度值距離相機更遠就不會進行混合操作。

這邊點出了一個很重要的觀念:當一個不透明物體出現在透明物體的前面,而我們先渲染了不透明物體,他仍然可以正常的擋住透明物體,深度緩衝對透明度混合來說只是讀取用的資料

Blending 算法:

Merged Pixel=[srcColor * src Factor] + [dstColor * dstFactor]

Source(Src):要處理的透明或半透片元
Destination(Dst):顏色緩衝器(Color buffer)裡面的數據

Shader寫法:

結構:Blend (blend factor) + (blend operator) + (blend factor)

blend operator

blend factor

漸層透明效果

漸層效果

Step1 新增一個Unlit shader

Step2 新增Transparent Queue

Step3 打開深度測試、Alpha Blending

pass 裡面新增

1. ZWrite off : 由於是半透明效果所以關閉深度寫入
2. Blend SrcAlpha + OneMinusSrcAlpha : 進行透明度混合

Step4 添加邏輯

由於我們希望顏色隨著x軸遞增,所以修改輸出的Alpha值等於x
col.a = i.uv.x;

如果看不到程式碼可以換到Chrome瀏覽器 :https://gist.github.com/doremi31618/16ea4bdb3ce2c0b4df0ad95f040e1eee

參考資料:

--

--

詹閔翔
Eric’s publication

現職專案管理與RD部門經理。畢業於國立台北科技大學 互動設計系。專注於各種可能的技術解決方案,喜歡從技術的角度解決問題,也喜歡接觸各種新科技跟open source專案與時代一起進化,並樂於將所見所聞製作成人人都能輕鬆理解的教學文章分享於網路平台。目前主力為軟體架構工程與系統開發