comp870 - Assignment 2

Overview

In this assignment, I implemented area light sources for soft shadows, glossy reflections, and ambient occlusion. All of these methods stochastically sample a large area. Unless otherwise mentioned, no super-sampling was used when rendering these images. Also, unless mentioned, all of these effects adaptively stop sampling as the result converges to a value.

The code and data for the project is available here.

Soft Shadows

Soft shadows are shadows that have a large penumbra. This is caused by light sources that have finite area. In the penumbra, only a fraction of the light surfrace may be visible, thus only some percentage of the light energy reaches the area in the penumbra.

By stochastically sampling the surface area of the light, the percent of visibility can be calculated. For this assignment, I implemented disc-shaped area lights. When calculating the shadow at some intersection point, I generate random points on the disc surface. For each point on the light, an occlusion test is performed. If the light is unoccluded, it contributes some energy to the intersection point.

Adaptivity Variance
Every few sampling cycles, the change in the shadow value is compared against an epsilon. If the difference between the old shadow value and the new shadow value is less than epsilon, the shadow is deemed to have converged to an answer and sampling is stopped. Smaller epsilons give more accuracy, but require more compute time. Pseudocode for the method is presented below.

for 0::num_samples
   new_sample = get_sample()
   sample_accum += new_sample

   if(time_to_check)
      if(sample_accum - old_accum < epsilon)
         return sample_accum
      else
         old_accum = sample_accum
      end
   end
end
Settings:
radius: 50
max samples: 500
check every: 50
epsilon: varies
variance: 0.1
time: 41.63s
image
variance: 0.01
time: 48.86s
image
variance: 0.001
time: 58.98s
image
Number of Samples
The total number of samples can be varied to adjust between accuracy and performance. For these test, no adaptivity was used. Clearly, increasing the number of samples improves the resulting shadow, but greatly increases the rendering time.


Settings:
radius: 50
max samples: 500
check every: N/A
epsilon: N/A
num samples: 5
time: 5.10s
image
num samples: 50
time: 37.45s
image
num samples: 100
time: 73.48s
image
num samples: 500
time: 361.71s
image
Radius
Since the area of the light is sampled, the adjusting the size of the light source results in different types of shadows. As light sources become smaller, the penumbra becomes smaller and the shadow edges become harder.

Settings:
radius: varies
max samples: 500
check every: 50
epsilon: 0.001
radius: 5
time: 38.93s
image
radius: 50
time: 59.26s
image
radius: 100
time: 80.51s
image

Glossy Reflections

Glossy reflections are reflections that do not reflect like mirrors, but rather reflect a blurred image. Samples are perturbed in a cone about the perfect reflection vector. As the cone radius spreads out, the resulting image is blurrier. As the spread becomes larger, more samples are needed to overcome noise.

Settings:
spread: varies
max samples: 500
check every: 50
epsilon: 0.001
spread: 10
time: 7.56s
image
spread: 20
time: 9.04s
image
spread: 40
time: 12.22s
image
spread: 80
time: 18.34s
image

Ambient Occlusion

Ambient occlusion is a non-physically based effect that approximates a global illumination look. It attempts to estimate how occluded a point is by sampling the hemisphere about the point. If many objects are found, it is likely that they would block the ambient light in the scene, thus reducing the light energy at the point.

Settings:
max samples: 500
check every: varies
epsilon: 0.001
check: 5
time: 54.55s
image
check: 20
time: 156.83s
image
check: 50
time: 273.35s
image

Other

Adaptive Stochastic Sampling

Cost to adaptively calculate the soft shadows.

Darker areas needed less samples, lighter areas needed more. As shown in the image, points in regions where the light is either entirely visible or occluded require the fewest samples. This is intuitive, as the shadow amount converges with few samples to the desired result. Shadow penumbra require the highest number of shadow rays, as occasional occlusions cause the result to converge slower.


Occlusion Caching

Simple occlusion caching by recording occluding objects.

colormeaningsingle rayfull test
red cache was emptyx
green cache hitx
yellow cache missxx
blue cache updated?x
Each time a shadow ray is found to be occluded, the object that caused the occlusion is cached. Cached objects are tested first for occlusion before testing other objects in the scene. Since shadow rays tend to be coherent, this results in fewer tests being needed. Rendering data for the Cornell Box scene with soft shadows is provided below.

with cache: 41.31s, 215.3 million intersections
no cache: 55.56s, 295.4 million intersections


All effects

All effects rendered together.

This image shows soft shadows, glossy reflections, and ambient occlusion. Even with medium-quality settings, this image required ~40 minutes to render.

Conclusions

While expensive, these effects add much more realism to the scenes. They help to soften the hard edges often found in raytraced scenes, replacing them with more acceptable noise. While the expense of the sampling could be mitigated by using acceleration structures, there still remains a high cost per pixel due to the number of samples needed to reduce noise (especially ambient occlusion).