遊戲引擎研究 單位向量與八面體的轉換演算法

2021-07-27 23:50:47 字數 2246 閱讀 4278

這篇部落格介紹了在延遲渲染(deferred rendering)中比較常用的一種用於優化單位向量在g-buffer中儲存的演算法,該演算法在quake2、虛幻ⅳ引擎中被運用。

讀者可以在虛幻引擎ⅳ的deferredshadingcommon.usf中接觸到相應的**,也可以閱讀相關**,傳送門。

在計算機圖形學中單位向量的使用極為普遍,例如表面的法線向量、切線向量和光線相關的向量等。這樣一來,很多的圖形學的演算法的時間&空間效能都取決於針對這些向量的讀取、處理和寫入的速度。

特別的是傳輸這些資料的頻寬需求與g-buffer對於記憶體的需求在很多地方制約了gpu渲染的速度。

在現在的圖形渲染管線中,3d的向量要麼存在高頻寬的暫存器(registers)中,要麼存在中等頻寬的計算機記憶體中,要麼存在低頻寬的磁碟中。針對於單位向量,暫存器由於對速度有著極高的要求,往往希望你能夠將其以float32*3的形式進行單位向量的儲存,而磁碟往往更希望更有效地利用儲存空間,因此會鼓勵你進行各種的編碼/解碼操作。

但是針對於在記憶體(或者晶元上的cache)中的儲存,往往需要在速度和儲存空間上取得乙個平衡。因此可以考慮將單位向量進行某種程度的編碼和解碼,當然這種編碼和解碼也不能太複雜或者損失太多資訊。

這個演算法的目的是如何編碼乙個單位向量的同時,能夠讓其占用最少的位數以及讓資訊損失量達到乙個可接受的程度;或者說如何在乙個固定的頻寬限制下,盡量最小化損失的資訊。

先看看單位向量的最普通的表現方法:乙個包含三個32-bit的浮點數的結構體:

struct
那麼它所占用的儲存空間為:3∗

4∗8=

96 bits。

可知的是,這種表現方法的域實際上是整個3d空間,r3

,換句話說就是從原點到無窮遠處(也不盡然……32位浮點數也有範圍)的空間。

但是正常的單位向量的域卻是位於原點,半徑為1的球面。

這就意味著這96-bit位的模版中有絕大部分的例項針對於表現單位向量是不起任何作用的。換句話說,資源浪費了不少

就儲存空間來說,完美的模版則應該是每一種例項都能夠表現這個球面上的唯一的乙個點。

有一種容易想到的演算法是使用球面座標,也就是儲存兩個32-bit的浮點數用於儲存該向量在三維座標系中的角度。這樣一來只需要花費64個位就能夠進行儲存了,而且精度相對來講也更加高。但是這要求進行一系列的三角函式運算,在計算過程中會帶來更多的誤差,也會導致導致更多的計算量。

此外,這樣的做法會導致在兩極的點較為密集、而在赤道上的點較為稀疏,這樣的偏差在很多地方也會出現問題。

真正完美的方法應該是兼顧效率、誤差、編碼、解碼和保證其均勻分布各個方面。

有一種可行的演算法是將整個球面上的點先投影至乙個八面體中,然後再投影到z=

0 的平面上。

但是針對於那些

z<

0 的點,則將其針對於八面體裡z=

0 的那些邊進行對折,從而將圓的點對映到乙個平面上,該平面為長寬為2的正方形,過程圖如下:

這樣一來,我們只需要儲存對應的(u

,v) 座標即可。

我們認為這種方法相對來講是最好的:編碼解碼的計算過程簡單,而且基本上也是平均的分布。

針對於這種向量進行編碼的方式叫做「octahedral normal vectors (onv),」這種方法相對來講高效且優雅,並且誤差也較小。

上面提到計算過程簡單的原因其實一開始我也沒想明白,而且也計算了好一會。但是後來發現在真正的實現中也並沒有按照完全的幾何結果來計算,而是粗暴的將l2

(歐幾里德範數)代替為l1

(曼哈頓範數),從而得到乙個近似的解。

按照上面的方法來實現的話,那麼對應的編碼和解碼如下:

float2 unitvectortooctahedron( float3 n )

return n.xy;

}float3 octahedrontounitvector( float2 oct )

return normalize(n);

}

實際上也有更加精確的實現方法,然而可能相對來講計算量要更大一些。glsl**如下:

vec2 float32x3_to_octn_precise(vec3 v, const in int n) 

}return bestrepresentation;

}

《全文完》

忙著研究Torque 3D遊戲引擎

快有大半年了沒來過了.應該是說最近也比較忙吧,由於公司最近要開發3d遊戲,而應用的就是torque遊戲引擎.公司裡上下都沒有人真正應用過這引擎,所以都要摸著石頭過河了,找資料看書.雖然公司購買這引擎會有一些應用與介紹,但也還是太過簡單,不全面.難處是全部是英語,也只有啃英語了.在網上找torque引...

單位張量叉乘 附錄向量與張量運算

附錄 向量與張量運算 標量 向量與張量 1.1基本概念 在本書中所涉及的物理量可分為標量 向量和張量。我們非常熟悉標量,它是在空間沒有取向的物理量,只有乙個數就可以表示其狀態。例如質量 壓強 密度 溫度等都是 標量。向量則是在空間有一定取向的物理量,它既有大小 又有方向。在三維空間中,需要三個數來表...

3D遊戲引擎數學基礎3 向量(下篇)

向量數乘 標量可以與向量相乘,可以直觀聯想到,該運算可以對向量進行縮放。該運算不改變向量的方向,除非標量是負數,這樣向量的方向與原來的方向相反。k u k ux,k uy,k uz 在unity引擎中有對物體進行縮放的功能,其提供在三個座標軸上的縮放,其底層的運算估計就是向量數乘。於是,有需要過載一...