For this assignment, you will add lighting to the ray tracer you implemented in assignment 2. The same input file format will be used to describe the scene, with additional commands included to support lighting (described below). The actual lighting calculation consists of multiple parts:
One of the benefits of ray tracing is that it allows for easy shadow calculation. When casting a ray into the scene, if an intersection is found, you should cast shadow rays from the intersection point to each light source (so if there are multiple light sources, you should cast multiple rays). If a shadow ray hits another object before reaching its light source, it means that the light is blocked and the point is in shadow.
Each light source that is not blocked should contribute to the local surface illumination, described below. There is one exception - if a light source is behind the current surface (i.e. in a direction opposite to the surface normal), it should be considered blocked.
The surface illumination includes specular and diffuse components (the NFF format does not allow for an ambient component). You should use the standard Phong model to calculate the specular component. Each light that is not blocked should contribute color according to:
localColor = lightColor * (Kd * surfaceColor * diffuse + (Ks * specular)^shininess)
In the case of multiple lights, you should just add the results together.
However, the NFF format does not define intensities for light sources, so
you may find it useful to scale each light's contribution by
1 / sqrt(# of light sources).
In addition, you should cast reflection rays from each intersection point into the scene whenever Ks is greater than zero, and refraction rays whenever the transmission component, T, is greater than zero (T is one of the properties defined by the 'f' command). The total color of a point in the scene (i.e. what you should write to your output) is:
totalColor = localColor + Ks * reflection + T * refraction
This is a recursive process, since the color of the reflection and refraction
rays is the color of whatever they hit. To avoid infininite recursion, limit
the ray tree depth (i.e. number of bounces) to 5. You may skip the reflection
or refraction ray if the contribution to the final color would be less than
1/255, but that optimization is not necessary.
You are expected to complete assignment 5 by modifying your code for assignment 2. If you did not complete assignment 2, or if you think you will be unable to modify your code, you can request a working implementation from the TA.
There are a few sample input files located at:
/afs/umbc.edu/users/r/h/rheingan/pub/435/Proj5/samples
The files balls1.nff, balls2.nff, and balls3.nff are identical to the sample
files from project 2, except that they include lighting commands. As before,
the files correspond to different levels of recursion for fractally defined
spheres.
As in project 2, the input file will use a subset of the NFF file format. You should support the commands below, in addition to the ones used in project 2 ("f" has been repeated since this assignment uses additional features of it).
| l |
Positional light. A light is defined by XYZ position. Description:
"l" X Y Z [R G B]
Format:
l %g %g %g [%g %g %g]
All light entities must be defined before any objects are defined (this
requirement is so that NFF files can be used by hidden surface machines).
Lights have a non-zero intensity of no particular value, if not specified
(i.e. the program can determine a useful intensity as desired); the
red/green/blue color of the light can optionally be specified.
|
| f |
Fill color and shading parameters. Description:
"f" red green blue Kd Ks Shine T index_of_refraction
Format:
f %g %g %g %g %g %g %g %g
RGB is in terms of 0.0 to 1.0.
Kd is the diffuse component, Ks the specular, Shine is the Phong cosine
power for highlights, T is transmittance (fraction of contribution of the
transmitting ray). Usually, 0 <= Kd <= 1 and 0 <= Ks <= 1, though it is
not required that Kd + Ks == 1. Note that transmitting objects ( T > 0 )
are considered to have two sides for algorithms that need these (normally
objects have one side).
The fill color is used to color the objects following it until a new color
is assigned.
|
Students in 634 should have added support for (convex) polygons in assignment 2, using the "p" command from the NFF specification. For assignment 5, you should add lighting for polygons, and also add support for the "pp" command, which includes a unique normal for each vertex. You should interpolate between normals when performing lighting calculations. There are several ways to do this:
Instead of point lights, treat each light source as a sphere with a specific radius and center given by the NFF "l" command. Then, instead of casting a single shadow ray, cast multiple rays to each light, to sample different points on the surface of the sphere. This allows points in the scene to be partially shadowed with respect a single light.
You may distribute the shadow rays in any sensible way (for exmaple, projected through a uniform grid). Also, you may consider light to emanate omnidirectionally from points on the surface of a spherical light, so you do not need to worry about doing any calculations with the sphere's normal vector.
You should use command line flags to control the radius of the spherical lights and the number of samples.
Simulate haze by attentuating light/reflection along ray. Use the command line flags to turn haze on.
As an alternative to Phong shading, add support for the artistic shading techniques described by Shirley in section 9.3 (line drawing and cool-to-warm shading). You should use separate command line flags to enable either effect. Each technique is worth 5 points individually.
Add antialiaing to your ray-tracer. Five points for implementing regular supersampling with a box reconstruction filter. Additional points for adding more sophisticated sampling or reconstruction: one point for jitter, two points for a pseudo-Poisson distribution (random with minimum distance is fine), two points for Gaussian reconstruction.
Use a command line flag to control the number of samples per pixel, as well as the selection of sampling and reconstruction technique.
More sample scenes in NFF format can be created using a set of programs called the "Standard Procedural Database", which is freely downloadable. A copy of the SPD is also located at:
/afs/umbc.edu/users/r/h/rheingan/pub/435/Proj2/spd
The sample files listed above were created using the SPD program 'balls', which writes
an NFF file to standard output. For example:
balls -s 1 > balls1.nff
The -s option controls the level of recursion. Note that the output of the SPD programs
typically includes NFF commands other than the ones required for this assignment (balls
outputs a single polygon which was removed from the sample files). Therefore, if you
want to test your ray tracer using the SPD programs, you should be able to handle the
presence of such commands in your input file (you should simply ignore any commands you
do not implement).
The program 'shells' outputs many spheres, similarly to balls; 'lattice' and 'jacks' output cylinders and cones, 'tetra' and 'teapot' output primarily convex polygons, and 'gears' includes concave polygons.
Submit your assignment as 'Proj5'. Include your source code and makefile. Please do not submit PPM files, as they can be very large. If you must submit images, convert them to a compressed format such as .jpeg. The 'convert' program is available on the GL servers, so for example you can do:
convert image.ppm image.jpg
Also include a readme file with a description of what hardware / software environment you used to develop your project, and a description of any help you received or outside resources you used. (If you received no help beyond the text and course staff, state as much.) Your readme should also include any instructions necessary for using your program.