UE Source Code Note 1
UE Shader層的單位向量壓縮與解壓
先貼源碼:
在論文《Survey of Efficient Representations for Independent Unit Vectors》中,提出一種將三維單位向量壓縮成二維向量的方法。方法是先將單位向量從球體(Sphere)映射至八面體(Octahedron),再投影到一個(gè)平面正方形(Square)上。

如第四張圖所示。
為什么不使用平方和為1的方法進(jìn)行壓縮而要如此大費(fèi)周章呢?
首先在公式中可以看到存在兩個(gè)平方與一個(gè)開(kāi)方的昂貴開(kāi)銷,會(huì)大大影響GPU流水線并行速度。其次,平方與開(kāi)方操作帶來(lái)的精度問(wèn)題不容小覷。因此,這種十分影響渲染質(zhì)量的壓縮是得不償失的。
接下來(lái)談?wù)剈e中的壓縮與解壓方法。
由圖中可得,球上點(diǎn)p的目標(biāo)是要映射至平面p''點(diǎn)。假設(shè)p點(diǎn)坐標(biāo)為,由球心向p點(diǎn)連線,與球內(nèi)正接八面體交于點(diǎn)p'。設(shè)p'坐標(biāo)為
,向量
與向量
之比為S,那么得到:
,又因?yàn)閜‘在正八面體上,所以
,代入之前的式子得出:
,因此:
從p'點(diǎn)到p''點(diǎn),舍棄z分量,簡(jiǎn)單投影到xy平面,即p''=p'。
這樣,就得到了單位向量從三維降維至二維的方法。
對(duì)應(yīng)至源碼中就是
這一行。
上面討論的是上半球面的情況,這樣只得到了一個(gè)2134構(gòu)成的菱形。如果是下半球面的話,為了防止投影時(shí)出現(xiàn)重復(fù),需要將其xy進(jìn)行重映射操作。
比如7號(hào)平面在投影時(shí)如果向內(nèi)折疊會(huì)與3號(hào)重復(fù),那么就將其投影平面向外折疊,可以簡(jiǎn)單看作是3號(hào)的對(duì)角線鏡像。
那么通過(guò)對(duì)稱關(guān)系與簡(jiǎn)單的幾何計(jì)算,不難得出,當(dāng)z小于0時(shí),
解壓就是壓縮的逆運(yùn)算。
此方法除了用于單位向量的壓縮外,還用于八面體映射(Octahedral map)的技術(shù)之中。
如侵刪。
歡迎評(píng)論指正。
參考來(lái)源:
https://zhuanlan.zhihu.com/p/594429859
https://www.cnblogs.com/timlly/p/13877623.html