Programming assignment 4: Drawing in 3D with basic shading and visibility determination

by Eftychios Sifakis on February 18, 2016

Due: Wednesday February 24th Friday February 26th.

NOTE ON LATE SUBMISSIONS: We decided to give you a courtesy 2-day extension on this programming assignment. Note, however, that if you still happen submit late after this deadline, and to minimize the impact of such a late submission on your grade, you will be asked to submit at least some partial progress towards your goal by the Feb 26th deadline. Reasonable partial progress would have to include (i) demonstrating the aspects that Programming assignment 3 was asking of you, i.e. perspective projection and user-controllable camera position, (ii) drawing solid, filled polygons instead of wireframe curves. Your partial submission would be even more convincing if your code also demonstrates drawing in 2 phases, i.e. first appending all the primitives that are to be drawn in some structure (e.g. array), and doing the actual drawing in a second pass. This would position you well, to complete the assignment with implementing the depth ordering, too.

Synopsis: You will create 3D animation using the JavaScript 2D canvas – this means you will implement your own complete 3D pipeline. 3D transformations, viewing transformation, perspective divide, … This time you will draw solid objects (filling triangles). You will figure out normal directions, try the painter’s algorithm for visibility, figure out some rudimentary shading, …

Learning Objectives: This assignment will give you the opportunity to see how 3D graphics really works. What you learn by implementing the transformation pipeline will come in handy in the future – since you’ll implement it again when we do WebGL. You will also either learn to use a matrix library, or implement one yourself. You will see what visibility computations do, and try some basic shading. And you’ll do a little hierarchical modeling in 3D.

Evaluation: Check/No Check/Above and Beyond. You get a check if you turn in a viable, and complete submission. It must draw some basic objects (a couple of cubes is OK), they must be animated (spin around to show the normal directions change – even better if they move in a hierarchical fashion (make an arm that waves, or a helicopter, or …). Things must be drawn with filled triangles. (preferably drawing them in the right order to get visibility correct). You must compute the normals for each triangle – and show it. There are opportunities for “project points” (technical challenges). Gold stars are given for nice interfaces or nice looking animations (cool objects or movements) – but the technical bits are what get you project points.


Handin: Will be as a Canvas (the course management system, not the JavaScript drawing library) assignment. (Link). Make sure that you turn in all files needed for your program to run.

Make sure that you turn in all files needed for your program to run. Note: if you have completed optional things for project points, be sure to say so in the typein box for the handin. Also, please list any dependencies your program needs to run (e.g. if you only tested it in a specific browser, or if it needs to access libraries over the web). You can link to twgl on the graphics group web server (see the tutorial). If you have multiple files, please package them as a single ZIP file (see handin instructions).

Here is a link to a simple example, and a fancy example (coming soon).


In this project, you will do some drawing in 3D. Except that you’ll use the JavaScript 2D drawing canvas. This means that you’ll have to implement your own transformations between 3D and 2D (since the Canvas 2D transformations are only 2D affine and cannot represent the perspective transformations). You can use a matrix library. We recommend trying TWGL (see the tutorial, and the P3 examples).

You will draw your objects with filled triangles. If you draw them in the wrong order, thing in the back might block things in front. You can sort the triangles into the right order (painter’s algorithm) – this will get you project points. It will make your program much cooler. You should have a button or some way to turn the painter’s algorithm on and off to show what happens when you don’t use it. The painter’s algorithm isn’t perfect – but implement it decently, and it will work well enough. Part of this assignment is to understand when it does and doesn’t work.

You will need to compute normal vectors for the triangles. This will turn out not to be so hard using a matrix library. You can show that you have the normals correct by either drawing them as little sticks poking out of the triangles (be sure to be able to turn them off – or to include them in the painter’s algorithm) – or using the normals in a shading calculation. (we haven’t done much shading in class, but we will explain simple flat/diffuse shading which will be perfect for this assignment).

You will need to have colors for your triangles. You can pick the colors. But its better if you use the normals for diffuse flat shading. It will look cool.

Your objects must be animated. They should move/spin so its clear that the normals are changing the right way (for example, to spin so the lighting changes). It’s better is there’s a clear hierarchy in your transformations.

You should have a user interface for manipulating the camera. Sliders for the camera parameters work. Or we’ll give you some code for something fancier to try (an arcball).

We’ll show you a sample solution – but you aren’t supposed to look at the code. There are plenty of examples already (plus you have a big start with Program 3, and everything that went into that).

Note: for this assignment, its worth getting hidden surface removal to work (painter’s algorithm). Grade wise, this will be valuable (it is the biggest source of project points), but it will also make it much easier to see everything else. Even if you get shading correct, it will be hard to see if if you don’t have hidden surface removal.


  • Perspective transformations
  • Interact with the camera
  • 3D hierarchical object that is animated (hierarchical is optional – but things must move so we can see how the lighting changes)
  • Filled triangles
  • Show normals with vectors and/or shading
  • All using Canvas 2D
  • Painter’s Algorithm for visibility (and the ability to switch it on and off).
    • Super bonus for splitting triangles to resolve intersections. If you do this, be sure to say so in the hand-in comment, and to show it off in your program (pick an object that makes use of it).
  • Diffuse Shading
  • Coolness we haven’t thought of.

Some Hints…

Obviously, the big thing is the painters algorithm. Rather than drawing the triangles, you’ll have to collect them in a list and sort them after transforming them).

The simplest thing is to pick 1 point as the depth for each triangle. This will always mess up some of the time. But getting it more correct is hard.

Draw 1 color per triangle (based on its normal). Don’t try to shade individual triangles. (this is hard given how Canvas works).

For diffuse shading (the simplest thing): take your color C (3 numbers RGB) and multiply it by the “brightness” of the light due to the orientation. Simplest version: (.5 + .5 N dot L) as we described in class. Be sure to do something where the lighting affects how things look (which is why there needs to be animation). You can make the light be vertical (come from the top) to make things easy – this way all the L vectors are (0,1,0).

For testing, make your program work with 1 triangle – and print the normal / lighting value (or look at it in the debugger) to confirm it works. Once that works, take it out and add more stuff (we don’t need to see your debugging work). Draw 2 triangles (not moving, at known depths in front of the camera) to make sure painters algorithm is working. Then make something more interesting.

Coming Attractions

Next week, we’ll start using WebGL to do the drawing – so we can draw fast and color each pixel.

Print Friendly, PDF & Email

Previous post:

Next post: