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.
Aim
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:
- 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!
- 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.
- 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.
- 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.
- 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.
- 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:
- Implement displacement mapping.
- Implement environment mapping.
- Create a surface of genus > 1, and texture map it.
You may use the provided mesh class to help display or subdivide it.
- Create an interactive scene: Create a textured world and
let the user walk around in it.
- Experiment with different shaders: Experiment with toon
shading, or parallax bump mapping, or any number of other effects
with shaders. Try combining them for a good artistic effect.
- Use a geometry shader: Try to do displacement mapping on the
graphics card using shaders.
- Shadows: Try adding shadows to your scene, either using
shadow maps or shadow volumes.
- Ambient Occlusion: Try implementing a screen space ambient
occlusion algorithm.
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:
- p x y: Define a control point of the cross section's b-spline.
- v 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.
- twist tw: Specify a global twist for the track
- azimuth az: Specify a global azimuth for the track
- texture "texturefile.png" [rl] [rw]: Specify a texture for the track.
- bump "bumpfile.png" : Specify a bump map for the track
- -- 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.
- # 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
Submission
To submit this project, all of the following needs to be done by the deadline:
- Submit using the submit as8 command on the INST machines:
- A copy of your code, including the whole framework, the compiles on the platform you developed on.
- All shaders and textures you used.
- A README.txt containing: Your name, SID, Login and a description of the platform your code compiles on.
- FOUR
images of the shape you have designed from a view which allows the
whole thing to be seen: with Gouraud interpolation, then with Phong
interpolation, then with Phong interpolation and texture, and finally
with Phong interpolation, texture and bump mapping
- ONE animated GIF of your shape rendered with all features enabled. Show how the shading changes as it rotates.
- The trk file for your custom sweep
- Put on your class instructional website:
- A separate page for this assignment.
- On this page, the images you are turning in, as well as the coaster track files for them.
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.
Framework
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
- Linking troubles: If you have problems linking against the
libraries, especially if
you're on mac or *nix, it may be because the precompiled .a files
we've provided in your framework lib directory are not compatible
with your system. You can get a compatible version of GLEW or FreeImage
by going to the GLEW website or
FreeImage website
respectively, downloading the source package, and building it by
following the instructions (typically as simple as unpacking the
files and typing "make"). Then take the .a file and put it in the
appropriate subdirectory of your framework's lib directory.
Alternatively, if your OS has a package manager it is likely you can get
a version of these libraries from there.
- Hardware shader support:If you don't appear to have hardware
support for shaders
(ie the program fails when it tries to load shaders), try
updating your graphics card drivers. Even integrated Intel graphics chips
should be able to support GLSL with the latest drivers, using
partial software emulation. If that doesn't help, you can also try
using pure software drivers which are available from mesa3d.org
- Shape is white and gl is being sent invalid values: Don't
worry -- that's
actually how we expect it to look before you fill in the needed code to
complete
the assignment.
- Other problems: Let us know by email and/or newsgroup. Also be
aware that the hive cluster in soda 330 should work, so you may develop
from there.
Implementation Tips
- Dimensions of image sizes for textures should be a power of two along
each axis to play nice with your graphics card memory.
- Chapter 17.3.4 (2nd ed) includes an example fragment shader which
implements
phong interpolation. Note that in the second edition the code is
incorrect (missing a
normalization, uses blinn-phong model instead of phong despite saying
phong). However, you can use this to get a feel for the language.
- GLSL documentation is also available at http://www.opengl.org/documentation/glsl/
- Hints and suggestions are spread throughout the code, search for HINT
and TODO in the shaders and the cpp files.
- Most of your code can go in the shaders, the renderSweep
function and the computeNormalMapFromHeightMap function.
- The default scene has an arbitrary mesh object in it just to
demonstrate the mesh class, which is there to help with extra credit
options. Go ahead and remove that if you don't want to use it.
- Note that texture coordinates in OpenGL wrap by default, and this
default has not been changed by the framework. This makes a `tiling'
texture mapping like the one requested for the sweep easier to
implement.
- Be aware that "varying" variables can be set in the vertex shader and
then read back in the fragment shader, where they will have been
automatically interpolated for you.
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.
Errata
- In the (optional) mesh class, there was an error in the handling
of obj files without texture and normal information that would cause a
crash on displaying or subdividing those meshes. It has been
fixed in the framework, and corrected files are posted here: mesh.h, mesh.cpp.
- In the provided shader code, the line
"cl * pow(max(0.0,dot(r,normal)),p);"
should say
"cl * pow(max(0.0,dot(r,-e)),p);". Correcting this is optional.
- In the hints in sweep.cpp, glVertexAttrib3dARBv should be
glVertexAttrib3dvARB. Other functions such as glVertexAttrib3fARB could
also be used.