Undergraduates will extend ray tracer that models the illumination of a scene composed of multiple basic primitive shapes and point light sources.

Objectives

This assignment is designed to teach you the main concepts for ray tracing, including:

  • The basic linear algebra necessary for modeling light transport, camera coordinates, and shapes.
  • Simple data structures for maintaining a scene of surfaces and computing their intersections with light rays.
  • Introductory models for illumination, including Lambertian and Blinn-Phong shading and hard shadows.
  • Implementing all of these components to put together a basic ray tracer that accumulates the light that illuminates a scene to produce an image.

In the following, I describe in greater detail the new features you must implement while also offering suggestions on how to implement them.

As with A03, you are welcome to implement these new features using any set of modules, except where I say you must implement something in a specific way.

Part 1: New Surfaces

In addition to previously specified Sphere surfaces, your ray tracer should be modified to work with scenes that include a mix of Spheres and a new surface type: Planes. Planes will be specified by a three-dimensional vector for a point on the plane and a three-dimensional vector for the plane’s normal, as described in class.

To implement this gracefully, I recommend using an abstract base class for Surfaces, for which Sphere and Plane extend. You may want to review details on Sub classing with extends as well as other object-oriented concepts from the two Javascript textbooks recommend with the course.

Regardless of how you design things, your code must include functionality for both surfaces so that given a surface instance, it is easy for you to take a description of a ray, a range of possible values for \(t \in [t_\min, t_\max]\) on the ray, and compute the hit (over all surfaces!) that is nearest to the origin of the ray and within the range. My recommendation is to each function includes a hit() function that returns a hit record to be used by the ray tracer.

Part 2: Lights and Color

Your program must implement point light sources and be able to light scenes that include multiple light sources. You do not need to modulate the intensity of the light based on distance, but instead you can use a constant intensity value (as suggested by the book). Point lights should be defined so that they can be of any color (thus, light “intensity” should be an RGB value).

At a given surface hit, you should compute the appropriate color based on the Blinn-Phong lighting model. You will compute Lambertian (diffuse) color as well as ambient and specular color. Each surface stores the necessary coefficients for ambient, diffuse, and specular color, as well as its phong_exponent. These four values determine a very simple material model for the surface.

Thus, when a hit is encountered, you will use which surface was hit to look up the material information, and then accumulate the amount of illumination for each light in the scene. When testing, I recommend that you first test the Lambertian component. Once you are convinced this is working, you can then debug the additional Blinn-Phong components. As you are accumulating color, be careful about overflow. The final colors you display will need to be clamped.

To compute the above, you’ll need to perform frequent operations with RGB triples. One approach is to consider using your three-dimensional vector class for this. Alternatively, since certain operations – like dot products – do not make sense for colors, you may want to consider further developing a separate color class that has the appropriate operators you will use. Chapter 1 of FOCG has a brief, interesting discussion on whether or not this is a good design choice. While the choice is yours, note that there is redundancy: operations such as accumulating color often look like adding two vectors and multiplying a vector by a scalar. Other operations (such as “multiplying” two colors) are component-wise.

Another small note on color. It is often commonplace to use a background ambient light, which is not a point light, but it is applied equally to all ambient colors. In my slides and the textbook this was referred to as \(I_a\). In my implementation, I used a constant light of \((0.65,0.65,0.65)\), which I then attenuated (multiplied) each ambient colors by when computing the ambient component for lighting.

Part 3: Shadows

Finally, during the Blinn-Phong lighting calculation, your code should also be able to compute hard shadows. This means that if a light source is not visible from the hit point, its illumination should be not be including in the final color. By ignoring certainly lights that cannot be reach, we can emulate the appearance of shadows.

To test this, you should follow the scheme from the book: after computing the hit point, compute a ray from the hit point to each light source to test its visibility (being careful to offset \(t_\min\) or otherwise prevent self-intersesction). If this ray does not intersect any other surfaces in the scene, then you can safely include the contribution from this light source in the final accumulated color.

Part 4: Updates to the Scene Specification

Scene files will again be a JSON format, extended from the previous assignment. In particular, the following changes must be supported:

surfaces is now a list of shapes that can include both Spheres and Planes. To denote these, each element in the surfaces array has a field called type which is defined as either sphere or plane. Depending on the type, the surface will either store a center and radius (for Spheres) or a point and normal (for Planes).

Each surface also now includes a complete list of material properties. Specifically, you will find fields for the ambient, diffuse, and specular colors (3 element arrays of RGB tuples in the range \([0,1]\)) as well as a phong_exponent (one float) for the specular calculation.

There is also now a new array of lights. Each light in the array is represented by two vectors, a position vector and a color (an RGB triple).

Part 5: Written Questions

Please answer the following written questions. You are not required to typeset these questions in any particular format, but you may want to take the opportunity to include images (either photographed hand-drawings or produced using an image editing tool).

These questions are both intended to provide you additional material to consider the conceptual aspects of the course as well as to provide sample questions in a similar format to the questions on the midterm and final exam. Most questions should able to be answered in 100 words or less of text.

Please create a separate directory in your repo called written and post all files (text answers and written) to this directory. Recall that the written component is due BEFORE the programming component.

  1. Briefly explain your design choice with how you chose to represent surfaces. Did you use polymorphism? What advantages/disdvantages have you encountered?

  2. When casting a shadow ray, we typically search for an intersection within the range of \([\varepsilon,d]\) where \(d\) is the distance to the light source and \(\varepsilon\) is some small number greater than zero. Explain why we do not use \([0,d]\).

  3. Given a vector \((1,1,0)\), construct an orthonormal basis. See Sections 2.4.5-2.4.7 of the textbook. State which vector \(\mathbf{t}\) you used. Show your work.

  4. Explain how the specular term of the Blinn-Phong shading model works and what visual effect it is trying to approximate. In particular, explain the vector \(\mathbf{h}\) and the Phong exponent \(p\).

  5. Exercise 10.2 on pg. 241 of the textbook.

Grading

Deductions

Reason Value
Program crashes due to bugs -10 each bug at grader's discretion to fix


Point Breakdown of Features

Requirement Value
Consistent modular coding style 10
External documentation (README.md) 5
Class documentation, Internal documentation (Block and Inline). Wherever applicable / for all files 15
Expected output / behavior based on the assignment specification, including

Updated your scene file parser for lights/planes/materials10
Computing ray-surfaces intersections for planes (and spheres)10
Computing Blinn-Phong lighting, employing ambient, diffuse, and specular components20
Computing hard shadows by tracing rays from hit points to lights10
Displaying your ray traced scene10
Designing a scene of your choice that shows off your ray tracer's capabilities, submitted as myscene.js and myscene.ppm10

70
Total 100