Project 2: Ray Tracing
Due Dates:
This assignment is worth 100 points. See the course web page for the
intermediate and final project due dates.
Each team gets two late days for this assignment. These days (and any left over from project 1)
will be used extend intermediate or final deadlines as needed.
Failure to meet any (possibly extended) deadline incurs a cost of 5 points per day until
the work is completed.
You are strongly urged to work early and often!
Overview
In this assignment you will implement a basic raytracer.
The program reads the description of a 3D scene from a
ray file and produces
a rendered image of that scene. The program works in interactive and
batch mode.
We provide skeleton code
that includes a host of support classes to help you get started. (Do
not change any class interfaces or control.cpp without talking to me
first!)
We also provide a solution executable to help you test and debug your code.
What You Have to Do
The project is broken down into three parts.
At the end of the first and second parts
you'll run a series of tests to demonstrate you've implemented the
required features. See the course web page for specific deadlines.
Features listed in bold are required. (You cannot receive points for
extensions unless you've made a good faith
effort at implementing the required features.)
Part I: Ray Casting (30 points):
In this part you'll build a simple ray casting system. Your program
will cast rays into the scene and
find the closest intersecting object; i.e. triangle or sphere. You will
also support scale, rotate, and translate
modeling transforms. Sample test files are provided with the skeleton
code; you should supplement them with your own test files to properly
test your implementation.
- (5 pts.) Cast rays into the scene:
Modify RayFile::raytrace() to generate rays from these
camera's position through each pixel of the image.
(Refer to camera.h and the rt UML to understand the information available to you.)
-
(5 pts.)
Intersections with spheres: Modify Group::intersect() and
Sphere::intersect() to compute intersections between the ray and
a sphere. Note: a group is a collection of shapes and other groups stored in a list;
a group must find the first intersection point between the ray and the shapes and groups in its list.
You should ignore group transforms for now.
(Test file: 1.sphere.ray.)
Information about the intersection point is passed using the _Intersection_
structure, which is described in intersection.h. The group and shape intersection routines
return the distance from the start of the ray to the intersection point.
Remember, you want to find the closest intersection point that is in front
of the camera!! Also, in computing the surface normal at the intersection point
(part of the _Intersection_ structure), you want the normal facing the camera.
We've provided some lighting code so at this point you should be able to render spheres.
-
(5 pts.)
Intersections with triangles: Repeat the same step for triangles,
this time modifying Triangle::intersect().
(Test file: 2.triangle.ray)
- (10pts.) Transformations:
Now introduce transformations. Modify Group::intersect() to take into
account its local transformation. Use the transform information to convert the ray
into local coordinates, find the closest intersection, and use the
transform information to convert the intersection back into the parent node's coordinates.
Be careful when converting the normal!
Also, be sure to re-compute the distance to the intersection point
in the parent node's coordinates.
(Test files: 3.xfm.ray, 4.groups.ray)
- (5 pts.)
Ray casting tests:
One week after the project begins you'll be required to render several ray files to demonstrate your
ray casting capabilities.
Part II: Recursion (35 pts.)
The next step is to add recursion and point lights. Note the number of recursive steps is
a program parameter that can be set through the interface in the Render
menu. The default is 0, which will not reveal any recursive effects
other than shadows. You must set the recursive depth to an appropriate
value for a given ray file.
- (5 pts.) Point Lights: Implement PointLight::getDiffuse(),
Point::getSpecular(), and PointLight::getShadow() to calculate the
effect of point lights on the scene.
Modify RayFile::getColor() to call these functions.
(Test file: 10.pointLight.ray)
- (10) Reflection: Modify RayFile::getColor() to recursively
cast reflected rays at the point of intersection and then use this value
in the color calculation. Be careful to offset the reflected ray slightly,
so you don't re-discover the same intersection point.
(Test file: 7.reflect.ray)
- (10) Transmission Modify RayFile::getColor() to recursively
cast transmitted rays at the point of intersection and then use this value
in the color calculation. For now, ignore the refractive index.
(Test file: 8.transmit.ray)
- (5) Snell's Law : Modify RayFile::getColor() to use the index of
refraction and Snell's Law to calculate the correct direction of
transmitted rays through objects.
(Test file: 9.refract.ray)
- (5) Recursion tests:
Two weeks after the project begins you'll be required to render several ray files to demonstrate your
recursive capabilities.
Part III: Bells and Whistles: (37 points)
Next you'll add some bells and whistles.
- (2 pts.) Emissive and Ambient:
Modify RayFile::getColor() to calculate color using the intersecting surface's
emissive and ambient properties and the ambient light in the scene.
(Test file: 5.ambientEmissive.ray)
- (5 pts.) Texture mapping: Add texture mapping. Modify Triangle::intersect() and
Sphere::intersect() to calculate texture coordinates at the point of
intersection. Add getTexture(u,v) to the material class.
Use bilinear interpolation for the texture samples.
(Test files: 11.textures.ray, texture file: z.bmp)
- (7) Bump Mapping: Add bump mapping. Modify Triangle::intersect() and
Sphere::intersect() to compute to fill in the bumpNormal structure of the material at the point of
intersection.
(Test files: 11.bump.ray, bump map file: bump.bmp)
- (5) Add a primitive : Add support for one of the following primitives: box, cone, or cylinder. Include
texturing and bump mapping capabilities.
- Extensions:
Following are list of possible extensions to your ray tracer. Choose options worth at least 13 points.
- (5 pts.) Spot Lights: Implement SpotLight::getDiffuse(),
SpotLight::getSpecular(), and SpotLight::getShadow() to calculate the
effect of spotlights on the scene.
Modify RayFile::getColor() to call these functions. (Test file: 8.spot.ray)
- (10) Procedural Textures - add support for 3D procedural
textures. Check out this
website for information on Perlin Noise.
(5) Jittering: Implement one (but no more than one) of the following techniques:
- Pixel jittering - implement a jittered supersampling technique to reduce
aliasing by casting multiple rays per pixel, randomly jittered about the
center of the pixel, and averaging the colors.
- Soft Shadows - treat each point and spot light as having some
finite volume and cast multiple rays for shadow tests. Modify
PointLight::getShadow() and SpotLight::getShadow() to return doubles
instead of booleans, and to return the average of these multiple shadow
tests. If you want, you can modify DirectionalLight:getShadow() to behave
similarly, but because a directional light doesn't have a position, good
results can be difficult to get.
- Depth of Field - implement depth of field camera effects
- (5) Add another primitive: box, cylinder, or cone. Support texture and bump mapping.
- (10) Torus Primitive - add support for a Torus primitive. Support texture and bump mapping.
- (5) Fisheye Lens - implement fisheye lens camera effects
- (5) Lens flare/bloom -- implement one type of lens flare or bloom effect. (May be repeated for multiple effects with approval of instructor.)
- (?) Impress us with something we hadn't considered
- (5 max) Submit an entry to the art contest.
Create an interesting model and ray trace it with your program.
(The operative word is interesting!)
You must submit the model to receive points.
- (10 max) Submit an interesting MPEG movie made from multiple raytraced images.
You also have to describe the
sequence of commands used to created the images.
What to Submit
You should upload a zipped floater that contains:
-
your Visual Studio project folder,
-
an html writeup called "assignment2.html" that describes all features you've
implemented
-
how any art images/movies were created
- all images you are submitting and their ray files (please link them to your html writeup)
Make sure the source code compiles and runs under Visual studio 8.
Remember our standing late policy and collaboration policy.
You may submit a project worth more than 100 however after 100 points, each point is divided by 2, after 110 points, each
points is divided by 4, etc.
Notes
Links
Last Update: Feb. 2013