空間分割加速三維資料的查詢

2021-06-01 08:53:52 字數 1439 閱讀 5259

最近在對一些模型進行輕量化的處理,需要壓縮模型的大小,並且要求可以較快的讀取載入。原始的模型由3dmax匯出的fbx獲得,鑑於上述要求與fbx模型的格式就選擇了與渲染時的vertex buffer最接近的方式來對模型進行儲存,儲存結構如下:

******** data->vertex data

其中每個******** data儲存其所對應的頂點的索引,每個頂點資料中又儲存其對應的position, normal, tangent, uv[n]...,每個vertex data均不相同(相同的條件為包含所有元素position, normal, tangent均相同),首先嘗試直接以這種結構對模型進行儲存,但發現得到的binary模型依然較大。而且通過output發現其中的vertex data均不相同,但其中包含的position, normal, tangent等均包含較多的重複元素,因而想到再加一層線性索引來剔除這些幾何資料中的冗餘元素。

首先需要考慮的是這樣的再索引會不會不僅不能減小模型的大小,反倒使之增大。於是判斷:用索引的vertex data需要儲存5個uint的索引(uv通道為2),5 x 4 = 20 bytes, 而乙個float3的大小為3 x 4 = 12 bytes, 直觀上這樣改變會帶來不小的空間優勢。感覺用統計之類的方法來分析有些麻煩,於是決定直接實現之再來驗證。而實驗的結果也符合自己的預期,模型的大小減少得還是比較可觀的。用了crytek的sponza來進行測試(max修改過):

三角形數目:182665

刪除冗餘幾何資料前:40.4mb, vertex data: 547995

刪除冗餘幾何資料後:18.5mb, position:94983, normal&tangent: 361846, uv: 9692

模型大小控制的目的達到了,但帶來了另外乙個非常致命的問題:冗餘頂點的搜尋效率。對於上述可以達到十萬級別的頂點數量,直接的搜尋簡直是*_*!!。不過對其也進行了測試,對於該模型處理進間甚至達到好幾十分鐘,若不加速則一點可行性都沒有。首先想到的是gpu來加速,但是覺得對於這樣的一種搜尋結構不太適合。之後就想到了用空間劃分來進行加速,這有些類似於用kd-tree進行光線跟蹤,bsp進行碰撞檢測。

以空間頂點的position為例,其對於某乙個頂點,它不可以與旁邊相跟很遠的頂點有相同關係進而是冗餘點,因而只需要檢索判斷空間位置處於其周圍的那些鄰居點就可以了,這樣就可以將每個點待判斷的點的數日大大減少。對於向量,uv進行分割加速方法與position類似,向量的話就以大體方向把各向量歸成一堆。那麼現在如何確定那些點是這個點的鄰居點呢?這就需要用到各種空間分割來施展它們的作用了,什麼octree, kdtree, bvh, bsp各種,你想用那種就用那種^0^。為了簡單起見這些用了octree,簡單易行。

實現之後得到的加速效果很明顯,對於上述模型進行處理只需要4,5s以內的時間(用的樹還很淺,懶得深分了,這個也只是邊角工作)。

空間三維散點資料的線性擬合

clc clear all close all num 50 num個隨機點 rand1 randi 1,1 num,3 雜訊範圍 rand2 randi 1,1 num,3 point1 1 0.5 0.5 num 1 1 0.5 0.5 num 1 1 0.5 0.5 num 1 rand1 p...

三維空間某物體的區域自然生長分割演算法

自動篩檢非標記點體素團 方法 區域增長,找到體積在合理範圍內的體素團 void cmssdlg getmss int i 0,iat 0,j 0,n 0,zmax 0,zmin 1000 lmax 0,numin 0,bianhua 0,l 0,lpointa 0,lpointb 0 double ...

三維空間剛體旋轉

剛體 運動過程中不會產生形變的物體,運動過程中同乙個向量的長度和夾角都不會發生變化。剛體變換也稱為歐式變換。旋轉矩陣 四元數旋轉向量 尤拉角安裝方式 eigen庫只有標頭檔案,沒有.so和.a二進位制檔案,所以在cmakelists.txt中只需要新增標頭檔案路徑,並不需要使用target link...