Ray Tracer

Development

I implemented the project together with my fellow student Basil Fierz for the ?Introduction to Computer Graphics? course at ETH during the autumn semester 2007.

Detailed Description

The features that we had to implement for the course include several different primitive types, intersection acceleration using kD-trees, reflection/refraction, different lighting models, texturing and other things that nearly every ray tracer has. Apart of this the ray tracer features some more special things.

First of all the architecture of the ray tracer has been built around shaders. To determine the colour of an object hit by a ray a shader is run. The shader to be run is determined by the material attached to the object. Shaders can feature ordinary lighting models or more complex stuff like ocean shading or normal mapping. In order to improve the data driven design the ray tracer allows those shaders to be implemented in a scripting language provided by the kaos Engine. This way an object?s appearance can be customized without changing the source code of the ray tracer.

To allow the rendering of animated scenes the ray tracer has to implement a sophisticated animation and camera model. Since rendering a movie can take possibly hours it is desirable to cache generated frames on the hard disc. The ray tracer can also be configured to either generate a series of images or to write directly a movie file.

For the end of semester contest we had to implement something special. Our entry, using this ray tracer, consisted of three different types of new scenes. First the rendering of an ocean using the statistical ocean model, second the rendering of a Doom 3 cut scene and third the rendering of a television playing a movie inside.

Technical Details

Feature List

Challenges

One of the challenges with the ray tracer was that the work had to be done besides the rest of all the studies. The far bigger challenge was that we did not focus on the performance of the ray tracer. We preferred to implement cool features. In the end we realised that we had to remove features (for example the area light) from our end of semester contest demos because we did not had the time to render the movies using them. We also had to constrain the movie to some low resolution like 480 times 320 pixels. Even using this low resolution we had a total rendering time of totally about thirty hours distributed to three 2.4 core 2 duo machines.

Screenshots

A reflecting sphere inside a room of "infinitely" reflecting mirrors

A set of doom3 models rendered with the ray tracer

A high-polygon dragon model from the set of Stanford models

Three procedurally textured horses

A sphere featuring normal mapping

Videos

Some strange camera movement around to chess pieces

Viewing the procedurally textured wooden horse from different angles

A film we created for the end of semester contest of the course. It was made using only the ray tracer and an audio editing tool

Code Sample

The code piece shown represents the main render loop. This is the place where all the pixels are colored.

//main renderloop that raytraces the given scene void Renderer::render(Scene* scene){ if (scene) { scene->getCamera()->getFilm()->AppendPicture(); scene->getCamera()->getFilm()->BeginFrame(); // Initialize Sampler Point p = scene->getCamera()->getFilm()->GetResolution(); m_sampler->init(p.x, p.y); // Initialize fields Ray ray; std::vector<Ray> shadowRays; IntersectionData* iData = 0; Sample* sample = new Sample(0,0); //reset film in camera sample->setSize( (p.x > p.y? p.x : p.y) ); scene->getCamera()->setSample(*sample); // Renderloop while (m_sampler->getNextSample(sample)) { // generate camera ray and intersect it with the scene ray = scene->getCamera()->generateRay(*sample); sample->setColor(traceColor(ray, scene, 0)); // write back the sample color scene->getCamera()->setSample(*sample); // observer update if (m_sampler->cycleComplete()) { notifyObservers(); } } //cleanup scene->getCamera()->getFilm()->EndFrame(); delete sample; } }

Related Links