Simple shadowing is extremely easy to implement once a basic lighting model has been put into place. We already find the initial intersection of our camera ray with the nearest object in the scene. From here, we create a simple "shadow ray" -- a ray with origin at the aforementioned intersection point and direction toward the current light. If this shadow ray intersects another object prior to finding the current light, our point is in shadow and we do not need to add any color from the light.
// Form the ray from point -> light
Vector dst_to_light = light->getPosition() - point;
Ray *shadow_ray = new Ray(point, dst_to_light);
shadow_ray->normalize();
// Does the ray intersect an object?
Intersection *shadow_int = getIntersection(shadow_ray);
if(shadow_int != NULL)
// Skip this light
else
// Continue coloring
The shadowing implemented here is very basic. It makes the assumption the binary assumption that a point is either shadowed or not. This is called hard shadowing, and makes sense if we are only dealing with point light sources. Its counterpart, soft shadowing, deals with area light sources and is significantly more realistic.
Soft shadows take into effect the umbra and penumbra of a shadow. Points in the umbra cannot see any part of the area light, while portions in the penumbra can see at least part of the light source. Furthermore, the antumbra is described in the image below (source: Wikipedia). Note that the example shows the sun as an area light source; even though it is rather far away, it still has significant angular extent.
Even with soft shadows implemented, we are poorly approximating the rendering equation. Later, we will cover radiosity and photon mapping. Later. Much later.