讀書筆記2
視差貼圖(parallax mapping)
視差貼圖為每個像素指定了高度或深度(意味著高于平面或低于平面)信息。在對某一像素進行貼圖采樣時,根據(jù)視差貼圖的位置信息和視點方向?qū)v坐標進行偏移,再采樣diffuse、normal等貼圖,從而像素顏色會根據(jù)視點的不同而變化,就好像具有真實的凹凸一般。

總結(jié)一句:視差貼圖最重要的就是計算觀察向量和曲線的交點。
視差貼圖為深度圖時,平面為0, 最低為1。視差貼圖為高度圖時,平面為0,最高為1。
視差貼圖的計算必須要在切線空間中,主要因為切線空間的切線與副切線通常與uv坐標軸分別對齊,因此觀察方向在切線空間中的xy分量代表了uv偏移的方向。
以深度圖為例的視差貼圖近似計算:
使用深度圖的時候,為減去p。
使用高度圖的時候,為加上p。
p有兩種計算方法,第一種為無偏移量限制的視差貼圖(Parallax Mapping),第二種為有偏移量限制的視差貼圖(Parallax Mapping with Offset Limiting)。
先談談第二種,當視角與平面近乎平行時,xy分量的最大值也才接近1,因此像素偏移是受限的。雖然能給出較好的效果,但并不是物理正確的。第一種則通過除上z分量來保證當視角越向平面靠近時,觀察向量就“看”得越遠,即代表了從平面到最低或最高的投影值。通過相似三角形可以得出:深度 / uv坐標偏移 = z分量 / xy分量,解得:uv坐標偏移 = xy分量 / z分量 * 深度。特別地,當深度為1時uv坐標偏移量為總偏移量。不難看出,視角近乎與平面平行時會因uv坐標偏移過大而出現(xiàn)走樣現(xiàn)象,第二種方法則可避免這個問題。
陡峭視差映射(Steep Parallax Mapping)

算法思路:
將深度分層,圖中分為8層。計算出每層uv偏移量,即viewDir.xy / viewDir.z * numLayers * depthScale。從平面開始,逐層向下通過偏移uv坐標,檢查視差貼圖中采樣的深度是否大于層深度。圖中可見,當uv偏移至T3時停止,那么T0的uv坐標為T3uv坐標值。
代碼:
浮雕視差貼圖:
就是在陡峭視差貼圖之后,得到最后兩層的uv偏移,那么觀察向量與深度曲線的交點必定位于兩層之間,那么可以采用二分法進行進一步近似,查找指定次數(shù)或達到指定誤差內(nèi)結(jié)束。
代碼:
視差遮蔽映射(Parallax Occlusion Mapping)
在陡峭視差映射的最后兩層之間進行線性插值。
代碼:
其中pre * w + cur * (1 - w)可由pre + (cur - pre) * (1 - w)化簡得到。
附:有一個較容易混淆的點,就是面的切線空間和點的切線空間。在法線貼圖的計算中,使用的是點的切線空間,N為點的平均法線,T為點的平均切線(注意還要施密特正交化)。而這里是在片元著色器中使用的切線空間,為面的切線空間,因此N為面的法線,T與u軸方向相同,B與v軸方向相同。
參考:
https://github.com/UPBGE/upbge/issues/1009
https://zhuanlan.zhihu.com/p/128682162
https://zhuanlan.zhihu.com/p/265317045