Ray-Triangle Intersection

I’m trying to do ray-triangle intersection test like it is done at the https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/ray-triangle-intersection-geometric-solution

I think everything is working, except that I’m getting a t value that is the opposite of what I expect. For example when I test a triangle with vertices v0 [-1, -1, -10], v1 [1, -1, -10], v2 [0, 1, -10], and point § [0,0,0], and direction vector (d) [0, 0, -1], I’m getting a value of -10 instead of +10 for t.

So when I solve using t to get the intersection point the z-value is always flipped, I wasn’t sure if this was something to do with the coordinate system in opengl or if I have an error in my code somewhere?? I went over my code pretty thoroughly to make sure I was doing the macro operations like vector, crossproduct, innerProduct etc the same as they do it on the site and I can’t figure out what else could be wrong!

This is java code, I guess I was just hoping to get an explanation why my t is wrong sign before I just add a negative sign to my calculations!


public static boolean RayTriangleIntersectionTest(Vector3f p, Vector3f d, Vector3f v0, Vector3f v1, Vector3f v2)
        {
            Vector3f e1 = VectorFromPoints(v0, v1);
            Vector3f e2 = VectorFromPoints(v0, v2);

            Vector3f h = CrossProduct(d, e2);
            double a = DotProduct(e1, h);

            if (a > -0.00001 && a < 0.00001)
                return false;

            double f = 1.0 / a;

            Vector3f s = VectorFromPoints(v0, p);
            double u = f * DotProduct(s, h);

            if (u < 0.0 || u > 1.0)
                return (false);

            Vector3f q = CrossProduct(s, e1);
            double v = f * DotProduct(p, q);

            if (v < 0.0 || u + v > 1.0)
                return (false);

            // at this stage we can compute t to find out where the intersection point is on the line
            double t = f * DotProduct(e2, q);

            if (t > 0.00001) // ray intersection
                return (true);
            else // line intersection but not a ray intersection
                return (false);
        }

public static Vector3d CrossProduct(Vector3f v0, Vector3f v1)
        {
            Vector3f Vout = new Vector3f();

            Vout.x = v1.y * v0.z - v0.y * v1.z;
            Vout.y = v1.x * v0.z - v0.x * v1.z;
            Vout.z = v1.x * v0.y - v0.x * v1.y;

            return Vout;
        }

        public static double DotProduct(Vector3f v0, Vector3f v1)
        {
            return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
        }

        public static Vector3d VectorFromPoints(Vector3f v0, Vector3f v1)
        {
            return new Vector3f(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z);
        }

You should rework your CrossProduct() method. It swaps v0 and v1 sometimes.
A correct version would be:


Vout.x = v1.z * v0.y - v0.z * v1.y;
Vout.y = v1.x * v0.z - v0.x * v1.z;
Vout.z = v1.y * v0.x - v0.y * v1.x;

Now method returning always false :confused:

Look veeery thoroughly over your code. The next error is this:


double v = f * DotProduct(p, q);

That’s supposed to be:


double v = f * DotProduct(d, q);

If you want to spare yourself the trouble, you can just use JOML’s Intersectionf.intersectRayTriangle() method. It’s the same algorithm.