CPE 471 Winter 2015 Final Project
Ray Tracer - Jon Doughty
Introduction & Theory
Ray tracing is the process of creating an image by tracing paths of light through pixels in the image plane and simulating the effects of the light’s encounters with objects.
Design and Basic Implementaton
The first step in writing a ray tracing program was to be able to find intersections between rays and primitive shapes including planes and spheres. Planes can only be intersected by a ray once, but spheres can be intersected between in either once or twice. Using this information, we can calculate what the closet hit point was and return the color of that object. The image below shows the first results of the program, and orthographic sphere.
Implementing Shading with Blinn-Phong
After successfully creating the Surfaces classes Sphere and Plane and making sure all ray intersections were working properly it was time to add some perspective through shading. I decided to implement the Blinn-Phong model of shading due to my familiarity from previous project work. Lighting works by calulating the differences between the light, view and normal directions. Blinn-phong uses and additional approximation vector, halfway, which evenly splits the view and light vectors to avoid certain awkward light situations. The image below shows a sphere shaded with the Blinn-Phong shading model.
The next step was to add shadows to our environment, luckily this step is fairly easy. In order to calculate if any arbitrary point is in shadow one must calucate a ray from the point of impact towards the light(s). If the shadow ray hits any objects while headed in the direction of a light, then that point must be in shadow. If the scene has more than one light, an approximation for soft shadows can be made where the point is shaded lighter if it is in shadow from one light but not from another light.
After adding shadows, I decided to add reflections to my ray tracer. This step was a bit more tricky because it involved dealing with recursively tracing rays as they hit reflective objects in the scene. Each ray much be traced as it bounces of reflective objects, the ray gathers a variable amount of color from each additional object it hits based on that specific objects reflectivity. At a certain point the ray must be stopped due to a depth limit or it finally reaches a non-reflective object. While popping off the recursion stack, the colors are combined based on the objects reflectiveAmount property.
For example this first image has objects that are only semi-reflective:
This second image is reminiscent of a hall of mirrors, I allowed the rays to recurse to a max depth of 20 and the material for the large grey spheres is highly reflective:
This image was a road bump in the development process, but a pleasant side effect. What is happening in the image is that the reflected rays are hitting the object they are bouncing off of causing the noise. The solution was to make sure all reflected rays began a small distance away from the surface from which they are being reflected:
The final featue I implemented was anti-aliasing. The basic idea of this concept is to create smooth edges by shooting more rays per pixel and averaging the colors of all the rays for that pixel. This feature really helps smooth out the edges of the spheres when they are rendered at lower resolutions of say 400x400. I implemented a control that allows the user to define how many rays should be used per pixel. At resolutions of 400x400 the using roughly 36 rays per pixel resulted in a decent rendering. This was especially useful for rendering scenes with multiple reflective objects.
For example in the following image the colored spheres are slightly reflective, the large sphere is supposed to be chrome-like so it is more reflective and the floor is a full mirror reflection:
Does anyone ever finish writing a ray tracer? The following is a list of additional features I would like to implement.
- Additional geometric primitives: triangles, cubes, tori, etc.
- Refraction via Snell's or Beer's Law.
- Better lighting: area lights, spotlights, attenuation.
- More realistic shadows via soft shadows.
- Multi-threaded rendering.
Great chapter on ray tracing
Helpful large scale algorithm for development
Tutorial by Codermind team