0

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

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

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

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

4

2 回答 2

6

计算光线盒交点的最佳算法之一是平板法我也在这里概述了我对它的优化实现。

于 2012-01-19T20:22:34.137 回答
3

您可以使代码更短且更具可读性。比如 change int tNear = -2147000000toint tNear = INT_MIN和 change

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).

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

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

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

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

一旦这工作起来,就很容易将其扩展到一般的交叉点和形状的差异(例如,在其中一个面上带有半球形凹痕的立方体)。

于 2012-01-18T02:39:29.800 回答