Ray-Sphere交叉:判别错误

时间:2011-12-25 03:13:35

标签: math geometry intersection raytracing

好吧,所以我正在使用phong阴影处理光线追踪器。到目前为止,一切都很好。我投射的光线已经击中了我场景中的球体,对它们应用了阴影,看起来很正常。

现在,我正在计算阴影射线,它从主光线到光源的交点发射光线,并观察它是否在途中碰到任何物体。如果确实如此,那就是阴影。

然而,当计算阴影射线是否击中任何球体时,我的判别式似乎存在误差,这是奇怪的,因为它对于主射线来说是正确的。

以下是设置:

// Origin of ray (x,y,z)
origin: -1.9865333, 1.0925934, -9.8653316
// Direction of ray (x,y,z), already normalized
ray: -0.99069530, -0.13507602, -0.016648887

// Center of sphere (x,y,z)
cCenter: 1.0, 1.0, -10.0
// Radius of the sphere (x,y,z)
cRadius: 1.0

,这是找到判别式的代码:

// A = d DOT d
float a = dotProd(ray, ray);

// B = 2 * (o - c) DOT d
Point temp (2.0*(origin.getX() - cCenter.getX()), 2.0*(origin.getY() - cCenter.getY()), 2.0*(origin.getZ() - cCenter.getZ()));
float b = dotProd(temp, ray);

// C = (o - c) DOT (o - c) - r^2
temp.setAll(origin.getX() - cCenter.getX(), origin.getY() - cCenter.getY(), origin.getZ() - cCenter.getZ());
float c = dotProd(temp, temp);
c -= (cRadius * cRadius);

// Find the discriminant (B^2 - 4AC)
float discrim = (b*b) - 4*a*c; 

显然,光线指向远离球体,但这里的判别是正的(2.88),表明射线正在击中球体。此代码适用于主光线,因为它们的判别式必须正确,但不适用于这些次级阴影光线。

我在这里遗漏了什么吗?

3 个答案:

答案 0 :(得分:3)

对我的问题做出如此简短的回答,以防有人发现并遇到同样的问题:

判别式会告诉您是否存在匹配(对于 ray ,就像我想的那样)。如果它是积极的,那么它已经在线路的某处发现了一个命中。

因此,在计算射线的t值时,检查它们是否为负值。如果它们是,则它是射线的原点(即射线的相反方向)之后的撞击,所以丢弃它。只保留正值,因为它们会在射线方向上击中。

更短的答案:丢弃负t值。

归功于 woodchips 让我意识到这一点。

答案 1 :(得分:0)

问题是,找到直线和球体的交点的技巧需要求解二次方程。这样的方程具有三种可能性之一作为解决方案 - 该方程有0,1或2个实数解。判别式的符号告诉我们有多少真正的解决方案(以及帮助我​​们解决这些解决方案。)

如果存在唯一解,那么该线就会亲吻球体的表面。当判别式正好为零时会发生这种情况。

如果存在两个解,则该线穿过球体,以两个不同的点击中表面。

如果不存在真正的解决方案(判别式为负的情况)那么该线离球体太远而无法接触它。

在发现线是否接近球体之后,我们才会担心光线是否会击中它。为此,我们可以看看我们如何定义光线。射线是半直线,仅在一个方向上延伸到无限远。所以我们期待看到交叉点发生在哪里。只有当我们关心的线的一半发生交叉时,才会有一个RAY-sphere交叉点。

关键是,判别式的计算(并简单地测试其符号)仅告诉您线的作用,而不是关于沿该线发生交叉的位置。

当然,仔细阅读您自己提供的链接会告诉您所有这些。

答案 2 :(得分:-1)

很确定“o-c”应该是“c-o”

你正朝错误的方向拍摄一条光线并找到球体另一侧的交叉点。