CMSC 435/634: Introduction to Computer Graphics

Assignment 6
Shading
Due May 13, 2008

The Assignment

For this assignment, you will use OpenGL or XNA to extend your Assignment 2 (or the Assignment 2 sample code from the TA) to include procedural bark on the tree. Your bark should compute both color and bump or normal-map based lighting in a fragment/pixel shader. You may choose to also create a custom vertex shader, but this is not necessary for the assignment. You may also use color or noise textures within your shader.

For information on how to load and activate a shader, see the GPU shading class slides for OpenGL, or the XNA samples for XNA. You may use code from any of these sources as part of your assignment.

Some of the grade will be awarded for creativity, originality and effort.

Extra credit

Try to mimic a specific species of real tree as closely as possible. Include a JPEG photo of the tree you have tried to match along with your completed assignment.

Helpful information

Steve May's RMan Notes, from a course at Ohio State, is focused on RenderMan, but has many helpful tips on shader development strategies.

To create the bumps, you will need to construct a local tangent frame for the surface (sometimes called a TBN matrix for Tangent/Bitangent/Normal). It is easy to get the per-pixel normal. You will need to pass in the axis of the branch to align the direction of your bark. The two tangents can be computed by one of the usual orthonormalization procedures (cross products or Gram-Schmidt). These three vectors then make a 3x3 matrix to transform from object space to tangent space.

Here is a noise texture you can use, and some code to use it based on Olano, "Modified Noise for Evaluation on Graphics Hardware," In Proceedings of ACM SIGGRAPH/Eurographics Graphics Hardware 2005:

GLSL HLSL
uniform sampler2D ntex;

const float NTmod = 61.; // modulus in random hash
const vec4 NTcoef = vec4(13.,17.,7.,1.); // hash offsets

// noise with 2D input
float noise(vec2 p)
{
return texture2D(ntex, p/NTmod).r*2.-1.;
}

// noise with 3D input
float noise(vec3 p)
{
// input cell, location in cell, and fade blend function
float i = floor(p.z), f = fract(p.z), sf = (3.-2.*f)*f*f;

// hash z & z+1 for noise offsets
vec2 h = mod(NTcoef.z*(i+vec2(0,1.)),NTmod);
h = mod(h*h,NTmod);

// lookup noise and blend slices
vec2 g0 = texture2D(ntex, (p.xy+vec2(0,h.x))/NTmod).xy*2.-1.;
vec2 g1 = texture2D(ntex, (p.xy+vec2(0,h.y))/NTmod).xy*2.-1.;
return mix(g0.r+g0.g*f, g1.r+g1.g*(f-1.), sf);
}

texture ntex;

float NTmod = 61.; // modulus in random hash
float4 NTcoef = float4(13.,17.,7.,1.); // hash offsets

// noise with 2D input
float noise(float2 p)
{
return tex2D(TextureSampler, p/NTmod).r*2.-1.;
}

// noise with 3D input
float noise(float3 p)
{
// input cell, location in cell, and fade blend function
float i = floor(p.z), f = frac(p.z), sf = (3.-2.*f)*f*f;

// hash z & z+1 for noise offsets
float2 h = fmod(NTcoef.z*(i+float2(0,1.)),NTmod);
h = fmod(h*h,NTmod);

// lookup noise and blend slices
float2 g0 = tex2D(TextureSampler, (p.xy+float2(0,h.x))/NTmod).xy*2.-1.;
float2 g1 = tex2D(TextureSampler, (p.xy+float2(0,h.y))/NTmod).xy*2.-1.;
return (g0.r+g0.g*f)*(1-sf) + (g1.r+g1.g*(f-1.))*sf;
}

What to turn in

Turn in this assignment electronically by checking your source code into your Assn6 CVS directory by 11:59 PM on the day of the deadline. We will use a dated checkout for grading, so you will be graded on whatever has been checked in as of 11:59 PM. Be sure to include a Makefile that will build your project when we run make, and a readme.txt file telling us about your assignment. What (if any) help did you receive from books, web sites or people other than the instructor and TA? What extra credit features did you add?

Also submit everything we need to run your submission. Double check the output of cvs update after you submit to make sure you have not forgotten any important source files. Submit your Makefile, any headers and C/C++ files, and any other auxiliary files we might need. Be sure to comment your code! You will not be graded on the presence or quality of your comments, but we will look at your code and anything that helps us understand what you did (or were trying to do) can only help. In any case, your programs are expected to be robust and easy to understand.