前往
大廳
主題 達人專欄

(Unity + Shader)切線空間、菲涅耳係數 製作動態環境與鏡面反射的水(上篇)

%%鼠 拒收病婿 | 2022-07-25 04:15:12 | 巴幣 2388 | 人氣 1144

前言:
偷偷打廣告,最近在跟大佬朋友一起做遊戲中,最近角色圖也出來了(連結),喜歡的話可以偷偷關注一下進度吧 (´▽`ʃ♡ƪ)。
最終實裝效果如下:

程式碼一樣可以在個人網站上查看,歡迎光臨寒舍

備註:這篇主要談基本概念,部分內容來自於當初讀《Unity Shader入門精要》的學習筆記。


反射

說到反射,最簡單的方式是使用固定的CubeMap環境貼圖,依照視角位置做採樣。
單純取樣CubeMap的作法:

跟2D取樣不同的是,2D使用TRANSFORM_TEX去計算offset和tilling後的uv位置,而CubeMap取樣的是標準化後的vertex位置。
為了取物體表面對應的環境反射,需要計算相對的反射向量:


結合cubemap與貼圖,並透過自定義的_ReflectAmount變數控制結合量。


水波

概念:利用高度貼圖讓平面產生起伏,並透過菲涅耳係數控制遠近水面的反射率。
菲涅耳係數
光照射到表面時,一部分進行反射,一部分進入物體發生折射或散射。 被反射的光與入射光之間存在一定比率關係,此比率可藉由菲涅耳等式進行計算。例如:離你近的海水能看到水中的小魚,較遠的海面只看的到水的表面。
用於計算:

Tangent Space

我們常使用Bump Map、Normal map去添加細節。 「切線貼圖」可能在初學的路上較少被聽到,但比起normal map,切線貼圖更適合做UV動畫。
Normal map分為切線空間與物件空間。 「切線空間」可能在初學的路上較少被聽到,可以理解成我們在每個vertex上創造出一個local坐標系,紀錄的是相對的位移。 (感FunS  勘誤)

法線貼圖

範圍:[-1,1];像素分量範圍:[0,1],對映

切線貼圖

常用切線空間儲存法線。每個頂點都有自己的切線空間,原點為該頂點。
    • Z軸 = 頂點的法線方向。
    • X軸= 頂點切線方向
    • Y軸= 法線和切線的叉積,稱為副切線。
法線貼圖為藍色是因為頂點法線若沒更動,其Z軸保持原(0,0,1)方向(face-up),對應至像素空間則為(0.5,0.5,1)淺藍色。
法線貼圖 物件空間-優點:
  • 在轉折處可透過插值獲得較圓滑的轉變。
  • 方便轉換
切線空間-優點:
  • 紀錄相對的法線資訊,換貼圖也可繼續使用。
  • 可做UV動畫,例如移動紋理UV座標實現凹凸移動的動畫。
  • 可壓縮,因Z方向總是正的,可只記錄XY座標,來推算出Z。
模型空間⇒切線空間的轉換矩陣 = 切線空間⇒模型空間的轉換矩陣的 轉置矩陣

Tangent Space Normal Mapping

參考:
我們可以透過Tangent Space Normal Mapping將一般的法線貼圖轉成切線貼圖,使其享受切線貼圖帶來的優點。

實做

變數設定


在頂點著色器中加入切線方向的巨集

巨集TANGENT_SPACE_ROTATION的內容如下:

片段著色
利用bump map建立切線空間。
dot(tangentNormal.xy , tangentNormal.xy) 會得到tangentNormal.xy向量的長度的平方。[2]
我認為 tangentNormal.z是依照xy求出相互正交的第三軸,進而形成一個local的坐標系。 也因為切線空間是local的,其z軸一定是相對向上延伸的向量,差別在於其長度而已。[1][3]

成果跟使用法線貼圖很像:
實戰:
為了計算水波交叉的疊影,需取得切線座標。
TANGENT會提供垂直於normal的單位向量(The tangent is a unit vector perpendicular to the normal)。[4]
就像上述bump map練習,我們可以從切線分離出切線、副切線、法線,形成一個3*3的matrix:

分離切線
依照normal mapping的公式[1]組成一個矩陣。

片段著色

* _RefractionTex可以來自Grabpass或RenderTexture。




東西好像有點太多了,Reflection Probe和Planar Reflection下次再講吧XD
早期這張圖的Planar Reflection有點失敗,下回會解釋


參考
  1. LearnOpenGL - Normal Mapping
  2. https://www.quora.com/What-will-we-get-if-we-dot-product-a-vector-with-itself
  3. 笛卡兒座標系 - 維基百科,自由的百科全書 (wikipedia.org)
  4. shaders - What is a surface tangent? - Blender Stack Exchange

送禮物贊助創作者 !
0
留言

創作回應

FunS
內文法線那邊跟我理解有點出入 想討論一下XD
法線應該是比較廣義的稱呼
不分為法線空間/切線空間
應該是法線貼圖下分為物件空間/切線空間
2022-07-25 11:10:49
%%鼠 拒收病婿
感謝勘誤! 確實法線只是一個vector的名稱!

normal map若使用的是物件空間,像素rgb會是 normal vector的x,y,z,但這會讓貼圖只能被固定的模型使用;若使用的是切線空間(此篇利用法線向量創造出來的另一個坐標系),則是每個點自己表面的local空間,即每個點的相對位移。

學到了,謝謝[e16]

https://docs.cryengine.com/display/SDKDOC4/Tangent+Space+Normal+Mapping

補個:物件空間vs切線空間
https://docs.cryengine.com/download/attachments/1605679/OSTS2.jpg?version=1&modificationDate=1251809736000&api=v2
2022-07-25 12:36:30
冰鳩
我酷耶,不過我只會一點3DMAX qwq
2022-07-31 19:24:13
%%鼠 拒收病婿
窩的基礎也差不多,只能靠程式彌補[e23]
2022-08-01 02:16:12
追蹤 創作集

作者相關創作

更多創作