# Ray-Triangle intersection/Raytracing problem

This topic is 3675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm working on adding triangles to my raytracer, it currently does planes and spheres including shading, shadows, and ambient occlusion. I've developed the code below to determine a ray's intersection point with an arbitrary triangle. Although the raw intersection is correct, the shading is wrong and a triangle will appear in-front of all other objects even when behind them. I think it's because the ray parameter 't' is getting calculated wrong, but I can't seem to figure out where. Any help is appreciated. The attached image is of a leaning-back triangle intersecting a vertical plane, as can('t) be seen, the part of the triangle behind the plane is still visible. I can provide other renders or the file I use to generate the scene if desired. The constructor for the Triangle and the hit function are copied below Triangle::Triangle(const Point3D& a, const Point3D& b, const Point3D& c) :GeometricObject(), t1(a), t2(b), t3(c) { // t1, t2, and t3 are the verticies of the triangle // Subtract points to get two sides of the triangle Vector3D v1 = t2 - t1; Vector3D v2 = t3 - t2; // ^ is cross product operator // use cross product to get the normal for the triangle n = v1 ^ v2; n.normalize(); // * is dot-product when used on vectors or anything // based on a vector (Normal, Ray) d = t1 * n; } bool Triangle::hit(const Ray& ray, double& tmin, ShadeRec& sr) const{ // t = ray * n / // (p0 * n) + d float vd = ray * n; // Origin in vector form Vector3D p0(-Vector3D(ray.o)); // Ray is parallel to triangle's plane if (vd == 0) return false; // Triangle's normal faces away from ray origin if (vd > 0) return false; float v0 = (p0 * n) + d; float t = vd / v0; // Intersection occurs before ray origin if (t < 0) return false; // ray-triangle intersection point Vector3D p(ray.o + t * ray); // Can be optimized, not for ease of debugging Vector3D v1 = t1 - p; Vector3D v2 = t2 - p; Vector3D v3 = t3 - p; Vector3D n1; // store the normal for the side float d1; // Check if the point is within the triangle // by checking which side of each edge it's on // Side 1 n1 = v2 ^ v1; n1.normalize(); d1 = p0 * n1; if (((p * n1) + d1) < 0) return false; // Side 2 n1 = v3 ^ v2; n1.normalize(); d1 = p0 * n1; if (((p * n1) + d1) < 0) return false; // Side 3 n1 = v1 ^ v3; n1.normalize(); d1 = p0 * n1; if (((p * n1) + d1) < 0) return false; // kEpsilon is a very small positive value // used to avoid shading errors due to // floating point precision if (t > kEpsilon) { tmin = t; sr.normal = n; sr.localHitPoint = ray.o + t * ray; return true; }else { return false; } }

##### Share on other sites
I think your normal is backwards. This is probably what you meant to write:

v1 = t2 - t1;
v2 = t3 - t1;

I didn't read the rest of the algorithm thoroughly, but why don't you give that a try first.

##### Share on other sites
Quote:
 Original post by MelekorI think your normal is backwards. This is probably what you meant to write:v1 = t2 - t1;v2 = t3 - t1;I didn't read the rest of the algorithm thoroughly, but why don't you give that a try first.

Renders the same, still wrong. The shape is right, but it's unshaded and not occluded by nearer objects

##### Share on other sites
float vd = ray * n;...float v0 = (p0 * n) + d;float t = vd / v0;

This seems a bit off...
the distance of a point at parameter t along the ray from the triangle's plane would be v0 + t*vd. When the ray hits the plane, this should be 0. So:
   v0 + t*vd = 0=> t*vd = -v0=> t = -v0 / vd

Haven't read further after that, hth.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 10
• 11
• 13
• 9
• 11
• ### Forum Statistics

• Total Topics
634087
• Total Posts
3015444
×