This repository contains my two implementations of The Ray Tracer Challenge. One of the implementations was written in Scheme (portable R7RS) to test the Scheme interpreter I am working on. The other implementation was written in Rust, whose superior performance allowed me to play with a few additional features.
- The basic ray tracer from the book
- write to PNG format
- Height fields
- Adaptive multisampling
- Area lights and soft shadows
- Depth of field
- Photon mapping
Although adaptive multisampling is a very simple technique, it greatly facilitates eye candy effects like anti-aliasing, soft shadows, and depth of field. Thus, it deserves a bit of an explatation...
The idea is simple:
- Randomly shoot a few rays through the area covered by a pixel.
- Compute the variance of the rays' resulting colors.
- Keep shooting more rays until the standard error of the average color falls below a chosen threshold.
Only few rays are cast for low variance pixels and as many rays as required are cast for high variance pixels. High variance pixels include, for example, edge pixels. Some rays through an edge pixel will hit an object, some rays will miss it. The more rays are hit by the object the more it contributes to the final pixel color. Thus, adaptive multisampling naturally gives rise to an anti-aliasing effect on edges.
Similarly, the implementation of soft shadows cast by area lights becomes beautifully simple. From the point being shaded, we simply cast a single light ray to a random point on the light's surface. If the point is partially shadowed its color has high variance and adpative multisampling takes care of casting the required number of rays.
The following images were rendered with the Rust implementation of the ray tracer.