程式碼一樣可以在
個人網站上查看,歡迎光臨寒舍
備註:這篇主要談基本概念,部分內容來自於當初讀《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有點失敗,下回會解釋
參考