Lab 5: Lighting & Shaders
CS 445: Computer Graphics,
Fall 2012
Due Dates:
Part 1: 5pm, Thursday, Nov 1
Part 2: 5pm, Tuesday, Nov 6
Goals
- Learn about vertex and fragment shaders.
- Learn the basics of GLSL (shading language)
- Learn how phong lighting is implemented in shaders.
- Learn how the shaders interact with the Opengl program.
- How are lights placed in the scene.
- What is the difference between Gouraud vs Phong Shading (this is different from Phong lighting!)
Resources
- Notes and readings will be provided and discussed during class including
slides from a siggraph workshop and several pages from Mike Bailey's Graphics Shaders book.
These will be available on \\home\classes\ in the folder \gorr\cs445Fa12\lab5Materials\Readings
It is your responsibility to read and learn the material.
- Your textbook introduces shaders beginning on p. 85. In particular, the InitShader function is described.
- Your textbook lists the GLSL openGL functions starting on p. 695
- Reference pages for GLSL
Part 1: Questions
Go over the material discussed in class and read the above references. You should be able to answer the
following questions.
- Where does each shader fit into the graphics pipeline?
- What functions are typically done in a vertex shader? In a fragment shader?
- At a minimum, what must the vertex shader do? At a minimum, what must the fragment shader do?
- What functions are still done by the fixed pipeline and so do not need to be done in the shaders?
- What are attribute variables and uniform variables? What does "in" and "out" mean?
- What are some differences between GLSL and C or C++ ?
The Car
You are already familiar with the Phong lighting model which you implemented in your ray tracer. In this
part of the lab, you are
to understand the Phong lighting model as implemented in the shaders. There are two common ways of doing this:
- Gouraud Shading - color calculations are done in the vertex shader and interpolated for the fragment shader.
- Phong Shading - color calculations are done in the fragment shader. This gives much better results.
The base color of the surface may be obtained in several different ways. We will discuss each of them:
- Using the "colors" array that you created when you modeled the object.
- Using a uniform variable (model_color) which gets set when you are about to draw the object
- In the shaders.
Start with the car navigation program you used from the last lab. Your
job is the modify it so that it can handle lighting. Here are the changes you need to make:
- On \\home\classes\, in our class folder (\gorr\cs445Fa12\lab5Materials), you will see a folder containing the different
shader files that you need to use for this lab.
- On \\home\classes\, in our class folder, you will see a file called CodeSnipptes.txt which
contains some of the code you need to bring into your main.cpp. We will go over the items
in this file in class.
- You need to make sure that the normals are calculated properly for your shapes. The
Cube class has an error in the quad method - you need to add the line:
vec4 norm = face_normals[n];
at the beginning. The Cylinder class ok.
- The drawWheel method in the Car class has one of the disks facing in the wrong direction. You
want the outward normal of each disk to face away from the center of the wheel. You will need to
think about how to fix it.
- In each of the shapes (Cube, Cylinder, Disk), you also need to update createVAO() so that the buffer loads the normals.
CodeSnipptes.txt contains what this should look like for the Cube. You need to modify this method in the other
shapes.
- In Shapes.cpp, you no longer need to draw the wire frame objects because the lighting will
make the shapes easy to see. In each of the draw methods in Shapes.cpp, comment out the wire part.
CodeSnipptes.txt contains what the drawCube method would look like.
- In the display() method of main.cpp, you need to set the location of the
light. To help you see where the light is, draw a cube at the location of the
light.
- Once you have calculated the position of the light as it should be in the shader, you need
to set the shader's corresponding light parameter:
glUniform4fv( glGetUniformLocation(program, "LightPosition"), 1, l_position );
where l_position is the value of the light position in eye coordinates (which is what the shader wants).
- Try running the code, first with the simple shader that you used last week, and then with the Gouraud and Phong shaders.
- Once you feel confident that the code runs and does what you expect, add code that
animates the camera so that it rotates around the y axis of the world coordinate system.
Also, you might want to add key presses that change the location of the light.
This movement will enable you to really test to make sure that the lighting is working.
- Finally, figure out how to modify the code so that the light moves as though it is attached to
the camera.
Car with Gouraud Lighting
Car with Phong Lighting
No later 5pm on Thurs, Nov 1, demonstrate this part of the lab
(no need to submit this part of the code via WISE Assignments).
Part 2: Fractal Landscape
This part of the lab will take some work so please get started early!
Download the zipped file containing the files
FractalLandHeights.cpp and FractalLandHeights.h, which will generate a height map, i.e. a
2-dimensional grid of values that
represent heights (the y-value) on a square grid (x and z). Read the comments at the top of
FractalLandHeights.cpp to see what it does and how the heights are stored.
You need to create a new class e.g. called FractalLandShape (along the lines of the Cube or Disk) which takes
the heights and generates a list of triangles (vertices) and normals. You need to think
about how to calculate the normals efficiently. Note, the normal at a vertex needs to be the average of
the normals of the surrounding triangles. Work it out first with pencil and paper.
The colors can either be implemented in your FractalLandShape class as a colors array
or you can choose to implement the color as a color map
in the shader (your choice). Either way, you will need to write a color map function which
takes a y-value and returns a color. GLSL has some nice smoothing functions
which you can use if you do it in the shader (preferably fragment over vertex, for the same reason
Phong Lighting is better done in the fragment shader).
In main.cpp, create a new FractalLandShape object and render it. Include a light source which you can
move around (along x, y, z). Include a cube that sits at the light location.
Moving the light will help you test whether your normals and light location are
set properly.
No later 5pm on Tues, Nov 6, demonstrate your program in lab
and submit this code via WISE Assignments.