Ray Triangle Intersection algorithm error?


Actually I have previous post open but would like to ask one more thing here.

I’ve tried various Ray Triangle Intersection algorithms and found that it works with some conditions but some doesn’t.
For example, the line is passing through triangle if you check out below screenshot, but algorithm returns false if the direction changes

  • Case 1

Origin → Direction: Function IntersectTriangle returns true

  • Case 2

Direction → Origin: Function IntersectTriangle returns false

I would like to have your advice to solve following problems in my program.

  1. Incorrect coordinate of intersection point x
  2. Reason why Ray Triangle Intersection algorithm returns different result when the direction of line gets changed?

struct Ray {
    vec3 Origin;
    vec3 Dir;

// Check whether the intersect point is in triangle
bool PointInOrOn(vec3 p1, vec3 p2, vec3 a, vec3 b) {
    // if the line from a corner point to the intersection point is between the to legs which are connected to the corner point
    vec3 cp1 = cross(b - a, p1 - a);
    vec3 cp2 = cross(b - a, p2 - a);

    // Return its result
    return dot(cp1, cp2) >= 0;

// Check whether the point is in triangle
bool PointInTriangle(vec3 px, vec3 p1, vec3 p2, vec3 p3) {
    return PointInOrOn(px, p1, p2, p3) && PointInOrOn(px, p2, p3, p1) && PointInOrOn(px, p3, p1, p2);

// Check intersection point
vec3 IntersectPlane(Ray ray, vec3 p1, vec3 p2, vec3 p3) {
    // Direction
    vec3 D = ray.Dir;

    // The normal vector of the plane can be calculated by the cross product of 2 legs of the triangle
    vec3 N = cross(p3 - p1, p2 - p1);

    // The intersection point X
    vec3 x = ray.Origin + D * dot(p1 - ray.Origin, N) / dot(D, N);
    // Return coordinate of intersect point
    return x;

// Check intersection between given line and triangle + obtain coordinate of intersect point
bool IntersectTriangle(Ray ray, vec3 p1, vec3 p2, vec3 p3, vec3 &x) {
    // Get coordinate of intersect point
    x = IntersectPlane(ray, p1, p2, p3);

    // Check intersection
    return PointInTriangle(X, p1, p2, p3);

// Main
int main() {
    // Intersection point

    vec3 x = vec3(0.0, 0.0, 0.0);
    // Triangle
    vec3 p1 = vec3(2.1, 3.0, 0.4);
    vec3 p2 = vec3(-0.5, 1.3, 4.0);
    vec3 p3 = vec3(7.0, 0.4, 4.3);

    // Line (Original)
    Ray ray;
    ray.Origin = vec3(3.6, 2.8, 2.3);
    ray.Dir = vec3(2.7, -1.0, 2.2);

    // Intersection check + obtain coordinate of intersection point
    bool rt = IntersectTriangle(ray, p1, p2, p3, x);  // Return true

    // Line (Reverse)
    ray.Origin = vec3(2.7, -1.0, 2.2);
    ray.Dir = vec3(3.6, 2.8, 2.3);

    // Intersection check + obtain coordinate of intersection point
    rt = IntersectTriangle(ray, p1, p2, p3, x);  // Return false
    return 0;

Um… isn’t it supposed to?

The simplest form of hidden surface removal has been not drawing triangles that face away from the camera, since (assuming a closed surface) such surfaces will already be blocked by some nearer triangle that faces the camera.

This is just as true for a rasterizer as a ray tracer. So most ray-triangle intersection algorithms are designed to ignore collisions when the triangle is facing away from the source of the ray.

The point returned by IntersectPlane is correct.

Because this:

    ray.Origin = vec3(2.7, -1.0, 2.2);
    ray.Dir = vec3(3.6, 2.8, 2.3);

isn’t the reverse of this:

    ray.Origin = vec3(3.6, 2.8, 2.3);
    ray.Dir = vec3(2.7, -1.0, 2.2);

It would be if you were using two points rather than a point and a direction, but you aren’t. To reverse it, use:

    Ray ray2;
    ray2.Origin = ray.Origin + ray.Dir;
    ray2.Dir = -ray.Dir;

So I’m starting to wonder whether the reason you think it’s returning the wrong point is because you’re treating ray.Dir as if it was a point on the line. It isn’t; it’s the direction of the line (i.e. the difference between two points).

The returned point isn’t on a line through Origin and Dir, it’s on a line through Origin and Origin+Dir (or more generally, Origin and Origin+k*Dir for any scalar k).

This one doesn’t.

HI @GClements,

Thanks for your input, your explanation is very helpful.
btw, is there a way for me to get intersection point between ray.Origin and ray.Dir which lies on Triangle plane?

I would like to calculate exact point of intersection, but all the algorithms I found gives me the same result that I can’t achieve my goal.
My goal is to find exact intersection point and perform Boolean operation between objects so precision is must. :sob:

Many thanks!!!

Thanks for your input, that’s very interesting…
I’m looking for algorithms which can help me to check whether the line passes through Triangles then get intersection point, so that I can do Boolean operation.

So it should be précised and not to miss any possible cases.

That isn’t meanginful. ray.Dir is a direction, not a position.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.