In its current form, this assignment is extra credit. Your score (as a percentage) will be multiplied by 50% and then multiplied again by the maximum number of points that you lost on any one assignment.
To do the assignment, first download all the code below. Read over it all and work out the overall structure. Then fill in TODO comments. I'll post further instructions too, but I'm always happy to answer questions if you post to Piazza.
For each individual TODO comment in the starter code, you have the option of either filling it in yourself or emailing me to get the solution. You will not receive credit for TODOs for which I provide the answer.
In the end, you should be able to produce renders like these. The first one took 17 minutes to render; the second took 6 hours (since the sphere has so many triangles in it). Both images are 450x300. Consider that the render time for a brute-force raytracer like ours generally scales linearly with the product of the number of pixels, the number of triangles, and the number of lights.
Submit your work through Canvas. Hand in your copies of all the files listed below under “Starter Code” or “Recycled Code”. In addition, submit a PDF that shows at least one render whose shortest side is at least 100 pixels.
Download the starter code and fill in the blanks.
Please download these files and fill in the TODO comments based on your previous work.
Download new copies of the helper code, but don't modify them.
Fill in the TODO comments in each of these files by copying them over from your previous work. This does not count toward your score, and you're welcome to just ask me for solution files.
Read both of the following files completely before filling in any of the TODOs. It's important to understand the distinction between the light falling on a particular position (and the direction of that light) versus the appearance of a surface at that position. Both files have loads of explanatory comments.
lighting.py (6 TODOs) — This file defines an abstract base class Light
and four subclasses: AmbientLight
, PointLight
, SpotLight
, and ParallelLight
.
Take the time to read the big comment at the top of the file. It contains standard definitions for terms like “color” that are used throughout the assignment (especially in surface.py and raytracer.py).
Each Light subclass has three public methods — ambiAt()
, diffAt()
, and specAt()
— that define the color of the illumination that the light provides at a given point in space. Each subclass overloads one or more of these methods to provide its own particular lighting behavior.
surface.py (5 TODOs) — This file defines the class Surface
, which represents the appearance properties of the surface of an object. The appearance of an object depends on properties of the surface, the lights in the scene, the surrounding environment, and the position of the viewer.
Fill in the reflect()
function, then ambiAppearance()
, diffAppearance()
, and specAppearance()
. Finally, fill in phongAppearance()
.
There are 8 TODOs in raytracer.py. Before you start, read over the entire file. There are some helper functions at the bottom that are used in the starter code. I'd suggest filling in the TODOs in the following order:
renderRaster()
(one TODO, though it involves calling the functions below, which you won't have filled in yet).makeViewVectors()
(2 TODOs).triangleIntersect()
(one big TODO).closestIntersection()
(one big TODO).isBlocked()
(one big TODO, but it's very similar to closestIntersection()).trace()
(two little TODOs).This assignment is worth 20 points.
Criterion | Points |
---|---|
All files submitted, including PDF. | 1 |
Recycled code, main program, and test scene. | 1 |
lighting.py | 4 |
surface.py | 5 |
raytracer.renderRaster() | 1 |
raytracer.makeViewVectors() | 1 |
raytracer.triangleIntersect() | 2 |
raytracer.closestIntersection() | 2 |
raytracer.isBlocked() | 1 |
raytracer.trace() | 2 |
Total | 20 |