我想實現光線跟蹤,我用從書‘的基礎基於物理渲染’KD樹構造方法在KD-tree構造邊界框。拆分從「基於物理渲染」
書使用一種稱爲SAH的方法來選擇分割邊界框的位置 它從場景中對象的邊界框的邊緣選擇分割位置。邊沿沿軸線從低到高排序。
它和它找到像這樣的最佳分割:
//<Compute cost of all splits for axis to find best>
int nBelow = 0, nAbove = nObjects;
for(int i = 0; i < 2 * nObjects ; ++i){
if(edges[axis][i].type == END) -- nAbove;
float edget = edges[axis][i].t;
if(edget > nodeBounds.pMin[axis] &&
edget < nodeBounds.pMax[axis]){
//<Compute cost for split at ith edges>
}
if(edges[axis][i].type == START) ++ nBelow;
}
我把球體100在場景隨機這樣的:
for(int i = 1 ; i < 100 ; ++ i){
float x,y,z,r;
x = 800 * float(rand())/float(RAND_MAX) - 200 ;
y = 800 * float(rand())/float(RAND_MAX) - 200 ;
z = 400 * float(rand())/float(RAND_MAX) - 100 ;
r = 50 * float(rand())/float(RAND_MAX) + 25;
initSphere(..., Point3D(x,y,z) , r ,...);
}
明顯,球體可以相互重疊。
並沒有好的分割位置,可以讓兩個子盒子覆蓋所有的對象。跨越分割位置的對象將不在任何子框中。 我增加了一個新的條件,只有當分割位置下方的對象數加上面的數字等於邊界框中所有對象的數量時,纔會記錄位置。
//update best split if this is lowest cost so far
if(cost < bestCost && (nBelow + nAbove == nObjects)){
bestCost = cost;
bestAxis = axis;
bestOffset = i;
}
(nBelow + nAbove == nObjects)總是「假」。如果
如果我們在這裏創建一個葉節點,那麼kd-tree是無意義的,它簡單地退化爲順序遍歷,因爲整棵樹將只包含一個葉節點。
那麼,有沒有解決方案?謝謝!
這裏是一些定義:
struct Point3D{
float x,y,z;
}
struct BBox{
float pMax[3],pMin[3];
}
struct BoundEdge{
float t;
int type; // START or END
}
BoundEdge *edges[3];
ps.i希望我的英語不好解釋清楚的問題...