(Task 4) Shadow Rays
In this task you will modify Pathtracer::trace_ray to implement accurate shadows.
Currently Pathtracer::trace_ray computes the following:
- It computes the intersection of ray
rwith the scene. - It computes the amount of light arriving at the hit point
hit.position(the irradiance at the hit point) by integrating radiance from all scene light sources. - It computes the radiance reflected from the hit point in the direction of
-r. (The amount of reflected light is based on the BSDF of the surface at the hit point.)
Shadows occur when another scene object blocks light emitted from scene light sources towards the hit point. Fortunately, determining whether or not a ray of light from a light source to the hit point is occluded by another object is easy given a working ray tracer (which you have at this point!). You simply want to know whether a ray originating from the hit point (hit.position), and traveling towards the light source (direction to light) hits any scene geometry before reaching the light.
Your job is to implement the logic needed to compute whether hit point is in shadow with respect to the current light source sample. Below are a few notes:
-
Get yourself oriented in the starter code by taking a look at
Pathtracer::trace_rayinsrc/student/pathtracer.cpp. Notice that the code, after finding a hit, loops over all light source accumulating radiance. (look for the comment// loop over all the lights and accumulate radiance). For each light the lambda functionsample_light()is invoked, and in that function the key line is the line that adds radiance into the variableradiance_out. This code is the code where the refection equation is being evaluated. -
In the starter code, notice that when the code calls
light.sample(hit.position), it returns the caller aLight_sample sample. (You might want to take a look atrays/light.hfor the definition ofstruct Light_sampleandclass light.) ALight_samplecontains the fieldsradiance,pdf,direction, anddistance. In particular,sample.directionis the direction from the surface hit point to the point on the light source being sampled, andsample.distanceis the distance from the hit point to the light sample. Given this information, all you need to do is determine if there is any scene geometry closer than that sample point. -
A common ray tracing pitfall is for the “shadow ray” shot into the scene accidentally hits the same object as
rdid. (The surface is erroneously determined to be occluded because the shadow ray is determined to hit the surface itself!). We recommend that you make sure the origin of the shadow ray is offset from the surface to avoid these erroneous “self-intersections”. For example, consider setting the ray’sdist_boundsappropriately to avoid hits with very smalltvalues, or adjust the origin of the shadow ray to behit.position + epsilon * sample.directioninstead of simplyhit.position.EPS_Fis defined in for this purpose (seelib/mathlib.h). - Another common pitfall is forgetting that the surface is not in shadow if the shadow ray hits scene geometry after reaching the light. (Also note that
Rayhas a member calleddist_bound…) - You will find it useful to debug your shadow code using the
DirectionalLightsince it produces hard shadows that are easy to reason about. - When you get started on Task 4, comment out the line
Spectrum radiance_out = Spectrum(0.25f);and initialize theradiance_outto be the correct value. Hint: is there supposed to have any light before we even start considering each light sample?
At this point you should be able to render very striking images with shadows.
Sample results:
At this point, you can add all kinds of lights using “New Light” in Layout mode, except for Sphere Light and Environment Map which you have the option to implement later (Note that you can still fill in Sphere::Uniform::sample in Samplers.cpp now to view the result of a mesh under Sphere Light). Here are some examples:
A sphere and a cube with hemishphere lighting

Hex and cube under diretional lighting

Bunny on a plane under point light

Spot on a sphere under diretional lighting

Spot on a sphere under hemisphere lighting
