3D模型體素化(Voxelization)過程實現與分析
體素化方法
體素化能夠對模型進行簡化,得到均勻的網格,在求模型的測地線,求交等過程中有較好的應用。個人理解,把體素化分為基於CPU的方法和基於GPU渲染的方法。輸入是三角面片,輸出體素化格子。
基於CPU的體素化方法
體素化無非是對模型所在空間進行劃分成網格,並決定網格是否有被模型覆蓋。CPU的方法即不需要通過模型渲染,直接對網格進行統計得到是否佔有該格子。
體素化的第一步首先是計算模型的包圍盒,然後決定劃分的網格數量,劃分出xyz
三個方向的網格。
三角面片距離方法
建立網格後,我們確定每一個網格是否被佔用採取的是遍歷所有的三角形,計算三角形到體素化網格中間的距離,設定閾值進行判斷是否覆蓋該格子。計算空間點與三角形的方法如下:
1. 首先計算該點在三角面片所在平面的垂足點p1
2. 垂足點在三角面片內:則最短距離是空間點到垂足點距離
d1
3. 垂足點不在三角面片內:則求垂足點到三角面片的最短距離
s1
,最短距離是s1
和d1
構成的直角三角形的斜邊。
茶壺模型
兩個長方體
三角面片插值點
前者需要對三角面片進行多次遍歷,耗時較長。獲得體素化的關鍵在於我們需要有足夠的隨機點,能夠判斷一個體素化格子是否被佔用。這時候我們可以對三角面片進行插值:
假設三角形三個點分別是A,B,C
:
三角形內任意點:D = t1*A+t2*B+(1-t1-t2)*C
其中t1 t2
的範圍在0-1
這樣插值出來的點在橫縱兩個方向不是完全均勻的,因此有一定的誤差。如下圖是對三個頂點插值得到的三角形內部點。
總結
基於CPU的方法運算較慢,可以通過建立預定的索引,如八叉樹,kd
樹簡化計算過程,由於需求不需要很大量的網格,因此沒有嘗試。
基於渲染的體素化方法
由於在渲染管線中,GPU會自動對三角面片進行光柵化,如果關閉深度快取,在片段著色器中,我們可以得到所有插值後的片元,這些片元是均勻的,我們將他寫入到buffer
中,然後在CPU中讀取,經過投影過程的反變換,獲得三維座標,可以參考前面的博文
OpenGL渲染管線以及二維到三維座標之間的相互變換,然後確定每一個網格中是否被覆蓋,達到體素化的效果。這樣的速度會比用CPU算快很多,GPU的插值是並行的。
以下是同學程式的效果,本人沒有實踐。以下是效果圖:
如有錯誤,歡迎指正~