For our final project we wanted to render a fun scene that also utilized advanced topics from the course. We worked on each piece of the project together, contributing equally.

Inspiration

Our biggest inspiration for this project was our imagination. We wanted to do something fun, and so we did some exploring online for models to use. Upon stumbling across a model of the Android OS mascot, we started to explore ideas using this character.

first android

We were also inspired by previous years images of glossy chessboards and decided to experiment with ideas for Androids as chess pieces.

android chess Android with balloon

Modeling

After deciding on creating an Android chess scene, we proceeded to acquire models of various weapons and accessories. The scene was put together using Blender, resulting in a final count of 538908 triangles. It was fun to learn how to use Blender, and it would have been much more to difficult to construct our scene if we did not have Blender at our disposal.

Blender modeling in Blender

Lighting

Distributed ray tracing was essential to achieve the lighting effects that we wanted. For direct illumination we used used multiple rays to sample our spherical area light sources. This allowed us to render soft shadows cast by the various objects in our scene. We also implemented specular highlights to achieve the metallic look for the weapons and helmets.

shadows various shadows

For indirect lighting we implemented photon mapping. In our scene we emit 1 million photons from both of our two light sources, resulting in a total of 2 million global photons. This helps to brighten areas of the scene that are in shadow, providing a more realistic look.

photon map global photon map

We also implemented glossy reflections that can be seen on the chessboard and the helmets. This was accomplished through distributed ray tracing by tracing multiple rays over a solid angle around the direction of perfect reflection. As can be seen in the chessboard, this results in a nice effect where objects that are closer to the reflective surface (e.g. the Androids' legs) can be seen more clearly than objects that are farther away.

glossy reflection glossy reflection

Depth of Field

We implemented depth of field by sampling each pixel using multiple primary ray origins randomly distribued around a disc (the camera lens) that converged at a specified focal distance. We used 49 samples per pixel to smooth the noise resulting from this implementation. It added a nice effect where characters toward the front of the scene and those in the back are slightly out of focus.

depth of field dramatic depth of field

Gamma Correction

When we put our final scene together with our two light sources, we noticed that some colors were too bright and others were too dark. To help balance the colors in our rendering we applied some slight gamma correction.

without gamma correction without gamma correction

Multi-Threading

To help speed up the rendering time of our project, we decided to implement multi-threading using Pthreads. For our approach we decided to assign a thread to render each line, essentially interleaving the rendering process. For example, when using 8 threads, one thread would render lines 0, 8, 16... another would render lines 1, 9, 17... and so on. The machine we used allowed for the simultaneous execution of 8 threads, and testing confirmed that 8 threads indeed provided the optimal performance. We were able to achive roughly a 5x speed increase.

Final Results

Our final implementation used 49 samples per pixel, resulting in the tracing of 12.37 billion rays over 5.3 hours! BATTLE ON!

final rendering final rendering