CS 5610/6610 - Fall 2009

Homework Assignment 3

Shaders (150 points)

Handed out: Oct 22, 2009

Due: 11:59pm, Nov 5, 2009 (Thursday)

You will be using GLSL or Cg to program custom vertex and fragment behavior. The goal is to render a swimming fish (CS6610: bump-mapped).

The only geometry your program should be drawing for the fish should be a cylinder of radius 1 and length 10, with texture coordinates. The cylinder should only be drawn twice, once solid, and once in wireframe, and stored in two display lists. The user should be able to select one of these two with a GLUI radio-button.

You should write a vertex program that takes the given cylinder and warps it to a swimming (or not) fish. The radius (fatness) of the fish is up to you, is should be symetric about the horizontal axis and the shape of the fish is up to you. I suggest using a table to control the shape of the fish.

The fish midline towards the tail should describe a sin wave. It should have some number of 'wriggles' (wavelengths) along the back length of the fish body to simulate swimming. This is basically a sin-wave controlled offset in one dimension for the swimming action.

The phase of the sine function should be animated in time (the fish should appear swimming). This should be controlled with a GLUI speed control (speed up, slow down). When the fish stops, the wriggles should go to zero (no bends in the fish). As the fish speeds up, the amplitude of the sin wave should increase. If this doesn't make sense, send email to the class list.

CS5610 only:

The scene should include a floor, bump-mapped with a dune pattern (provided directly as a normal map image), and lit only with diffuse lighting. You can inspire yourself from the bump map shader example in the Cg Toolkit. Note, the normals in the normal map modify the Nz component, you'll have to swizzle to get it right for the floor (whose normal points in the +y direction). The Cg tutorials will help since all of the code is basically there except for the fish code (which is trivial to figure out). If you do not understand the fish code (how to form it) send email to the class mailing list.

CS6610 only:

In addition to bump-mapping the floor, the fish should be bump mapped and lit with both diffuse and specular lighting (using the Blinn half-angle formulation), computed per fragment. You will use the tangent space bump mapping method: for each vertex you will use vertex programs to compute the three orthonormal vectors of the tangent frame, the normal, tangent, and binormal, and then express the light and view vectors into this local frame. In fragment programs, you will perturb the normal using the normal map, and then compute the dot product between the light vector and the normal and the half vector and the normal. You will use the 2 dot products to compute diffuse and Blinn/Phong specular lighting. You can inspire yourself from the bump map shader example in the Cg Toolkit.
If the graphics cards we have in the Windows lab don't support the power function in fragment programs, you will have to look up the result of Blinn shading into a texture. The texture should contain at texture coordinate s= cos(h) the result of the lighting calculation (cos(h))^shiny, where cos(h) is the dot product between the (unit length) half vector (midway between the light vector and the view vector) and the local normal perturbed using the normal map. shiny is the Blinn specular exponent, which should be adjustable from the GUI (you may have to recompute the texture when it changes).
Here is a bump map for the fish and the associated color texture. Since the bump map is provided as a grayscale 'height field', you will need to convert it internally to a normal map, where each pixel contains an RGB value corresponding to a (nx, ny, nz) perturbation of the normal. Note that colors range from 0 to 1, while normal perturbations in x and y can range between -1 and 1 (nz will always be positive), so in your fragment program you will have to convert between the 2 ranges. Adding .5 and multiplying by 2 can be done by the 'input mapping' hardware, so it will not cost you one of the 9 register combiners "instructions". You can use the Nvidia bump-to-normal map conversion routines.

CS5610 and 6610:

The scene should include a floor, and a directional light.

The GLUI should provide the following controls:

1. Manipulation of the whole scene using the mouse (rotate, pan, zoom) just like the last assignment(s)

2. Manipulation of the fish using the arrow keys (translation in the floor plane).

3. Glui control for slowing and speeding the animation of the fish.

4. Glui control to switch between a wireframe fish and a shaded one.

 

Extra Credit

CS5610: you can get extra credit by implementing the part required for 6610.

CS5610 and CS6610

Possible ways to get extra credit include generating your own bump maps, or including other effects such as making the fish reflective (using a bump map and an environment map).

Submission

Please handin on the CADE system like the other assignments. The handin name for this lab is "openGL3". Name your zip/tar openGL3.[zip|tar.gz] where tar is used for Linux and win for Windows. Submit your executable along with the source code and the user's manual. Windows users should use the Zip utility and handin a single zipped file. Unix users should use the tar program followed by gzip to do the same.

 

Additional Resources

GLSL Example using ARB (works in CADE Windows and Linux Labs)
header for read routine SGI's "RGB" image format
source for read routine of SGI's "RGB" image format
example of how to use the image read routine
NVidia bumpmap to normalmap conversion
Sample code (GLUI) for loading a vertex program