CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Dec 2008
    Posts
    1

    Ray-Triangle intersection/Raytracing problem

    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;
    }

    }
    Attached Images Attached Images  
    Last edited by Bjartr; December 24th, 2008 at 08:24 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured