CS 6620 - Fall 2017 - Ray Tracing for Graphics

Project 1 - Ray Casting

In this project we will begin writing a ray tracer. The input will be an XML file describing the scene and the output will be an image in PPM format. Source code for reading the scene file is provided.

Requirements

XML Scene Format

Here we define a basic XML format for describing the scene. Upcoming projects will have additional descriptions and we will define them as we need them.

Here is an example scene file:

<xml>
  <scene>
    <object type="sphere" name="sphere1">
      <scale value="25.0"/>
      <translate x="0" y="50" z="-25"/>
    </object>
    <object type="sphere" name="sphere2">
      <scale value="5.0"/>
      <translate x="0" y="50" z="5.1"/>
      <object type="sphere" name="sphere3">
        <scale value="0.2"/>
        <translate x="0" y="0" z="1.2"/>
      </object>
    </object>
  </scene>
  <camera>
    <position x="0" y="0" z="0"/>
    <target x="0" y="20" z="0"/>
    <up x="0" y="0" z="1"/>
    <fov value="40"/>
    <width value="800"/>
    <height value="600"/>
  </camera>
</xml>

Notice that all the objects are declared inside the "scene" tag with an "object" tag. The only object type we will have in this project is "sphere" which denotes a unit size (radius = 1 unit) sphere centered at the origin. The object transformations can be translate, rotate, and scale (in this project translate and scale only) that are declared under the object tag. The transformations are applied in the order that they appear in the XML file. Multiple "scale" and "translate" tags can be defined for the same object. Examples of transformations are given below.

<!-- Translate -->
<translate x="3.04" y="50" z="-25"/>

<!-- Translate in y direction only -->
<translate y="7.8"/>

<!-- Rotation around an axis (30 deg) -->
<rotate value="30.0" x="1" y="1" z="0"/>

<!-- Rotation around z axis -->
<rotate value="-10" z="1"/>

<!-- Uniform Scale -->
<scale value="5.0"/>

<!-- Nonuniform Scale -->
<scale x="1.5" y="0.5" z="2.1"/>

Object descriptions can also be nested. In that case, all transformations of the parent object also apply to all of the child objects. Child objects can appear before or after (or in between) transformations in the XML file. Regardless of the order, all transformations of the parent object are applied to all of the child objects.

The scene file also includes a "camera" tag that describes the view angle. The size of the final image to be rendered is defined along with other camera parameters (see the example above).

You can use the TinyXML library (or any other library that you prefer) for parsing the XML files.

PPM Image Format

We will use the PPM image format for saving the rendered images. The PPM format was chosen for its simplicity.

The particular PPM variant we will use has an ASCII header followed by the BINARY image data. Here is an example header:

P6
200 150
255

The header begins with the magic number "P6" that defines the PPM format followed by a whitespace. In the example above the whitespace is a new-line character. The following two numbers indicate the width and the height of the image respectively separated by a space character and followed by another new-line character. The next number indicates the largest integer value in the image, which is 255 for our files. Right after 255 we place a single new-line character, which concludes the header. Note that the PPM header format is slighly more general than this description (it can include comments and additional white spaces), but the description provided here is enough for writing a valid PPM header.

Right after this header, the binary image data is written. The binary data will be 8-bit values (0 to 255) for each color component, red, green, and blue respectively. The pixel data is written starting from the top-left corner of the image towards the bottom-right in the English reading order.

Here is an example code that writes a PPM image file:

bool WritePPM(const char *filename, int width, int height, unsigned char *data)
{
	FILE *fp = fopen(filename,"wb");
	if ( ! fp ) return false;
	fprintf( fp,"P6\n%d %d\n255\n", width, height );
	fwrite( data, 3, width*height, fp );
	fclose( fp );
	return true;
}

Source Code

The following source code files are provided to help you with this and upcoming projects. You are not required to use them, but it is highly recommened that you use some of them.

Optional Feature Suggestions

Student Project Pages



_