Assignment 2 - Stochastic Raytracing

General Sampling Approach

Central to stochastic rendering is creating good random samples. As with other Monte Carlo methods, stratification greatly reduces the variance. For each pixel I generate a set of jittered  samples in the domain [0,1] x [0,1].  I use the samples directly as subpixel sample locations for eye rays. I reuse the samples for other dimensions, utilizing a permutation table (also generated once per pixel) in order to eliminate correlation between samples.

I do not branch the ray tree. That means that if I want 64 shadow rays I need to send 64 eye rays. This greatly simplifies the task of stratifying samples. It also means that I can sample many different effects in the same scene with very little increase in computation time. All of these scenes use soft shadows and anti-aliasing. For toy scenes like those generated for this assignment a lot of rays are wasted sampling smooth areas. It might be worth trying a multistage approach for stratification. For instance I could sample the image plane with 4 rays and then cast 16 more rays from a single intersection point to evaluate soft-shadows, glossy reflection etc. After the first intersection of the scene I would not branch the ray tree and I could continue to sample the higher dimensions as I do now.
 

Soft Shadows

To generate soft shadows I create uniform samples on a convex polygonal light source as described by Greg Turk in  "Generating Random Points in Triangles" in Graphics Gems.
 
 

64 samples / pixel - 5 minutes



Glossy Reflections

For glossy reflections I transformed uniform random samples into a cosine lobe distribution centered around the reflection direction. This image shows a glossy plate split down the middle. The left side is glossy while the right side is perfectly reflective.
 
 

64 samples / pixel - 6 minutes



Translucency

This effect is generated using the same cosine lobe distribution as I used for reflection, except it is centered around the transmission direction. Once again, the left half of the plate is translucent while the right side is perfectly transmissive.
 
 

64 samples / pixel - 7 minutes


Depth of Field

To create the depth of field I choose a position on a virtual lens. I perturb the origin of the eye ray while constraining the direction such that the ray still passes through the same point at the focal length as the original ray. To generate samples on th lens I warp a uniform 2D random variable to a uniform disc distribution.
 
 

64 samples / pixel - 7 minutes



Texture Mapping

Texture mapping significantly enhances the realism of a scene. It is a texture-mapped sphere on a plane textured with a procedural checker/marble shader. I do not filter the texture look-ups at all. You can notice some pixelation occuring, especially near the crown of the parrot's head. The procedural texture is pretty expensive to evaluate. While very simply geometrically, this scene took the longest to generate.
 
 

64 samples / pixel - 19 minutes


Stochastic Cow Effect

This image shows cow particles arranged stochastically about a teapot primitive. The models are made up of triangle meshes. I used grids with uniform hierarchical voxels to accelerate intersection tests. Notice the subtle shadowing at the base of the objects. This is due to a very large area light source used to simulate skylight.
 
 

36 samples / pixel - 12 minutes



Code

This code is in constant evolution. I have been playing with it for some time now seeking a satisfactory design. I recently encountered an unpublished manuscript for a book called A Literate Raytracer  by Matt Pharr, Greg Humphreys, and Pat Hanrahan that has a design I really like. I have adopted portions of their design. I will continue to refining the code a lot over the next few projects.