raytracer で 3D KD-Tree をトラバースしようとしています。ツリーは正しいですが、ブルート フォース アプローチを使用する場合と比較してエラーが発生するため、トラバーサル アルゴリズムに問題があるようです (いくつかの小さな表面領域が無視されるようです)。
注: 問題の光線はどの軸にも平行ではありません。
これは私のトラバーサルアルゴリズムです:
IntersectionData* intersectKDTree(const Ray &ray, KDTreeNode* node, double tMin, double tMax) const{
if (node->GetObjectCount()==0) return 0;
IntersectionData* current = 0;
bool intersected = false;
if (node->m_isLeaf){
...test all primitives in the leaf...
}
else{
int axis = node->m_splitAxis;
double splitPos = node->m_splitPos;
double tSplit = (splitPos-ray.point[axis])/ray.direction[axis];
KDTreeNode* nearNode = ray.point[axis]<splitPos?node->m_leftnode:node->m_rightnode;
KDTreeNode* farNode = ray.point[axis]<splitPos?node->m_rightnode:node->m_leftnode;
if (tSplit > tMax)
return intersectKDTree(ray, nearNode , tMin, tMax);//case A
else if (tSplit < tMin){
if(tSplit>0)
return intersectKDTree(ray, farNode, tMin, tMax);//case B
else if(tSplit<0)
return intersectKDTree(ray, nearNode, tMin,tMax);//case C
else{//tSplit==0
if(ray.direction[axis]<0)
return intersectKDTree(ray, farNode, tMin, tMax);//case D
else
return intersectKDTree(ray, nearNode, tMin, tMax);//case E
}
}
else{
if(tSplit>0){//case F
current = intersectKDTree(ray, nearNode, tMin, tSplit);
if (current != 0)
return current;
else
return intersectKDTree(ray, farNode, tSplit, tMax);
}
else{
return intersectKDTree(ray,nearNode,tSplit, tMax);//case G
}
}
}
}
私はすべての異なるケースでグラフィックを作成しました:
(出典: cycovery.com )
ケースがありませんか?
お手伝いありがとう!