我目前正在实施 Revelles、Urena 和 Lastra 的论文“An Efficient Parametric Algorithm for Octtree Traversal”。在Ray - Octree 交叉算法中,有人实现了它并粘贴了他的代码。我的实现应该是相同的,只是我使用了一些向量进行计算。然而,使用这个八叉树只会渲染图像的右上角,对于图像的其余部分,八叉树不会被遍历。检查是否遍历发生在以下方法中:
bool Octnode::intersect( Ray r, SurfaceData *sd )
{
unsigned int a = 0;
v3d o = r.origin();
v3d d = r.direction();
if ( r.direction()[0] < 0. ) {
o[0] = _size[0] - r.origin()[0];
d[0] = -r.direction()[0];
a |= 4;
}
if ( r.direction()[1] < 0. ) {
o[1] = _size[1] - r.origin()[1];
d[1] = -r.direction()[1];
a |= 2;
}
if ( r.direction()[2] < 0. ) {
o[2] = _size[2] - r.origin()[2];
d[2] = -r.direction()[2];
a |= 1;
}
v3d t0 = ( _min - o ) / d;
v3d t1 = ( _max - o ) / d;
scalar t = std::numeric_limits<double>::max();
// traversal -- if any -- starts here
if ( t0.max() < t1.min() ) {
return processSubtree( t0, t1, r, &t, sd, a );
} else {
return false;
}
}
[编辑]上述方法实现功能
void ray_parameter( octree *oct, ray r )
从纸上。正如 C. Urena 指出的那样,论文中有一个错误导致遍历不正确。不幸的是,在此错误起作用之前跳过了遍历。在 C. Urena 的链接之后可以找到的 Google 组中,似乎八叉树节点的大小的计算方式不同。我做了:
_size = _max - _min;
相对
_size = ( _max - _min ) / 2.;
在谷歌组。我将对其进行测试并发布另一个更新。[/编辑]
[编辑 2]应用 Carlos 提到的修复程序并将大小减少一半给我带来了这么多:
球体应该被完全渲染,但至少不是左上角的所有光线都被拒绝。[/编辑 2]
[编辑 3]使用不同的数据集我得到了看似更好的结果,看起来我必须调查代码的其他部分。
[/编辑 3]