In this assignment, you will add new primitives (planes and triangles) and affine transformations. You will also implement a perspective camera, and two simple shading modes: normal visualization and diffuse shading. For the normal visualization, you will simply display the absolute value of the coordinates of the normal vector as an (r, g, b) color. For example, a normal pointing in the positive or negative z direction will be displayed as pure blue (0, 0, 1). You should use black as the color for the background (undefined normal).
Diffuse shading is our first step toward modeling the interaction of light and materials. Given the direction to the light L and the normal N we can compute the diffuse shading as a clamped dot product:
d | = L . N | if L . N > 0 | |
= 0 | otherwise |
If the visible object has color cobject = (r, g, b), and the light source has color clight = (Lr, Lg, Lb), then the pixel color is cpixel = (rLrd, gLgd, bLbd). Multiple light sources are handled by simply summing their contributions. We can also include an ambient light with color cambient, which can be very helpful in debugging. Without it, parts facing away from the light source appear completely black. Putting this all together, the formula is:
cpixel = cambient * cobject + SUMi [ clamped(Li . N) * clighti * cobject ]
Color vectors are multiplied term by term. Note that if the ambient light color is (1, 1, 1) and the light source color is (0, 0, 0), then you have the constant shading used in assignment 1.
void getIllumination (const Vec3f &p, Vec3f &dir, Vec3f &col);
to find the illumination at a particular location in space. p is the intersection point that you want to shade, and the function returns the normalized direction toward the light source in dir and the light color and intensity in col.
PerspectiveCamera(Vec3f ¢er, Vec3f &direction, Vec3f &up, float angle);
Hint: In class, we often talk about a "virtual screen" in space. You can calculate the location and extents of this "virtual screen" using some simple trigonometry. You can then interpolate over points on the virtual screen in the same way you interpolated over points on the screen for the orthographic camera. Direction vectors can then be calculated by subtracting the camera center point from the screen point. Don't forget to normalize! In contrast, if you interpolate over the camera angle to obtain your direction vectors, your scene will look distorted - especially for large camera angles, which will give the appearance of a fisheye lens.
Note: the distance to the image plane and the size of the image plane are unnecessary. Why?
Plane(Vec3f &normal, float d, Material *m);
d is the offset from the origin, meaning that the plane equation is P . n = d. You can also implement other constructors (e.g. using 3 points). Implement intersect, and remember that you also need to update the normal stored by Hit, in addition to the intersection distance t and color.
Triangle(Vec3f &a, Vec3f &b, Vec3f &c, Material *m);
Use the method of your choice to implement the ray-triangle intersection: general polygon with in-polygon test, barycentric coordinates, etc. We can compute the normal by taking the cross-product of two edges, but note that the normal direction for a triangle is ambiguous. We'll use the usual convention that counter-clockwise vertex ordering indicates the outward-facing side. If your renderings look incorrect, just flip the cross-product to match the convention.
Transform(Matrix &m, Object3D *o);The intersect routine will first transform the ray, then delegate to the intersect routine of the contained object. Make sure to correctly transform the resulting normal according to the rule seen in lecture. You may choose to normalize the direction of the transformed ray or leave it un-normalized. If you decide not to normalize the direction, you might need to update some of your intersection code.
You will need to edit the Makefile to include any .C files that you add to the project.
raytracer -input scene2_01_diffuse.txt -size 200 200 -output output2_01.tga raytracer -input scene2_02_ambient.txt -size 200 200 -output output2_02.tga
raytracer -input scene2_03_colored_lights.txt -size 200 200 -output output2_03.tga -normals normals2_03.tga
raytracer -input scene2_04_perspective.txt -size 200 200 -output output2_04.tga -normals normals2_04.tga
raytracer -input scene2_05_inside_sphere.txt -size 200 200 -output output2_05.tga -depth 9 11 depth2_05.tga -normals normals2_05.tga -shade_back raytracer -input scene2_05_inside_sphere.txt -size 200 200 -output output2_05_no_back.tga
raytracer -input scene2_06_plane.txt -size 200 200 -output output2_06.tga -depth 8 20 depth2_06.tga -normals normals2_06.tga
raytracer -input scene2_07_sphere_triangles.txt -size 200 200 -output output2_07.tga -depth 9 11 depth2_07.tga -normals normals2_07.tga -shade_back raytracer -input scene2_07_sphere_triangles.txt -size 200 200 -output output2_07_no_back.tga
raytracer -input scene2_08_cube.txt -size 200 200 -output output2_08.tga raytracer -input scene2_09_bunny_200.txt -size 200 200 -output output2_09.tga raytracer -input scene2_10_bunny_1k.txt -size 200 200 -output output2_10.tga
raytracer -input scene2_11_squashed_sphere.txt -size 200 200 -output output2_11.tga -normals normals2_11.tga
raytracer -input scene2_12_rotated_sphere.txt -size 200 200 -output output2_12.tga -normals normals2_12.tga
raytracer -input scene2_13_rotated_squashed_sphere.txt -size 200 200 -output output2_13.tga -normals normals2_13.tga
raytracer -input scene2_14_axes_cube.txt -size 200 200 -output output2_14.tga raytracer -input scene2_15_crazy_transforms.txt -size 200 200 -output output2_15.tga
raytracer -input scene2_16_t_scale.txt -size 200 200 -output output2_16.tga -depth 2 7 depth2_16.tga
See the main Assignments Page for submission information.