我已经使用适用于iOS的MetalFramework实现了实时光线跟踪器,它实现了以下光学棱镜,如十二面体,二十面体,八面体,立方体等。我所有的图形都是由三角形组成的,例如立方体 - 12个三角形,八面体 - 4三角形。我跟踪光线并搜索与图形的交点,然后我搜索光线如何在棱镜中移动。然后射线离开图,我搜索与天空盒的交叉点。问题在于复杂的数字。当我测试立方体fps是60时,但是当我测试十二面体时fps是6.在我的算法中,与图形的交点与任何三角形的交点相同。这意味着当我检查与光线和图形的交叉点时,我必须检查与所有三角形的交叉点。我需要知道如何不检查所有三角形的交叉点。感谢。
答案 0 :(得分:3)
假设你的世界受到一些边界框的限制
创建网格(将此框划分为多维数据集或其他内容)
每个体素/细胞
是一个三角形的列表,它们相互交叉或在其中,所以在渲染每个单元格之前处理所有三角形并存储所有三角形内部或交叉的索引
重写光线追踪器以追踪此体素地图
因此,只需通过相邻体素增加光线,就像像素上的线光栅化一样。这样你就完成了部分Z-sort。因此,第一个体素被光线击中并仅测试其中包含的三角形。如果发现任何体素击中然后停止(不需要测试其他体素,因为它们更有效)。
进一步优化
如果三角形已经过测试,您可以添加标记,因此只测试那些尚未测试的标记,因为许多三角形将被多次测试,否则
<强> [注释] 强>
每个轴的体素数量会极大地影响性能,因此您需要稍微玩一下才能获得最佳性能。如果您有动态对象,那么体素图列表计算必须偶尔进行一次,甚至每帧进行一次。对于静态场景,只需执行一次即可。
答案 1 :(得分:1)
要有效跟踪,您需要使用加速结构,例如KD树或边界体积层次结构(BVH)。这类似于使用二叉搜索树来查找匹配元素。
我建议使用BVH,因为它比KD树更容易构造和遍历。我建议不要使用统一的体素网格结构。当三角形在场景中分布不均匀或者集中在几个体素中时,体素网格很容易表现出很差的性能。
BVH只是一个边界体积的树,例如轴对齐的边界框(AABB),它包含其中的图元。这样,如果你的光线错过了边界体积,你知道它没有击中它所包含的任何基元。
构建BVH:
将所有三角形放在一个边界体积中。这将是树的根。
将三角形划分为两组,其中每组三角形的边界体积最小化。更准确地说,你想要遵循表面区域启发式(SAH),在那里你想要创建一组三角形,你最小化两组三角形的(BVH的表面区域)/(#三角形)之和。 / p>
递归地对每个节点重复步骤2,直到你剩下的三角形数量达到某个阈值(4是一个很好的数字来尝试)。
遍历
检查光线是否击中根边界框,如果是,则进入步骤2,否则不会命中。
检查是否碰到了儿童边界框。如果是,则对其子边界框重复此步骤。否则没有命中。
当你得到一个只包含三角形的边界框时,你需要测试每个三角形以确定它是否像正常一样被击中。
这是BVH的基本概念。还有更多细节,我没有涉及你需要搜索的BVH,因为细节有很多变化。
简而言之实现要跟踪的边界卷层次结构。