光线追踪框相交

Posted

技术标签:

【中文标题】光线追踪框相交【英文标题】:Ray tracing box intersections 【发布时间】:2012-01-17 23:54:04 【问题描述】:

所以我又带着另一个光线追踪问题回来了。我的代码将球体渲染得很好,很漂亮,但立方体并没有真正起作用。我正在使用此代码来测试交叉点:http://pastebin.com/qgm6vpdx(这是一个递归函数,t 是到交叉点的距离) 边界框定义为:

Cube* c1 = new Cube;      
c1->Corner1 = Vec3(100, 100, 100);      
c1->Corner2 = Vec3(200, 200, 200);

我已确认相机不在立方体内。 现在,唯一的问题是整个屏幕显示为绿色(指定给立方体的颜色)

我不认为我在做立方体交叉点,任何人都可以校对我的代码吗?

【问题讨论】:

嗨,克里斯,我不想阻止你发帖和寻求帮助,但我认为你应该在提问之前对你的代码进行一些健全性检查。例如,如果您的方框交叉点不起作用,则测试情况是您知道正确答案是什么。即角在 (0,0,0) 处大小 (1,1,1) 与 (-1,0.5,0.5) 处的射线相交的框沿 (1,0,0) 移动将在 (0,0.5 ,0.5),这种事情。然后,当您来到这里时,您可以获得建议,而不仅仅是将其用作校对服务。 【参考方案1】:

计算光线盒交点的最佳算法之一是slab method。我还概述了我对它的优化实现here。

【讨论】:

嗨,Tavian,我发现这非常有用! - 但是,这种方法是否应该尊重/理解方向向量的符号?因为将您的函数逐行复制到 Golang 似乎并不 - 我只是在这里提出了一个 SO 问题:***.com/questions/9971105/…【参考方案2】:

您可以使代码更短且更具可读性。例如,将int tNear = -2147000000 更改为int tNear = INT_MIN 并更改

if(t1 > t2)

    float temp1 = t1;
    t1 = t2;
    t2 = temp1;

if(t1 > t2)

    // std::swap is built-in
    swap(t1, t2);

或更好

// Define 'order' yourself
order(t1, t2);

改变

if(t1 > tNear)

   tNear = t1;

// std::max is built in
tNear = max(tNear, t1);

那么你的一段代码就变成了:

if ((ray.dir.x == 0) && (ray.start.x < Min.x) && (ray.start.x > Max.x))

    //parallel
    return false;

else

    float t1 = (Min.x - ray.start.x) / ray.dir.x;
    float t2 = (Max.x - ray.start.x) / ray.dir.x;
    order(t1, t2);
    tNear = max(tNear, t1);
    tFar = max(tFar, t1);
    if ((tNear > tFar) || (tFar < 0))
        return false;

这揭示了一个问题。 tNeartFar 定义了一个t 值的区间,在该区间内线与立方体相交。您测试的每个坐标(x、y 和 z)进一步限制了区间。但是代码tFar = max(tFar, t1) 正在扩大间隔。将其更改为tFar = min(tFar, t1)

更根本的是,这将您限制在轴对齐的长方体上,尽管此代码稍后可能会用作更复杂形状的快速命中测试。无论如何,一旦它起作用,您可能希望使其更通用。

您可以将任何凸多边形定义为法线朝外的一组无限平面。如果一个点在所有平面“内部”,则它位于多边形内部。

平面将空间分成两半。将法线指向的一半定义为“外侧”,另一半定义为“内侧”。如果该点的平面方程为正,则该点在平面外,如果值为负,则在平面内,如果值为零,则在平面上。

要进行光线追踪,您需要确定光线/平面的交点并选择最近的。要确定该点是否在面内(请记住,平面是无限的),请检查该点是否在所有其他平面内。如果不是,则测试下一个最近的路口,依此类推。

一旦它开始工作,就很容易将其扩展到一般的交叉点和形状的差异(例如,在其中一个面上具有半球形缩进的立方体)。

【讨论】:

以上是关于光线追踪框相交的主要内容,如果未能解决你的问题,请参考以下文章

C中的光线追踪器,光线平面相交

在光线追踪中为对象着色

是否可以在没有 CUDA/OpenCL 等的情况下使用 GPU 进行光线追踪?

光线追踪、光线投射、光线行进和路径追踪有啥区别?

GAMES202 笔记-实时光线追踪

3D渲染-光线追踪-包围盒