Partial Due: 11:59pm, Wednesday Oct 9
Final Due: 11:59pm, Monday Oct 21
Goal: In this assignment you will practice basic modeling and implement transforms and lighting on 3D objects using the WebGL rasterization API.
Submission: Submit your assignment using this Google Form.BASIC GRADING:
The main components of this programming assignment are:
- 5% Part 0: partial feedback
- 5% Part 1: properly turned in assignment
- 10% Part 2: render the input triangles, without lighting
- 25% Part 3: light the triangles
- 20% Part 4: interactively change view
- 5% Part 5: interactively select a model
- 20% Part 6: interactively transform the triangles
- 10% Part 7: make it your own
- Participation: Receive participation credit (outside of this assignment) for posting images of your progress, good or bad, on the class forum!
You may (optionally) work with one partner on this assignment. You should each turn in the same code.
We provide a small shell in which you can build your code. You can run the shell here, and see its code and assets here. The shell shows how to draw triangles using WebGL without any model or view transform, and how to parse the input triangles.json file. It also shows how to use animation callbacks to render multiple image frames.
The default view and light are as in the first assignment. The eye is at (0.5,0.5,-0.5), with a view up vector of [0 1 0] and a look at vector of [0 0 1]. Locate the window a distance of 0.5 from the eye, and make it a 1x1 square normal to the look at vector and centered at (0.5,0.5,0), and parallel to the view up vector. With this scheme, you can assume that everything in the world is in view if it is located in a 1x1x1 box with one corner at the origin, and another at (1,1,1). Put a white (1,1,1) (for ambient, diffuse and specular) light at location (-0.5,1.5,-0.5).
5% of your assignment grade is just for correctly submitting your work! For more information about how to correctly submit, see this page on the class website.
Part 2: Render the input triangles, without lighting
Use rasterization to render unlit triangles, giving each triangle its unmodified diffuse color (e.g, if the diffuse color of the triangle is (1,0,0), every pixel in it should be red). You will have to use vertex shaders to perform viewing and perspective transforms, and fragment shaders to select the diffuse color. We recommend the use of the glMatrix library for creating these transforms.
Part 3: Light the triangles
Shade the triangles using per-fragment shading and the Blinn-Phong illumination model, using the reflectivity coefficients you find in the input files. Use triangle normals during lighting. Your fragment shaders will perform the lighting calculation.
Use the following key to action table to enable the user to change the view:
- a and d — translate view left (a) and right (d) along view X
- w and s — translate view forward (w) and backward (s) along view Z
- q and e — translate view up (q) and down (e) along view Y
- A and D — rotate view left (A) and right (D) around view Y (yaw)
- W and S — rotate view forward (W) and backward (S) around view X (pitch)
Part 5: Interactively select a model
Use the following key to action table to interactively select a certain model:
- left and right — select and highlight the next/previous triangle set (previous off)
- space — deselect and turn off highlight
- k and ; — translate selection left (k) and right (;) along view X
- o and l — translate selection forward (o) and backward (l) along view Z
- i and p — translate selection up (i) and down (p) along view Y
- K and : — rotate selection left (K) and right (:) around view Y (yaw)
- O and L — rotate selection forward (O) and backward (L) around view X (pitch)
- I and P — rotate selection clockwise (I) and counterclockwise (P) around view Z (roll)
EXTRA CREDIT GRADING:
- 461: ½% — arbitrarily sized viewports
- 461: ½% — off-axis and rectangular projections
- 461: ½% — multiple lights at arbitrary locations
- 461: 1% — 561: ½% — smooth shading with vertex normals
- 461: 3% — 561: 1% — render ellipsoids
Accept a new square canvas (viewport) width/height through your UI. Size your canvas to match.
Extra credit: Support off-axis and rectangular projections
Accept new window parameters in viewing coordinates through your UI (left, right, top, bottom). Adjust your projection matrix to this new window, and render the scene.
Extra credit: Multiple and arbitrarily located lights
Read in an additional lights.json file that contains an array of objects describing light location and color. Note that these lights will have distinct ambient, diffuse and specular colors. Render the scene with all of these lights. You can find an example lights.json file here. Assume that the input lights file will always reside at this URL when you turn in your code.
Extra credit: Smooth shading with vertex normals
Using only triangle normals, your curved shapes will look disappointingly faceted. To represent curvature more accurately, you need vertex normals. When you read in triangles, check for vertex normals in the input file. As you apply the composited modeling, viewing and projection matrices to your vertices, apply the inverse transpose of the modeling transform to your vertex normals. During lighting, use these normals rather than the face normal. The rasterizer will interpolate them for you. We will provide an example json file with a curved shape on request.
Render ellipsoids as described in input. You can find an example ellipsoids.json file here. There are no ellipsoid primitives available in WebGL, so you will have to build an ellipsoid out of triangles, then transform it to the right location and size. You can do this statically with a hardcoded sphere model, or procedurally with a latitude/longitude parameterization. Again you will have to use vertex shaders to perform viewing and perspective transforms, fragment shaders to select color. The ellipsoids should be shaded like triangles, and should use vertex normals if you are claiming that extra credit.