This lab is designed to show you how shaders enable you to experience "life beyond Phong". Its goals are:
Provide practice with implementing illumination models using shaders
Provide practice in coding a shader from a written specification.
In this lab, you will be implementing a number of standard (and non-standard) illumination models using shaders. All of these shaders were described in Monday's lecture on BRDFs. The shaders that you will write are:
BASIC: Phong illumination model with multiple light sources
INTERMEDIATE: Ward's anisotropic illumination model
ADVANCED: The Strauss "quasi-physically-based" model
As with the previous assignment, two ZIP archives have been provided for you:
lab2files.zip
expands into a folder named lab2files which contains "starter"
code for your GLSL and RenderMan®
implementations
lab2template.zip
expands into a folder named lab2results which is a framework
into which you should place your solutions and resulting images.
As with the previous assignment, please place your solutions in the
lab2results folder, as follows:
Place your source code (not object files or binaries) in the appropriate
subfolder (e.g., your GLSL basic source files in the
GLSL/Basic folder, your RenderMan intermediate source
files in the RenderMan/Intermediate folder, etc.).
Place your result images in the Results subfolder, with
names of the form
lang-task.suffix.
For lang, use glsl or rman,
as appropriate; for task, use basic,
intermediate. or advanced;
suffix should match the type of the image file
you created (typically, tiff, png, gif,
etc.
Please use all-lowercase names for these files.
For example, the result image for the Basic RenderMan task might
be named rman-basic.tiff, and the Advanced GLSL task result
image might be named glsl-advanced.png.
Create a ZIP archive of your lab2results folder by using
the "Compress" entry of the right-click menu for the folder.
Submit this ZIP archive on one of the Ubuntu systems with the command
try wrc-grd shading-2 lab2results.zip
Both shading systems that we have looked at prefer the Phong-Blinn model (which makes use of the halfway vector) for basic illumination. In this part of the lab, you will be implementing the Phong model proper (i.e., using the R dot V definition) for specular reflection.
To make things more interesting, you must implement the RenderMan version
of this part without using the built-in diffuse and
specular functions.
You are free to use ambient if you wish.
You can either use the illuminance construct directly, or
write your own diffuse and specular functions (being sure to use
different names for them, like myDiffuse and
mySpecular).
(The advantage of the latter approach is that you can reuse these
function definitions in later parts of this lab by changing the function
definitions.)
You should apply the shader to the scene found in rit2.rib
in the RenderMan folder of the ZIP linked above.
Name the shader realPhong.
On examining the RIB file, you will see the sphere making use of
this shader.
Feel free to provide different values to
the shader parameters to see the effect on the rendered image.
By default, point light sources in RenderMan will attenuate
based on distance.
Although this will be useful to us when we get to the
lighting lab, for now, if would be better if this was not the case.
Thus, included in the RenderMan folder is a light source shader
plainPointLight (found in the file
plainPointLight.sl) which is referred to in the RIB file.
Be sure to compile this file before attempting a render.
To fully test the illuminance construct in the shader that
you created above, add additional light sources to the scene.
This will require modification of the RIB file rather than the
shader code (assuming your shader is correct).
(The RIB file already contains a plainPointLight light source
located at (0,10,-8) in the world.)
Also, feel free to move the light sources and re-render the image to
verify that the specular highlight moves with them.
For the GLSL part of the BASIC shader, you will implement Phong (proper) as a fragment shader working with multiple light sources. (You already have an example of a Phong shader implemented as a vertex shader; see the lab 0 shader files.) Use the code in the GLSL folder to start. Material properties and lights have been set up in this file; your shader should be able to access this OpenGL state directly.
In fixed-pipeline OpenGL (which we are using with GLSL 1.20), information
about light sources is held in a global array of structures named
gl_LightSource; each array entry describes one OpenGL light.
(element 0 is GL_LIGHT0, etc.).
The global gl_MaxLights tells you the size of the array.
Each array element contains color/intensity information, position,
spotlight characteristics, etc. for the corresponding light.
(We'll do more with this when we cover lighting later in the quarter.)
Similarly, material properties are held in a pair of global variables
named gl_FrontMaterial and gl_BackMaterial.
These variables contain the ambient, diffuse, and specular
characteristics (as vec4 data members) and the shininess (as
a float) of the object surface.
See the Phong vertex shader code from lab 0 for an example of accessing
the relevant data members of these data structures.
OpenGL positional lights can be distinguished from directional lights by
looking at the fourth component of the position data member:
if it's zero, this is a directional light, otherwise it's positional.
For simplicity, the driver program has been set up to use a directional
light.
There is no easy way to determine whether or not a specific OpenGL light
has been enabled.
I suggest that you communicate this information from the OpenGL program
to your shaders through a global uniform shader variable.
Recall that some of the information you need in order to implement Phong as a fragment shader is only available in the vertex shader. You'll need to process that data in your vertex shader and assign the results to global shader variables to pass them through (via interpolation) to the fragment shader. As with the RenderMan shader, try moving the light positions (from within OpenGL) and assure that the specular highlight moves accordingly.
This shader will focus on Ward's anisotropic shading model for specular highlights. You will modify your Phong implementation to use this instead of the specular function you created for Part 1. You should review Ward's paper, "Measuring and Modeling Ansiotropic Reflection" (Proceedings of SIGGRAPH 1992, pp. 265-272) to refresh your memory before attacking this part of the assignment.
You'll find a RenderMan implementation of this as a function in the
locillum.h header file from lab 1, and on page 229 of the
Advanced RenderMan textbook.
This function takes two additional parameters: a vector that is tangent
to the surface at the shading point (used to define the "x" direction
across the surface), and a second roughness value.
The two roughness parameters define the roughness in the "x" and "y"
directions across the surface.
For GLSL, you will need to adapt the RenderMan implementation. You are free to implement it as either a vertex shader or a fragment shader.
For part 3, you are to implement the Strauss model. This model is described in A Realistic Lighting Model for Computer Graphics (IEEE Computer Graphics and Applications, November 1990, pp. 56-64) and in the slides for the Reflection lecture. Don't let all the equations frighten you; they are just equations, and between the parameters to the shader and the constants defined in the paper you should find all the values needed for the variables in the equations. For GLSL, you are free to implement the shader as either a vertex shader or a fragment shader.