大量球体的光线拾取最佳算法

3
在我的OpenGL应用程序中,我有很多球体(超过100,000个),我想实现一个高效的射线拾取算法。
到目前为止,我的方法是天真的:
计算与鼠标指针对应的射线(在对象空间中),然后与我拥有的每个球体相交。虽然这种方法对于我的应用程序可能足够快(实际渲染球体的速度可能比用射线拾取它们慢...),但我想知道这种情况下最好的方法是什么。
我特别关注的是这些球体可能具有任意半径,我不知道如何在空间划分结构(如八叉树)中考虑这一点。
你有什么建议吗?
我将添加更多细节:
所涉及的应用程序是一个分子查看器,其中原子被表示为球体,如下图所示:
球体可以部分或完全重叠。场景可以是动态的(您可以进行分子模拟),但通常在动画期间不希望选择任何内容。
理想情况下,我希望找到一个解决方案,也可以将其扩展到未来的圆柱体。

你能再次查看问题吗?我已经添加了更多信息并审查了问题标题。我认为这个问题是合适的,因为它询问了一个非常特定情况下的最优算法。这就像询问特定排序的最佳搜索算法一样。这个问题很可能有一个独特且最优的答案。 - pygabriel
2个回答

3

这是一个有趣的问题!

在IT技术中,射线和球体碰撞测试是最简单的之一,因此通常用于确定潜在可见集(PVS)时使用球体。

基本上,你可以用大球体围住小球体。首先,你需要用一个巨大的球体测试射线碰撞,如果失败了,那么你就可以确定任何其他位于这个大体积内的球体也不会与该射线相交。 如果射线相交,则只需移动到该体积内并测试组中的下一个球体... 这种层次结构将节省大量计算时间。

从O(N)(每个球体都进行测试)到O(Log N)(如二叉树或四叉/八叉树)。

一个问题是当你的层次结构是动态的时,你将不得不重建球体。你可以重建整个树 - 大约O(n Log n),或者聪明地重建层次结构的移动部分。 如果K个球体在移动,那么重建的时间可以减少到约O(K Log N)(例如删除特定的球体,然后再插入)

这里有一个关于选取的教程和一个关于包围球体的维基百科


2
如果允许将球体附加到八叉树的内部节点,则超大球体可以位于不会使其分裂的任何级别。 编辑: 进一步讨论时,了解球体是否允许重叠以及它们是静态还是动态也很有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接