Graphics 有效计算查看光线和一组对象之间的第一个交点的最佳方法是什么?

Graphics 有效计算查看光线和一组对象之间的第一个交点的最佳方法是什么?,graphics,3d,raytracing,Graphics,3d,Raytracing,例如: 一种有效计算观察光线与一组三个对象(一个球体、一个圆锥体和一个圆柱体(其他3D基本体))之间的第一个交点的方法。您需要的是一种空间分割方案。处理这个问题有很多选择,在这个领域也投入了大量的研究。克里斯特·爱立信(Christer Ericsson)是一本好读物 该书中介绍的一种简单方法是定义一个网格,将所有对象指定给它所相交的所有单元,并沿着与线相交的网格单元向前向后走,与与与该网格单元关联的每个对象相交。请记住,一个对象可能与更多的网格单元相关联,因此计算的交点实际上可能不在当前单元中

例如:


一种有效计算观察光线与一组三个对象(一个球体、一个圆锥体和一个圆柱体(其他3D基本体))之间的第一个交点的方法。

您需要的是一种空间分割方案。处理这个问题有很多选择,在这个领域也投入了大量的研究。克里斯特·爱立信(Christer Ericsson)是一本好读物

该书中介绍的一种简单方法是定义一个网格,将所有对象指定给它所相交的所有单元,并沿着与线相交的网格单元向前向后走,与与与该网格单元关联的每个对象相交。请记住,一个对象可能与更多的网格单元相关联,因此计算的交点实际上可能不在当前单元中,而是在以后

下一个问题是如何定义网格。不幸的是,没有一个好的答案,你需要考虑哪种方法最适合你的剧本。

其他感兴趣的分区方案是不同的树结构,例如,和。你甚至可以考虑使用与网格相结合的树。

编辑
如前所述,如果你的集合实际上是这三个对象,那么你最好将它们相交,然后选择最早的一个。如果您正在寻找光线球体、光线圆柱体等相交测试,这些测试其实并不难,快速的谷歌应该可以提供您可能需要的所有数学知识。:)

“计算效率”取决于集合的大小

对于三个简单的集合,只需依次测试它们中的每一个,就不值得尝试优化

对于较大的集合,请查看划分空间的数据结构(例如KD树)。整章(甚至整本书)都致力于解决这个问题。我最喜欢的参考书是(埃德·安德鲁·格拉斯纳)


或者,如果我误解了你的问题,而你实际上是在询问特定类型对象的光线对象交点算法,请参阅同一本书

我假设你有一条射线d=(dx,dy,dz),从o=(ox,oy,oz)开始,你正在寻找参数t,这样交点p=o+d*t。(与第页类似,第页描述了使用P2-P1表示d、P1表示o和u表示t的光线平面相交)

我想问的第一个问题是“这些物体相交吗?”

如果没有,那么你可以作弊一点,并按顺序检查光线碰撞。由于每帧有三个对象可能移动,也可能不移动,因此需要预先计算它们与摄影机的距离(例如,从它们的中心点)。按距离摄像机的距离,从最小到最大,依次对每个对象进行测试。尽管现在渲染的空白部分是最昂贵的部分,但这比仅针对所有三个部分进行测试并取最小值更有效。如果您的图像是高分辨率的,那么这是特别有效的,因为您在像素数量上分摊了成本

否则,对所有三个进行测试并取最小值


在其他情况下,您可能希望混合使用这两种方法。如果您可以按顺序测试其中两个对象,则可以这样做(例如,沿圆柱形通道向下移动的球体和立方体),但请测试第三个对象,并取最小值以找到最终对象。

好的,这取决于您真正想做什么。如果您想为简单场景中的几乎每个像素生成一个正确的解决方案,一个非常快速的方法是通过使用扫描转换(也称为z缓冲区)将具有唯一识别颜色的所有对象预渲染到背景项缓冲区中,预计算每个像素的“前面是什么”。这有时称为项目缓冲区

使用该预计算,您就可以知道将要拍摄到场景中的几乎所有光线都可以看到什么。因此,光线与环境的相交问题大大简化:每条光线击中一个特定对象

当我这样做的时候,我正在生成公认简单场景的实时光线跟踪图像。我已经有很长一段时间没有重温这段代码了,但我怀疑,使用现代编译器和图形硬件,性能会比我当时看到的好几个数量级


PS:我第一次读到关于物品缓冲区的想法是在90年代初,当时我正在做我的文献搜索。我最初发现它出现在(我相信)70年代末的ACM论文中。遗憾的是,我没有可用的源代码参考,但简言之,这是一个非常古老的想法,在扫描转换硬件上非常有效。

仅对3个对象进行分区就太过分了。我认为最好解释下一票…非常感谢,如果你在下一票/投票前阅读了整个答案,你会注意到我也提到了这一点。更重要的是,那些二次曲面不适合按照空间细分的要求进行分割。当对象计数增加时,空间层次结构更有可能是OP想要的。。。