• Advertisement
Sign in to follow this  

Ray-Triangle intersection/Raytracing problem

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
Share on other sites
Quote:
Original post by Melekor
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.


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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement