Graphics 具有边界体积层次的光线跟踪对象矩阵变换
在我正在开发的光线跟踪器中,我遇到了一个有趣的问题。场景中的对象存储在边界体积层次中。每个单独的对象都封装在层次的叶节点处的边界框中,并具有与其关联的矩阵变换 现在,在光线跟踪中,我学习的对物体进行矩阵变换的方法是通过物体矩阵的倒数变换每条光线,然后看看是否有交点。在伪代码中(并且没有bvh树),它将如下所示:Graphics 具有边界体积层次的光线跟踪对象矩阵变换,graphics,matrix,3d,raytracing,bounding-box,Graphics,Matrix,3d,Raytracing,Bounding Box,在我正在开发的光线跟踪器中,我遇到了一个有趣的问题。场景中的对象存储在边界体积层次中。每个单独的对象都封装在层次的叶节点处的边界框中,并具有与其关联的矩阵变换 现在,在光线跟踪中,我学习的对物体进行矩阵变换的方法是通过物体矩阵的倒数变换每条光线,然后看看是否有交点。在伪代码中(并且没有bvh树),它将如下所示: float minimum_distance = FLOAT_MAX; Intersection closestHit = null; for(each object in scene
float minimum_distance = FLOAT_MAX;
Intersection closestHit = null;
for(each object in scene)
{
Matrix transform = object.transform();
Matrix inverse = transform.inverse();
Ray transRay = transformRay(eyeRay, inverse);
Intersection hit = CollisionTest(transRay, object);
if(intersectionFound)
{
if(hit.distance() < minimum_distance)
{
closestHit = hit;
}
}
}
Shade(closestHit);
现在让我们假设我们有一条只与正确的盒子相交的光线。光线将只检查右框中的相交对象,而完全忽略左框中的任何对象(这是将对象放置在这样的层次中的主要优点…以避免不必要的检查)
但是,左框中的对象A有一个与其关联的缩放变换,应用该变换时会拉伸对象A,使其跨越右框区域。如果允许光线针对场景中的每个对象检查自身,您会发现,当对象A的变换的逆方向应用于光线时,将找到交点。但是,光线永远不会被允许进行转换检查,因为未转换的对象A正好位于左框中。因此,交点将丢失,结果将是部分渲染的对象a
所以我的问题是我将如何解决这个问题?我不想放弃使用边界体积层次,但我不知道它如何与上面的光线反转算法兼容。有什么想法吗?首先,有许多BVH树的专门化。更常见的方法是排除相邻节点边界体积的交点(即左框不能与右框相交) 现在,边界体积的整个要点是它将基础对象边界化。因此,如果该对象的变换将其缩放到边界体积之外,则表示该边界体积不是正确的边界体积(BV) 解决此问题的两种方法是,如果边界体积是在未变形的几何体上计算的,则在检查光线边界体积交点时,首先将BV变换为与对象相同的坐标系 根据您正在执行的操作,更有效的方法可能是直接在变换对象(缩放、平移等)上计算BV。这样,在执行初始光线BV检查时,不需要变换长方体(或光线)
希望这能有所帮助。不幸的是,在光线跟踪中,不建议变换对象而不是光线。假设你的对象是球体——变换球体并与未变换的光线相交需要提出一种可以处理任意球体的相交算法。变换光线意味着您可以始终使用常规球体光线相交测试。此外,我不能仅仅通过对象变换来变换边界框,因为假设左框中有两个对象,有两个不同的变换。是否需要对每个对象的边界框进行迭代变换?因此,如果一个框中有两个对象,则需要计算两个~transformed~对象的边界框。现在,您可以将未变换的光线与此框进行比较,如果它命中,则将光线变换到对象1的空间中,检查碰撞,然后将光线变换到对象2的空间中,并在那里检查碰撞。会很好的。
ROOT
Left Box Right Box
| |
V V
object A object B