Practical 1: Shadow Mapping and GLSL programming
Summary of the Practical
The goal is to implement the shadow mapping algorithm using GLSL.The program loads an object and displays it. The user interface lets you manipulate the object and the light source, and the shader takes care of local illumination. Your goal is to add shadow mapping to this shader, using what you learned in class.
Hardware and software requirements
- I recommend that you do the practical in groups of 2 or 3 students.
- You can do the practical either at home, on your own computer, or in the ARV room of the ENSIMAG building in Montbonnot. The computers in the ARV room should have all the required software installed.
- If you do it on your own computer, you will need:
- A computer with OpenGL capabilities (at least OpenGL 2.1, preferably 3.0 and above) (anything less than 3 years old should do, perhaps you'll need to install the latest drivers)
- A C++ compiler (but you should have that already)
- Qt, by
TrolltechNokia. (but you probably have it already as well) - (The project was made with Qt4, and doesn't work with Qt3.)
- libQGLviewer
a
very useful interface between OpenGL and Qt. (so useful you won't regret installing it) - api_graphics, a special API for loading GLSL shaders and interface with advanced features of OpenGL.
- Depending on your architecture and your version of OpenGL, you might need to install GLEW, and add the relevant lines in the code.
Instructions
First, download and uncompress the practical. Then, compile it. The directory contains a shadowMap.pro file, which you should use to create a Makefile (if this seems strange to you, spend some time reading a Qt tutorial)
The program should compile straight out of the box (you might have to edit the .pro file to adapt it to your configuration). It takes an (optional) argument which is the name of the model. It displays this model, with no shadow. There are other models in the model directory. Try moving the light source and the object: L sets the manipulated frame for the light source, O sets it for the object. Then right-click + drag moves the manipulated frame.
The program loads the shader in shader/shadow directory. All the functions you have to edit are in editing this shader, but you should look at the code of Viewer.cpp first.
- First, identify the lines that load the shader and the lines where we send it its parameters.
- Then, identify where we create the shadowMap itself, and how we pass it as a parameter to the shader.
- What other parameters are we sending to the shader?
- Finally, open the sources of the shader, and modify the vertex shader so that it passes the right value to SM_tex_coord. Remember, in order to compute the right value for SM_tex_coord, you need to convert the vertex position from object coordinates to light coordinates (the best way is probably to go through camera coordinates). Then, you need to convert the light coordinates (in [-1,1]^3) into texture coordinates (in [0,1]^3), through a simple scaling.
- Once you've set up the vertex program so it computes the right value for SM_tex_coord, you can uncomment the lines in the fragment program that use this value. You should now see your shadow map. Make a screenshot.
- Check that your program is correct by moving the object and the light source, and verify that the shadow and lighting are behaving correctly (it is a fairly common mistake to forget about the object modelling matrix). Make a screenshot.
- Your shadow map probably shows heavy Z-fighting in lit areas. Add some bias (in the fragment shader this time) to remove the Z-fighting. Play with the values of the bias (with an object touching the ground), test different formulas. Make a screenshot.
- Try different values of the shadow map resolution (smaller, larger).