PDA

View Full Version : Raytracer - Triangle Intersection + Normals



twoski
04-09-2014, 11:56 AM
So i have written a basic raytracer which so far is functional with spheres. However i am extending its functionality to also work with meshes, which means implementing triangle intersections.

I found the general logic of triangle intersections and implemented it easily enough, however i am not quite sure how to calculate the intersection normals.

Here is the code i have written for spheres.




bool sphereIntersection(Ray *ray, Sphere *sphere, Intersection* intersection)
{
double discriminant;
double dirDot, rayDot, radDot;
double lambda1, lambda2;
TVector temp;

dirDot = ray->direction | ray->direction;
temp = ray->origin - sphere->center;

rayDot = 2 * (temp | ray->direction);
temp = ray->origin - sphere->center;

radDot = (temp | temp) - (sphere->radius * sphere->radius);

discriminant = rayDot * rayDot - 4 * dirDot * radDot;

intersection->valid = false;

if (discriminant >= 0)
{
lambda1 = (-rayDot + sqrt(discriminant)) / (2 * dirDot);
lambda2 = (-rayDot - sqrt(discriminant)) / (2 * dirDot);

// is the object visible from the eye position?
if (lambda1 >= 0 && lambda2 >= 0)
{
if (lambda1 == lambda2)
{
intersection->lambdaIn = intersection->lambdaOut = lambda1;
}
else if (lambda1 < lambda2)
{
intersection->lambdaIn = lambda1;
intersection->lambdaOut = lambda2;
}
else
{
intersection->lambdaIn = lambda2;
intersection->lambdaOut = lambda1;
}

intersection->valid = true;
return true;
}
}

return false;
}

void normalOfSphereIntersection(Ray* ray, Sphere *sphere, Intersection* intersection)
{
double lambda, scale;
TVector v1, v2, point, normal;

lambda = intersection->lambdaIn;

v1 = lambda * ray->direction;
point = v1 + ray->origin;

intersection->point[0] = point[0];
intersection->point[1] = point[1];
intersection->point[2] = point[2];

v2 = point - sphere->center;

if (sphere->radius <= 0)
{
sphere->radius = 1;
}

scale = 1 / sphere->radius;
normal = scale * v2;

normal.normalize();

intersection->normal[0] = normal[0];
intersection->normal[1] = normal[1];
intersection->normal[2] = normal[2];
}

And here is my triangle intersection code:



bool triangleIntersection(Ray* ray, Triangle* tri, Intersection* intersection)
{
TVector v0 = tri->points[0];
TVector v1 = tri->points[1];
TVector v2 = tri->points[2];

TVector e1 = v1 - v0;
TVector e2 = v2 - v0;

TVector h = ray->direction * e2;

float determinant = e1 | h;

intersection->valid = false;

if (determinant > -0.00001 && determinant < 0.00001)
{
return false;
}

float inverse = 1.0 / determinant;
TVector s = ray->origin - v0;

float u = inverse * (s | h);

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

TVector q = s * e1;

float v = inverse * (ray->direction | q);

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

float t = inverse * (e2 | q);

if (t > 0.00001) // ray intersection
{
intersection->lambdaIn = t;
intersection->valid = true;

return true;
}
else // there is a line intersection, but no ray intersection
{
return false;
}
}

void normalOfTriangleIntersection(Ray* ray, Triangle* tri, Intersection* intersection)
{
//todo
}

is the normal of the triangle intersection just the normal of the triangle that is hit? Or would it be the direction in which the ray would bounce if it hit the triangle?