I am struggling massively with an assignment where I am supposed to implement a raytracer. I have a basic raytracer done but I have almost no idea how to implement shadows. I will include some of the functions we have to program and some of the data structures we are given. I think I know in theory on what to do but I am completely clueless on how to implement any of this properly.
void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
Ray3D shadowRay;
for (;;) {
if (curLight == NULL) break;
// Each lightSource provides its own shading function.
// Implement shadows here if needed.
if (!ray.intersection.none) {
shadowRay.origin = ray.intersection.point + 0.01 * ray.dir;
shadowRay.dir = (curLight->light->get_position() - ray.intersection.point);
shadowRay.dir.normalize();
}
curLight->light->shade(ray);
curLight = curLight->next;
}
}
}
Colour Raytracer::shadeRay( Ray3D& ray ) {
Colour col(0.0, 0.0, 0.0);
traverseScene(_root, ray);
// Don't bother shading if the ray didn't hit
// anything.
if (!ray.intersection.none) {
computeShading(ray);
col = ray.col;
}
// You'll want to call shadeRay recursively (with a different ray,
// of course) here to implement reflection/refraction effects.
return col;
}
struct Intersection {
// Location of intersection.
Point3D point;
// Normal at the intersection.
Vector3D normal;
// Material at the intersection.
Material* mat;
// Position of the intersection point on your ray.
// (i.e. point = ray.origin + t_value * ray.dir)
// This is used when you need to intersect multiply objects and
// only want to keep the nearest intersection.
double t_value;
// Set to true when no intersection has occured.
bool none;
};
// Ray structure.
struct Ray3D {
Ray3D() {
intersection.none = true;
}
Ray3D( Point3D p, Vector3D v ) : origin(p), dir(v) {
intersection.none = true;
}
// Origin and direction of the ray.
Point3D origin;
Vector3D dir;
// Intersection status, should be computed by the intersection
// function.
Intersection intersection;
// Current colour of the ray, should be computed by the shading
// function.
Colour col;
};
endif
We are supposed to implement shadows in computerShading, although I trhink we have to do something in shadeRay as well but I am not really sure. I am not sure whether in computerShading I am supposed to calculate the ray intersectiion or create a new ray before I calculate the ray intersection or after or I must computer the new ray first and calculate the intersection. We also have a colour function. I also implemented some intersection functions for a unit square and sphere, both work, but I just don't understand how to get shadows! I am just really really lost. Please any help would be great!
EDIT: Okay so I added some stuff but I am not getting any shadow or I am getting a complete black image depending on the change of parameters:
void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
for (;;) {
Ray3D shadowRay;
if (curLight == NULL) break;
// Each lightSource provides its own shading function.
// Implement shadows here if needed.
shadowRay.origin = ray.intersection.point + 0.01*ray.dir;
shadowRay.dir = curLight->light->get_position() - ray.intersection.point;
shadowRay.dir.normalize();
traverseScene(_root, shadowRay);
if (shadowRay.intersection.t_value >= 0.0 && shadowRay.intersection.t_value <= 1.0) {
shadowRay.col = Colour(0,0,0);
}
else {
curLight->light->shade(ray);
}
curLight = curLight->next;
}
}
Where traversescene goes through every object and does the intersection and puts the proper value. Maybe I didn't put this stuff in the proper area.