Program 3: object hierarchies and frustum culling

Due: 11:59pm, Friday November 13th

Submission: Submit your assignment using Wolfware Classic. Remember that 10% of your assignment grade is for correctly submitting your work! For more information about how to correctly submit, see this post on the class website.

Goal: In this assignment you will implement object hierarchies and frustum culling using a rasterization API (either WebGL or OpenGL).

All graphics functionality of this assignment must be completed using a rasterization API (WebGL or OpenGL). Your assignment will be evaluated as follows:
  • 10% Properly turn in the assignment.
  • 20% Render a single model as in Program 2.
  • 20% Render several models at once, arranged in an object hierarchy.
  • 10% Add bounding boxes to each node in your hierarchy, display them on demand.
  • 10% Render the current frame rate and time in a heads up display.
  • 30% Use view-frustum culling to accelerate your rendering, turn it off on demand.
  • Participation credit: You can receive participation credit (outside of this assignment) for posting images of your progress, good or bad, on the class forum!

General Notes (read carefully!):
This assignment has many similarities to your previous assignment, but still, make sure you start early!

You are free to choose the window size, position of eye, and light position and color. By default, your renderer should choose a view that makes the model visible! Since the assignment requires interactive transforms, your program should run in real time (>= 60fps).

Unlike Program 2, we will not be providing you with specific models to test as you build your application. You should include appropriate models and test scenarios which demonstrate the required functionality.

How Your Assignment Will Be Invoked (read extra carefully!):

JS / WebGL: your program must accept a query string parameters specifying the hierarchy file to load. The browser will be run with --disable-web-security in order to allow cross origin requests. We will run your assignment using:


C / OpenGL: your program must accept a command line argument specifying the hierarchy file to read. We will run your assignment using:

prgm3.exe [hierarchyfilepath]

Assignment Details:

Part 0: Properly turned in assignment
Submit files as specified here.

Part 1: Render a single model as in Program 2
Use a rasterization API and shaders (WebGL or OpenGL) to render triangles loaded from OBJ files. Perform depth buffering and Blinn-Phong lighting. Blinn-Phong lighting can be calculated in either the vertex shader or fragment shader. Load a texture associated with a material specified in the material library file (.mtl). Use this image and the texture coordinates specified in the OBJ file to perform texture mapping on a 3D object which uses the texture mapped material. By default, you should support the BMP image format.

As in Program 2, interactively move the view using the keyboard and cursor keys (arrow keys) for input. Transformations must be performed using (vertex) shaders.

Let the user move the view as follows:
  1. Use "z" and "Z" to move into / out of the view (translate the eye in view Z)
  2. Use "x" and "X" to slide the view left and right (translate the eye in view X)
  3. Use "y" and "Y" to slide the view up and down (translate the eye in view Y)
  4. Use "up" and "down" to rotate the view up and down (rotate lookat around view X)
  5. Use "left" and "right" to rotate the view left and right (rotate lookat around view Y)

Part 2: Render several models at once, arranged in an object hierarchy
Load a hierarchy file with multiple records having the following format:

<filename.obj>       // obj file for the node, if any. NOOBJ if no file.
<transform>          // node transform, 16 floats. IDENTITY if identity transform.
<num children>     // the number of children for the node. 0 if no children.
<blank line>         // white space separates each node.

The tree is described in a depth first fashion, meaning all the descendants of a node precede any of the node's siblings in the file. To determine each model's transform, compose a transformation matrix by multiplying all the node transforms in the hierarchy file from the root to the model's node.

Part 3: Add bounding boxes to your hierarchy, display them on demand
Calculate max and min X, Y and Z for the subtree described by each node. When the user presses "b" or "B", display the bounding boxes described by these minima and maxima as wireframes. An example of this is shown in the image below.

When bounding box wireframes are displayed, pressing the "space bar" shows only the box around the hierarchy root. Each time the user presses the "space bar" again, the box moves to the next node in the hierarchy file. When the user presses "b" or "B" a second time, the boxes disappear.

Part 4: Render the current frame time in a heads up display
Compute and display the time it took to render the current frame in milliseconds (ms). This is called the frame time. Do this by finding the delta between the walk-clock time of the current buffer swap and the the previous. Optionally, also compute and display the frame rate (Hz). Display the frame time in the upper left corner of the window using text.

Part 5: Use view-frustum culling to accelerate your rendering
Define the six planes of the current view frustum and recursively compare the bounding box(es) of the hierarchy from Part 3 against those planes. You may use intersection code you find on online if you credit it appropriately.

If a box is entirely outside all planes, ignore all of its models and stop recursion (also known as culling). Otherwise, recurse through the node's children. If a node has no children, it is a leaf and the geometry (OBJ file) should be rendered.

As fewer models and triangles are rendered, your program should have lower frame times. The complexity and number of models your program uses must clearly demonstrate the performance advantage gained by view-frustum culling for full marks.

Extra Credit:
Extra credit opportunities include the following:
  • 5% include another mode that tests triangles against the view frustum
  • 1% support arbitrarily sized images (and interface windows)
  • 1% support multiple lights at arbitrary locations
  • 1% support additional image file formats
  • 1% implement alpha test in pixel shaders

Test triangles against the frustum too
Rather than simply rendering models when an intersecting bounding box has no children, test each triangle in the model against the frustum and render it only if it is not wholly outside the frustum.

Arbitrarily sized interface windows
Allow users to resize the interface window, and change the graphics window to match. This should effect every part of your assignment.

Extra credit: Multiple and arbitrarily located lights
Read in an additional lights.txt file that on each line, describes the location and color of a light (use three triples for a light's color: ambient, diffuse and specular). Render the scene with these lights. This should affect every part of your assignment.

Extra credit: Multiple image formats
Implement support for loading at least one additional image format beyond BMP (e.g. PNG, JPG, DDS).

Extra credit: Alpha Test
Implement alpha test in the pixel shader. Demonstrate alpha test working with the provided vase model and DDS texture.