Program 3: texturing and transparency — due Friday Nov 18 (updated)

(Updated on 11/14)

Due: 11:59pm, Friday November 18

Goal: In this assignment you will learn about rendering textured and transparent models using the WebGL rasterization API.

Submission: Submit your assignment using Wolfware Classic. The submit locker is now available. Click on "Submit Assignments" next to "Grade Book".

The main components of this programming assignment are:
  • 10% Part 0: properly turned in assignment
  • 40% Part 1: render the input triangles and spheres, textured but without lighting
  • 10% Part 2: render using both lighting and texture
  • 20% Part 3: render using lighting, texture and transparency
  • 20% Part 4: render using lighting, texture, transparency and transparent textures
  • Participation: Receive participation credit (outside of this assignment) for posting images of your progress, good or bad, on the class forum!

You will render triangles and spheres, described in the same sorts of JSON input files used in the second. We will again test your program using several different input files, so it would be wise to test your program with several such files. The input files describe arrays of triangles and spheres using JSON. Example input files reside at and Use these URLs in hardcode as the locations of the input triangles and spheres files — they will always be there. While testing, you should use a different URL referencing a file that you can manipulate, so that you can test multiple triangles and sphere files.

For this assignment, we have made additions to the file format supporting a transparency alpha, texture filenames and texture coordinates. All textures will reside at the same URL as the model input files. For example, if the triangles.json file makes a reference to texture1.jpg, then it will reside at When you load the texture from github, some browsers will deem it a cross-origin risk and invalidate ("taint") your canvas. To avoid this problem set the image's crossOrigin attribute to "Anonymous".

We will shortly have provided a shell in which you can build your code. You will be able to run the shell here, and see its code here. This shell will be is a correct implementation of program 2, which also loads an image (which can ultimately become a texture) as the canvas background. Default viewing parameters are the same as in the first two assignments.

You should code the core of this assignment yourself. You may not use others' code to implement texturing, blend texture with lighting, or implement transparency. You may use math, matrix and modeling libraries you find, but you must credit them in comments. You may recommend libraries to one another, speak freely with one another about your code or theirs, but you may never directly provide any code to another student. If you are ever uncertain if what you are contemplating is permissible, simply ask me or the TA.

Part 0: Properly turned in assignment
Remember that 10% of your assignment grade is for correctly submitting your work! For more information about how to correctly submit, see this page on the class website.

Part 1: Render the input triangles and spheres, textured but without lighting
Use WebGL to render unlit triangles and spheres, giving each fragment its textured color. Do not perform lighting. You will have to use the fragment shader to find the appropriate color in the texture. UV coordinates are provided with triangle sets, but must be generated for spheres. We suggest latitude and longitude be mapped to [0,1].

Part 2: Render with texture and lighting
Improve your renderer to shade fragments by mixing texture with lighting. A simple approach is modulation, which uses the lit fragment Cf to scale the texture Ct: C = CfCt. You can find more ideas here.

Part 3: Render with texture, lighting and alpha
Improve your renderer further by adding transparency (alpha) to its rendering. To avoid transparent objects occluding other objects, you will have to first render opaque objects with z-buffering on, then transparent objects with the z-write component of z-buffering off (gl.depthMask(false)).

Part 4: Render with texture, lighting, alpha and alpha textures
Add the ability to use transparency in textures. Make sure you treat any object with a non-opaque alpha as transparent, even if its material is otherwise opaque. If you are modulating, you can update alpha similarly to color: A = AfAt.

The extra credit components we suggest for this assignment are:
  • 1% off-axis and rectangular projections
  • 1% multiple lights at arbitrary locations
  • 2% improved procedural sphere sampling
  • 2% smooth shading with vertex normals
  • 3% improve transparency correctness with sorting
Other extra credit is possible with instructor approval. You must note any extra credit in your file, otherwise you will likely not receive credit for it.

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: Improved procedural sphere sampling
Most sphere triangulations use the latitude/longitude parameterization, which oversamples the poles and alters topology around them (triangles vs quads), creating rendering artifacts. An alternative is to begin with a 20-sided icosahedron (one of the Platonic solids), recursively subdivide each triangle a few times to increase sampling resolution, and project all the new vertices onto the sphere containing the icosahedron. There are many triangle subdivision schemes, but a nice one for our purposes is Loop subdivision, which turns each triangle into four triangles by placing a new vertex at the midpoint of each edge. For this assignment, you will also have to generate texture coordinates on the sphere (lat/long is fine).

Extra credit: Smooth shading with vertex normals 
Using only triangle normals, your spheres and other curved shapes will look disappointingly faceted. To represent curvature more accurately, you need vertex normals. As you generate spheres, create vertex normals as we did in your previous assignment: subtract the sphere center from each vertex. When you read in triangles, check for vertices in the input file. As you apply the composited modeling, viewing and projection matrices, make sure you apply them to your normals as well (had we used non-uniform scaling in this assignment, you would have to apply the inverse transpose of the composite). During lighting, use these normals rather than the face normal. The rasterizer will interpolate them for you. (Removed since it was included in the provided shell).

Extra credit: improve transparency correctness with sorting
Sort your transparent triangles to improve transparency correctness, and render them in back to front order. For details, see Eric Haines video on the topic here. You may earn 2% extra for simply sorting whole sets and spheres. You may earn 3% for sorting individual triangles. You may earn 5% for implementing a fully correct sort using BSP trees.