This ray tracer
was written in C++ from scratch for
the Computer Graphics assignment. The SDL is used for presenting
the images to the user. The following
primitives are supported: spheres, planes and sphereflakes (which were added
to obtain reasonable comparison of the ray tracing acceleration
algorithms).
As part of the assignment the following features were implemented:
 shadows
 reflections

ray tracing acceleration:
 per object axis aligned bounding boxes (AABB)^{1}
 bounding volume hierarchy (BVH)
Shadows implementation
At each intersection point, a shadow
ray is shot towards each light source and the contribution of this lightsource is
taken into account if the shadow ray does not intersect any other objects along
its path.
In order to avoid surface acne (black spots on the surfaces of objects due to
numerical imprecisions leading to incorrect selfshadowing) any intersections
near the ray origin are discarded.
Reflections
Reflections are rendered by recursively tracing secondary rays, when an intersection with a reflective object occurs. A maximum recursion limit is used to
avoid infinite recursion.
Ray tracing acceleration
Axis aligned bounding boxes are calculated for each object during initialisation.
The rayobject intersection functions test the ray against the object's bounding
box before calculating intersections with the object itself.
Because the scenes are made out of very simple primitives which are trivial to
intersect a new arbitrarily complex primitive was introduced: the sphereflake
fractal.
In order to further improve rendering performance, a hierarchy of axis aligned
bounding boxes was constructed for the superflake.
Tests conducted
The rendering meantimes where calculated by taking 12 measurements,
removing the 2 outliners and averaging the rest.
Test 1: Brute force ray tracing vs BV for primitive objects
A scene with planes and spheres was rendered with per object bounding
boxes (AABB) and then without bounding boxes (brute force ray tracing).
The mean rendering times when the AABB algorithm was used were:
 1686 miliseconds (when 512x512 images were rendered)
 6728 miliseconds (when 1024x1024 images were rendered)
The mean rendering times when brute force ray tracing were used were:
 1729 miliseconds (when 512x512 images were rendered)
 6949 miliseconds (when 1024x1024 images were rendered)
Per object bounding box is marginally faster than brute force ray tracing.
Test 2: Brute force vs BV for objects with more complex
primitives
A scene with planes, spheres and a sphereflake with 4 iterations (259 spheres)
was rendered with per object bounding boxes and then without bounding boxes
(brute force ray tracing). The render mean times where:
 13711 miliseconds when bounding boxes were used
 33454 miliseconds when brute force ray tracing was used
The test conducted by rendering 512x512 images.
Test 3: BVH vs BV
A scene with planes, spheres and a sphereflake with 4 iterations (259 spheres)
was rendered with BHV and per object bounding boxes. The
render mean time was:
 4285 miliseconds when BVH was used
 113711 when per object bounding boxes were used
The test conducted by rendering 512x512 images. The BVH was significally
faster than per object bounding box.
Test 4: BVH vs BV for very complicated objects
The previous scene but with a sphereflake with 8 iterations (335923 spheres)
was rendered.
 BVH rendering time: 81393 miliseconds
 BV rendering time: more than 24 hours
Code:
The code can be downloaded from here and it runs on Linux.
You must specify a scene description file.
Notes:
1. An axisaligned bounding box, or AABB for short,
is a box aligned with coordinate axes and fully enclosing some object.
Because the box is never rotated with respect to the axes, it can be defined
by just its center and extents, or alternatively by min and max points.
Back to top
