Ray Tracing: Shadows

Shadows are the first place where ray tracing has an advantage pipelined graphics (OpenGL). Not that shadows in pipelined graphics are impossible, but they can be a bit of a struggle (or at least they have been for me.) But as we’ll see: with ray tracing they’re actually quite pleasant.

We actually already have everything we need with the castback idea; we just need to extend them a bit so that we give shaders empty castbacks when the path to the light is blocked. What’s great is that we already have exactly that function built in, it’s the same function we use to intersect the scene. Here’s what the castback construction code looks like:

light_castback :: Scene -> Intersection -> Light -> Light_Castback
light_castback scene (Intersection _ inter_loc _ _ _) (Point light_loc color intensity) =
    if ((miss scene_xn) || light_t < (t scene_xn))
    then (Light_Castback (light_loc <-> inter_loc) color intensity)
    else empty_light_castback
    where ray = (ray_from_to inter_loc light_loc)
          scene_xn = (intersect_scene scene ray) --intersection with the scene
          light_dir = (light_loc <-> inter_loc)
          light_t = (len light_dir) --parameter at which we hit the light

Simple enough: we intersect with the scene and if the intersection is closer the to castbacks origin than the light we’re aiming at, we have an empty castback. So let’s see how it works:

Something is very wrong.

Hmm, not so well at all, although that is a cool looking bug. This type of effect is generally called surface acne and it’s normally down to a floating point error somewhere. In this case the problem is that the castback ray that I shoot out is, depending on roundoff errors, hitting or missing the object whose illumination we’re computing (the object it originally hit.) The easiest way to solve this is to just nudge the ray’s origin points off of the objects they’re intersecting using a function like this:

epsilon = (10 ** (-4))
nudge :: Ray -> Ray
nudge ray = (Ray (ray `at` epsilon) (dir ray))

Bug fixed.

Comments are closed.