Original Post
I'm working on my raytracer and in an effort to speed it up a bit, I'm ditching the algebraic method of ray-triangle intersection, and am replacing it with a parametric method, as described here. I'm gonna start talking some math stuff here so I made this diagram to help explain the method I'm using.
Ro = origin of the ray. Rd = direction of the ray. P = point of intersection on the plane constructed from the three vertices of the triangle v1, v2, v3 = vertices of the triangle, in clockwise winding order. now according to the slides in the Princeton lecture, in order for P to be inside the triangle, a and b must both be in the range 0..1. My 3D math isn't the best but I recognised that a is simply the scalar projection of Z onto X, and b is the scalar projection of Z onto Y, where Z = P - v3, X = v2 - v3, and Y = v1 - v3. Correct? So here's my implementation... And the output...
Doesn't quite look like the famous Utah Teapot, now does it? Where exactly did I go wrong here?
Ro = origin of the ray. Rd = direction of the ray. P = point of intersection on the plane constructed from the three vertices of the triangle v1, v2, v3 = vertices of the triangle, in clockwise winding order. now according to the slides in the Princeton lecture, in order for P to be inside the triangle, a and b must both be in the range 0..1. My 3D math isn't the best but I recognised that a is simply the scalar projection of Z onto X, and b is the scalar projection of Z onto Y, where Z = P - v3, X = v2 - v3, and Y = v1 - v3. Correct? So here's my implementation... float RTTriangle::intersect(const Rayf &ray)
{
float distance = mPlane.intersect(ray);
if(distance == std::numeric_limits<float>::infinity())
{
return distance;
}
Vector3f P = ray.mOrigin + ray.mDir * res.distance;
Vector3f Z(P - mVerts[2]); //P - v3
Vector3f X(mVerts[1] - mVerts[2]); //v2 - v3
X.normaliseSelf();
float a = Z.dot(X);
if(a < 0 || a > 1)
{
return std::numeric_limits<float>::infinity();
}
Vector3f Y(mVerts[0] - mVerts[2]); //v1 - v3
Y.normaliseSelf();
float b = Z.dot(Y);
if(b < 0 || b > 1)
{
return std::numeric_limits<float>::infinity();
}
return res;
}
Doesn't quite look like the famous Utah Teapot, now does it? Where exactly did I go wrong here?



