八叉树光线投射/光线追踪 - 无需递归的最佳光线/叶子相交
谁能提供一个简短的&关于如何在不递归的情况下向体素八叉树投射光线的甜蜜解释(或建议一个好教程)?
我有一个复杂的模型烘焙成八叉树,我需要找到与射线相交的最佳/最近的叶子。标准的向下钻取迭代树遍历:
- 抓住根节点
- 检查交集
- 否?退出
- 是吗?找到与射线相交最接近射线原点的子级
- 循环直到到达叶子或退出树
始终返回叶子,但在树存储地形的情况下,距离射线原点最近的节点不会必然包含最匹配的叶子。这并不奇怪——使用这种方法不会测试较远节点中较高的对象。
我可以通过找到树中所有相交的叶子、按距离排序并选择最接近光线位置的叶子来递归地完成此操作。然而,这很慢并且需要递归。
我读过一些关于使用 Bresenham 线算法来遍历树的内容,这似乎要求每个节点包含指向相邻邻居的指针,但我不清楚如何以有用的方式实现这一点。
有什么建议吗?我可以在 HLSL 中使用固定长度数组或每个潜在堆栈条目都有一个元素的结构来伪造堆栈,但对于足够大的树来说,其内存需求可能会变得严重。
帮助。
Could anyone provide a short & sweet explanation (or suggest a good tutorial) on how to cast a ray against a voxel octree without recursion?
I have a complex model baked into an octree, and I need to find the best/closest leaf that intersects a ray. A standard drill-down iterative tree walk:
- Grab the root node
- Check for intersection
- No? Exit
- Yes? Find child that intersects the ray that is closest to the ray's origin
- Loop until I reach a leaf or exit the tree
Always returns a leaf, but in instances where the tree stores, say, terrain, the closest node to the ray's origin doesn't necessarily contain the leaf that's the best match. This isn't suprising - taller objects in farther nodes won't get tested using this approach.
I can do this recursively by finding all of the intersecting leaves in the tree, sorting by distance and picking the closest one to the ray's position. However, this is slow and requires recursion.
I've read a little about using the Bresenham line algorithm to walk the tree, which seems to require that each node contain pointers to adjacent neighbors, but I'm unclear on how to implement this in a useful way.
Any suggestions? I can fake a stack in HLSL using a fixed-length array or a struct with an element for each potential stack entry, but the memory requirements for that can become crippling with a sufficiently large tree.
Help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经设法使用 3D DDA 算法和邻居节点指针来实现此功能。
我仍在解决一些错误,但这里有一个似乎可以工作的 C# 版本。当它到达第一片叶子时,它就会停止,但这并不是完全必要的。
欢迎指出任何错误。如果有任何需求,我会发布 HLSL 版本。
这是另一个版本,它仅以叶子大小的步骤遍历树,而无需进行相交检查。这作为 3D DDA 演示很有用:
HLSL 版本仅将树存储在 Texture3D 中,没有邻居或树的任何“稀疏性”。
这仍然是有问题的。使用
hitbox()
进行的第一个测试工作正常,但光线最终在树内发生折射。这看起来很酷,但并不正确。这是当我停在根边界而不使用 DDA 遍历树时的样子:
更新
发现了一个非常好的体渲染教程!
http://graphicsrunner.blogspot.com/search?updated-max=2009-08-27T02%3A45%3A00-04%3A00&max-results=10
I've managed to get this mostly working using a 3D DDA algorithm and neighbor node pointers.
I'm still working out a few bugs, but here's a C# version that appears to work. This one stops when it reaches the first leaf, but that's not entirely necessary.
Feel free to point out any bugs. I'll post the HLSL version if there's any demand.
Here's another version that just steps through the tree in leaf-sized steps without intersection checking. This is useful as a 3D DDA demonstration:
And an HLSL version that just stores the tree in a Texture3D, without neighbors or any "sparseness" to the tree.
This is still buggy. The first test with
hitbox()
works correctly, but the ray winds up getting refracted within the tree. This looks very cool, but isn't correct.Here's what it looks like when I stop at the root bounds, without using the DDA to traverse the tree:
update
Found a very good volume rendering tutorial!
http://graphicsrunner.blogspot.com/search?updated-max=2009-08-27T02%3A45%3A00-04%3A00&max-results=10