Features List

We implemented the following features in our ray tracer.

Lighting

We implemented four different types of light, Ambient Light, Point Light, Directional Light and Spotlight. Ambient light accounts for the uncalculated light in the scene, spotlight resembles theatre lights which emits light in a cone, point light emits light in all directions while directional light only emits in a specified direction.

Materials

We implemented phong material model which can be used to produce many different types of materials just by changing the specular and diffuse component. For perfectly specular materials, the diffuse component is zero, while for perfectly diffuse or matte material, the specular component is zero. A combination of specular and diffuse components produces phong material.

Acceleration Structures

We implemented two acceleration structures, Regular Grids and BVH (Bounding Volume Heiarchy). We conducted tests on regular grids only as BVH had some issues when it came to rendering the final scene due to the high number of primitives. Both structures gave huge boosts in speed due to which we were able to render high resolution scenes with thousands of primitives keeping quick render times.

Camera

We implemented both parallel as well as perspective viewing in our raytracer.

Image reading and writing

We extended our image class so that in can not only write final images but also read .ppm images for texture information.

Primitives

Our raytracer supports planes, triangles (flat as well as smooth), and spheres as the basic geometric primitives.

Bonus Features

A complete list of implemented bonus functionalities is given below.

OBJ Loader

Our ray tracer supports loading scenes as .obj file. A mesh or any scene consisting of multiple meshes can simply be first exported to .obj format through a 3D software and can then simply be loaded into our ray tracer. Our raytracer can also read material information from generated .mtl files along with the .obj.

Blender Correspondence

We used Blender for modelling and exporting our concept scene, and having to constantly figure out co-ordinate transformations proved to be quite a grunt hassle. Therefore, we settled this by establishing a one-to-one mapping with Blender's default viewing co-ordinates. A 3D-coordinate (x, y, z) in the default Blender space gets mapped to (x, -z, -y) in our raytracer space. Because of this, any scene that can be viewed in Blender can be directly loaded as an .obj in our raytracer without any worry of co-ordinate transformations.

Shadows

All our implemented light sources support shadows through the concept of secondary ray generation as per the book. This results in beautiful and realistic renders - as documented ahead.

Texture Mapping

Our ray tracer also supports texture mapping. Models in Blender that have an image texture wrapped can simply be exported and loaded into our scene using the texture properties in the implemented Phong material - with the only extra cost of converting the image texture to .ppm format. This is done through using the UV unwrapping information in the .obj file which is generated by Blender. This feature can be easily extended to incorporate normal and bump mapping since most of the functionality will overlap.

Anti-Aliasing

For smoothing out jaggies, we implemented a jittered sampler in our raytracer. The principle it operates on is that multiple rays are shot per pixel instead of one, producing a much nicer interpolation in the colors assigned to each pixel. This can be best scene in action in the final render presented above.

Smooth Shading

Our ray tracer supports both flat and smooth shading. In flat shading, the primitive triangle has a single normal, causing the mesh to appear "flat". In smooth shading, the primitive triangle is tweaked such that each triangle vertex possessess its own normal vector, which is then interpolated to better represent smooth surfaces as triangle meshes.

Multithreading

Our main raytracing loop also takes use of multithreading. This was done simply using the OpenMP library for C++, and this resulted in even quicker render times - on top of the acceleration structures.

Lighting

Following images are generated in different lighting environments.

Materials

Following images are generated with different types of materials.

Smooth Shading

These two images compare the Shrek triangle mesh with flat and smooth shading. In flat shading, each triangle has a constant normal, causing each triangle to appear "flat". In smooth shading, the normal of each triangle varies based on the normals of the adjacent triangles, creating a smoother appearance. This allows us to better represent smooth surfaces as triangle meshes.

Shrek with flat shading

Flat Shading

shrek with smooth shading

Smooth Shading

Shadows

These two images show the shadows generated in different lighting.

shadow with spotlight

Shadow with Spotlight

shadow with spotlight and directional light

Shadow with Spotlight and Directional light.

Anti-aliasing

These two images compare the scene rendered with anti-aliasing off and anti-aliasing on. With anti-aliasing on, the sharp edges gets smoother.

Simple Sampler with no Anti-aliasing

Simple Sampler with no Anti-aliasing

Jittered Sampler with Anti-aliasing

Jittered Sampler with Anti-aliasing

OBJ Loader

To import meshes into our scene, we first generate a .obj file. The .obj file is then imported in our raytracer, which has been coded to reflect an exact one-to-one mapping with Blender's default viewing co-ordinates. A 3D-coordinate (x, y, z) in Blender space gets mapped to (x, -z, -y) in our raytracer space, as explained previously. This is a pigeon model downloaded from Windows 3D viewer in .fbx format. It was then exported to blender to export a .obj along with .mtl file for material information. This image shows a render of this model through our ray tracer with beautiful blue and white spotlights.

Texture Mapping

These two images show shrek rendered along with textures with flat and smooth shading.

Textured Shrek with flat shading

Textured Shrek with Flat Shading

Textured Shrek with smooth shading

Textured Shrek with Smooth Shading

Acceleration Structures

The following tables compare the render times of our ray tracer with and without acceleration grids. The rendering was done on a hardware with following configurations:

  • Processor i7-5700HQ 2.7 Ghz
  • RAM: 8 GB
  • System Type: 64-bit Operating System
  • Number of Cores: 4

Comparison Times

Acceleration Structure Number of Primitives (triangles) Image Size Time taken (in seconds)
Regular Grid On 15,178 1024 x 1024 5.539991
Regular Grid Off 15,178 1024 x 1024 1236.096242
Regular Grid On 15,178 100 x 100 0.111991
Regular Grid Off 15,178 100 x 100 12.079617
Regular Grid On 60,712 100 x 100 0.166598
Regular Grid Off 60,712 100 x 100 49.082720
Regular Grid On 242,848 100 x 100 0.380353
Regular Grid Off 242,848 100 x 100 200.939594

Build Files

Following are the build files used for creating different images. These build files can be found in the build folder.

buildShrek.cpp

This scene consists of a 3D model of shrek. Use smooth and texture flags to generate an image with flat/smooth shading or with/without texture.

buildWhitePigeon15k.cpp

This scene consists of a 3D model of a white pigeon. Use smooth and texture flags to generate an image with flat/smooth shading or with/without texture. This scene contains 15,178 primitives.

buildWhitePigeon60k.cpp

This is the same scene as buildWhitePigeon15k.cpp but contains 60,712 primitives.

buildWhitePigeon200k.cpp

This is the same scene as buildWhitePigeon15k.cpp but contains 242,848 primitives.

buildHWJittered.cpp

This scene is same as buildHelloWorld.cpp modifed to produce an image with anti-aliasing.

buildHWSimple.cpp

This scene is same as buildHelloWorld.cpp modifed to produce an image without anti-aliasing.

buildFull-highres.cpp

This is our main scene in high resolution.

buildFull-lowres.cpp

This is our main scene in low resolution.

buildSword.cpp

This scene consists of a sword model exported from blender.

buildHelloWorld.cpp

This scene was already provided, but we modified it to test different lights and materials effect.

Other Renders

The following renders have all been generated by our raytracer; however they didn't make it through as the final concept.

Our Team

We all are Computer Science Majors at Habib University of class of 2020. This ray tracer engine was developed as the final project of our course Computer Graphics offered by Dr.Waqar Saleem.

Credits

The textbook, "Raytracing from the Ground Up", by Kevin Suffern and the accompanying code snippets.
3D Models from Microsoft and sketchfab.com
Bly7's OBJ Loader from Github
Libing Zeng's raytracer for texture mapping from GitHub
The textbook, "Mathematical Tools in Computer Graphics with C# implementations", by Alexandre Hardy for Spot Lights
Professor Waqar Saleem, the course instructor, for his continuous help and for offerting this awesome course.
Ahmed Bilal, the projects lab RA, for allowing us to stay late in the lab for the project