In addition to teaching the basics of ray tracing, this assignment will be used as the base for following assignments. Since you will be adding and reusing your code, it is advised that you write your code in a clean, structured object-oriented fashion.
Your ray tracer will consist of the following four sections:
Documentation for the features needed for
assignment 1
Complete povray scene format documentation
Your raytracer must be able to parse the following types:
The rays should be represented by a class object. To cast a ray, simply traverse the scene object list (also represented by C++ objects) testing for intersection with each object. Each derived geometry object class should have its own intersection routine that takes a ray, performs an intersection test and returns the closest intersection (if one exists).
The closest intersection will be shaded using the model described in
the next section. However, in the first pass of the algorithm you
may wish to color every intersection a constant color to test for correct
intersection.
I = sum over all lights { diffuseCoefficient * lightColor
* objectColor * (N dot L)
+ specularCoefficient *lightColor * (H dot N) ^ (1/roughness) }
Where the diffuseCoefficient, specularCoeffiecient, and roughness are specified by the diffuse field, specular field and roughness field, respectively. N is the unit normal at the intersection point, L is the unit vector in the direction of the light, and H is defined as the unit vector that bisects L and V (the unit vector in the direction of the eye).
This equation gives us the local color of the intersection. In
the next section we will see how to combine this with the colors of reflected
and refracted rays.
Reflection should be computed by casting a ray in the direction that is the reflection of the incoming ray. Your object intersection code should be reused here.
Transmission should be computed by recursively casting a ray in the refracted direction dictated by Snell's law, using the ior (index of refraction) povray command. (you will have to figure out when you are inside an object, and when you are outside) The color of your ray should then be computed by the following equation, where L is the output of the local model, R is the output of the reflected ray, and T is the output of the transmitted ray:
I = (1 - kRefl - kTran) L + kRefl * R + kTran * T + ambient * objectColor
Where kRefl is specified by the 'reflection' povray command, kTran is specified by the 'filter' povray command, ambient is specified by the 'ambient' povray command.
To implement shadows, before considering the contribution from a light source, cast a ray in the light source direction and test for intersections. If you find an intersection that is closer than the light source, then this light is obstructed at the point, and you should not consider any contributions from that light source (there may be contributions from another light source, though).
To avoid infinite recursion, store the depth to which a ray has been
traced, and stop recursing at some point (3-7 steps or so).
raytrace [options]
where the options are:
+W imageWidth
+H imageHeight
+I inputFilename.pov
So raytrace +W640 +H480 +Isample.pov will render a 640x480 image file, sample.ppm, consisting of the scene defined in sample.pov.
Image files should be output in ascii ppm format and named inputFilename.ppm
Sample input files and images are given below. The pictures are
generated by Povray and will not look identical to your output (due to
differences in the shading model, etc.). You will be required to
turn in rendered versions of these files (ppm format, 640x480) along with
the amount of time required to render (in the README file). The README
file should also contain a description of which parts of the ray tracer
that you believe are working, partially working, and not implemented.
This will assist the grader in determining what is causing potential errors
in your output and help in assigning partial credit.
You may wish to start with a file that is simply a sphere and a camera. Code the camera class and sphere class (derived from a generic geometric object class). Now, write the sphere intersection code coloring all of the intersections a constant color. Test this and make sure it works and then proceed to implement the other intersection tests. Then add shading (and light sources). Then shadows. Then reflection. And finally add refraction.
10% Parsing
10% Camera Model
15% Plane, Triangle Intersections
15% Box, Sphere, Cone Intersections
15% Shading
10% Reflection
10% Refraction
10% Transformations
5% Shadows
A late penalty of 10 points will be applied for every day that your program is late (your program is considered one day late if it is turned in within 24 hours after the deadline, two days for 24 to 48 hours, etc.). For example, if you turn in the assignment 2 days late and would have gotten an 84, you will receive a 64. If you wish to continue working on the assignment after handing it in, you should work on a copy of the program since we will be using the timestamps on the files for grading purposes. You may later submit a updated version for grading, but you will get the grade for your last turned in version (even if it is lower than a previous version).