CS184 AS8: Textured Smooth Surfaces

DUE DATE: Wednesday March 30, 11:00pm
You may work with a partner for this assignment.

Compatibility Warning! This assignment requires hardware shader support and some additional libraries to run. It will probably not run on the sun machines, computers from ~2005 and earlier, or some netbooks. It may also take some additional work to get running. If it doesn't work "out of the box," see the notes at the bottom of this page for more help.


In this assignment we use the track generator part of As#7 to create ribbons, sculptures, worms, or snakes with textured surfaces.
You will learn how to make smooth -- or smooth-looking surfaces, and how to make these surfaces more interesting with texture-mapping and with bump-mapping.

Minimum Specifications

We will provide you with a reduced rollercoaster generator/renderer that has the supporting columns stripped out. We will use the remaining sweep generator to accomplish the following:

  1. Creating an interesting shape: by modifying the spline control points and using an interesting cross section. For instance try to bend a thick worm into a tightly knotted, tangled ball ... BE SURE TO MODIFY the provided curve shape and cross section!
  2. Create a really smooth surface: by replacing the polygonal cross section with a closed B-spline and rendering the whole sweep as a finely sampled B-spline surface.
  3. Write GLSL shader code to render your shape with phong interpolation. Use a phong illumination model (not blinn-phong) and perform your lighting calculations in eye space (not tangent space). You may customize your shader to the specific lights in your scene. Pressing 'P' should toggle between your Phong interpolation and Gouraud interpolation. (Note: The Gouraud interpolation mode doesn't have to support the texture mapping or bump mapping features you'll add below -- it's just to illustrate the lighting difference.) See the implementation tips section for more information on GLSL shaders.
  4. Texture-map this surface: Use one or more texture tiles and place them on your surface to create a seamless patterning. Support the texture mapping in your shader, and use a uniform input variable to toggle it on and off when 'T' is pressed.
  5. Bump-map this surface: Add support for bump mapping to your shaders and use one or more bump-map tiles to decorate your surface. Use a uniform input variable to toggle the bump map on and off when 'B' is pressed.
  6. Combine texture-mapping and bump mapping: pick two maps that yield correllated results, e.g. something like a stained-glass window: enhanced, raised, gray lead-beads that separate facets of bright colors.

Extra Credit ideas:

Sweep File Format

We provide a simple custom file format to specify a (closed) sweep, an example of which is provided with the framework. The format provides the following commands:
  1. x y:  Define a control point of the cross section's b-spline.
  2. x y z [az] [scale]:  Define a control point of the sweep curve's b-spline. [az] is an optional parameter, which specifies a local azimuth value on the spline. [scale] is an additional optional parameter with locally adjusts the cross section size. Note that these azimuth and scale values are smoothed by the b-spline function just like the x, y, z.
  3. twist  tw:  Specify a global twist for the track
  4. azimuth  az:  Specify a global azimuth for the track
  5. texture  "texturefile.png" [rl] [rw]:  Specify a texture for the track.
  6. bump  "bumpfile.png" :  Specify a bump map for the track
  7. -- pattern repetition: The optional integer parameters [rl] and [rw] specify how many times the texture repeats in the longitudinal (length) direction [rl] , and in the lateral (width) direction [rw] over the whole tubular surface. The default for these values is 1.
  8. #  comment:  Lines beginning with '#' are comments

Example Sweep File

# basic sweep example

# global azimuth of 45 degrees everywhere - as a starting base for further modifications.
azimuth 45
# global twist 360 degrees - i.e., a linearly increasing azimuth, starting at 0 degrees and ending at 360 degrees.
twist 360
texture "tracks.png" 30 2
bump "tracksBumps.png"
# a simple cross section
p -1 1
p 1 1
p 1 -1
p -1 -1

# a simple knotted loop (trefoil knot).
v    10.0 -2.0 4.0
v    -6.732 7.66 -4.0
v    -6.732 -7.66 4.0
v    10.0 2.0 -4.0
v    -3.268  9.66 4.0
v    -3.268  -9.66 -4.0


To submit this project, all of the following needs to be done by the deadline: Windows Users: The grader should ONLY have to open your .sln file and press F5 to build and run your solution.
*Nix Users: The grader should ONLY have to run make with the appropriate makefile to build your project. Thus, for Mac and Linux make and for solaris gmake.

Note: The submit program retains the directory structure of what you send it. Thus, we recommend making a new directory for your assignment on the server, cd'ing into that directory, copying the whole framework with your code into this directory, and running submit as8 to easily submit the whole project to us.

Group submissions

For this project, groups of two are allowed. If you're working in a group, only one of you should submit the full project results; the other should only submit the README.txt file. Both of you should include your partner's name in the README.txt file.


See the Framework page here. Version 6 of the framework provides code to load and display sweeps, as well as code to load textures and GLSL shaders.

Note that this assignment does require more powerful graphics hardware than previous assignments; if your computer doesn't support pixel shaders, the computer in the labs should work. Specifically we've verified that the hive machines in soda 330 work, and everyone should have access to this room.

Getting the framework to compile and run

Implementation Tips

Bump Mapping Notes

The framework asks you to do bump mapping in this assignment through a several step process: (1) convert a height map to a normal map, (2) upload a local coordinate frame to the vertex shader, and (3) transform the normal from the normal map into the local coordinate frame in the fragment shader.

The local coordinate frame consists of a tangent, bitangent and normal vector. The normal is the familiar surface normal, while the tangent and bitangent are orthogonal vectors both tangent to the object surface. These terms may be familiar from the discussion of Frenet frames of curves, which consists of tangent, binormal and normal vectors -- the difference being that a curve has two natural normal vectors (normal and binormal), while a surface has two tangent vectors instead.

To convert a height map to a normal map, use finite differences to compute the tangent vectors of the height map in X and Y, then a cross product to compute the normal. The normal can be scaled to adjust the effective heights of the height map values. Each normal can then be written into a normal map image by mapping the range [-1,1] onto [0,255] for each color channel (XYZ maps to RGB). Then you'll have to map it back from the range [0,1] to [-1,1] in the fragment shader.

To tranform a vector from world space to eye space in the vertex shader, normally would use gl_ModelViewMatrix. Since normals don't transform as other vectors do (inverse transpose, etc), gl_NormalMatrix is provided to tranform normals from world to eye space.