Project 4: Lighting and Shading
This project is on OpenGL lighting and shading, and includes GLSL shader programs.
This project is due on Friday, November 2nd at 1:30pm. It will be introduced in lab 260 by Sid on Monday, October 29th at 2:30pm.
Note that while you are welcome to start working on this project immediately, we will not have covered all the material in class until Tuesday, October 23rd.
1. Lighting and Per Vertex Shading (50 points)
We provide source code to help you get started with the project. The code displays two spheres on the screen, deliberately at a low tessellation level (i.e., few triangles) to make the lighting effects you are implementing more obvious.
You should start by adding your mouse control code from Project 3. It does not have to work perfectly, but needs to at least somehow rotate the spheres and allow the user to zoom in. Then you should write classes to manage light and material properties (Light and Material). As a starting point, refer to the relevant sections in Chapter 5 of the OpenGL Programming Guide, as well as the OpenGL Lighting FAQ.
Then you need to do the following things:
- Display the two spheres from the starter code and and modify their material properties: one of them should be shiny and diffuse, the other only diffuse. They should both be white. (5 points)
- Your mouse control routines from Project 3 need to allow the user to modify the coordinate system of the spheres. The spheres should move together, they should always remain fixed with respect to one another. In this mode, the mouse control routines should not move the light sources. (5 points)
- Change the directional light from the starter code to a red point light. (10 points).
- Create a green spot light with a relatively narrow spot. In its initial position it should point to at least one of the spheres. The spot diameter should be smaller than that sphere so that the outline of the spot can be seen on the sphere, as well as the brightness gradient at the edge of it. (15 points)
- Support two keyboard keys: '1' and '2': The '1' key turns the point light on and off, the '2' key turns the spot light on and off, so that you can demonstrate the functionality of each light individually, as well as their combination. (5 points)
- Allow the user to move the light sources by applying your mouse control routines to them: whichever light source is enabled with the '1' and '2' keys should be affected by the mouse, which means affect their coordinate systems as if they were data models. If no light source is enabled, the mouse should move the spheres. Similar to Project 3, the 'r' key should reset the positions of all spheres and light sources. (10 points)
- OpenGL multiplies light position and direction with the Modelview matrix when they are set. Therefore, you need to modify the Modelview matrix with your mouse control routines to rotate the light sources, independently for each light source.
- The spheres are generated by the glutSolidSphere routine, which automatically generates normal vectors. To ascertain that these normals will survive scale operations correctly, you should use the following OpenGL command: glEnable(GL_NORMALIZE).
- By default, OpenGL uses a simplified model for the calculation of the highlights. For a more realistic model add this command to your code: glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE).
- In this (and all following) homework projects, there are no longer any restrictions on which OpenGL routines you are allowed to use.
2. Shader Programs (50 points)
In this part of the project, you will need to add support for per-pixel shading of the effect of your light sources from part 1 on the spheres, which will significantly improve the visual appearance of the light reflections on the spheres.
For Windows and Linux users, in order to expose OpenGL extensions, you need to download GLee and add the glee.h and glee.c files to your project files, or tell the linker to link with the GLee library (glee.lib or glee.dll for Windows, or libglee.a/libglee.so for Linux). OSX users will not need GLee, as OpenGL extensions are available by default.
If the above link doesn't work, we've uploaded GLee here.
We provide a sample shader class and three sample combinations of vertex and fragment shaders for you to familiarize yourself with GLSL shader programming. For this part of the project, extend the diffuse_shading shader to perform per-pixel Phong shading. The shader should use the properties of your light sources and materials. These properties can be accessed in the shader through the predefined gl_LightSource and gl_FrontMaterial variables.
- Create GLSL vertex and fragment shaders for the point light from Part 1 (15 points).
- Create GLSL vertex and fragment shaders for the spot light from Part 1 (15 points).
- Create GLSL vertex and fragment shaders with support for both light sources concurrently (10 points). For this you will have to merge the code of the two shader programs into one shader program. You would determine the final color by averaging the contributions of the light sources (cumulative_light = (light_a + light_b)/2).
- Demonstrate the scene with the two spheres from Part 1 with optional per-pixel shading: add support for the 'g' key to toggle your GLSL shaders on or off, to demonstrate the difference between OpenGL's built-in (per vertex) shading and your custom per-pixel shading. (10 points)
- While most CSE lab computers do, some older computers or simpler graphics cards do not support GLSL. Be aware that this might be a problem with your personal computer.
- It is more efficient to compute the reflection vector in the vertex shader. Then you pass it to the fragment shader as a varying parameter. OpenGL will automatically interpolate the vector at each pixel. However, you will have to re-normalize it in the fragment shader to make sure it is a unit vector.
Here are a few URLs with tutorials on how to write GLSL shader code. The tutorial at the first URL contains detailed instructions for how to do per-pixel shading for point and spot lights, including sample shader code.
- Lighthouse3D GLSL tutorials
- Clockworkcoders GLSL tutorials
- GLSL quick reference
- GLSL reference documentation
3. Extra Credit: Disco Dragon (10 Points)
Create a 3D scene with a dragon which is illuminated by colorful lights.
Load this OBJ file with the Stanford Dragon, which contains normals in addition to vertex coordinates and triangle connectivity, into your software program from parts 1 and 2. The Wikipedia page for OBJ files describes the data format. Modify your OBJ reader from homework assignment 2 to parse this file (2 points). If you are curious about the Stanford 3D model repository, you will find more information about it here.
Take a close look at the lighting of the dragon's surface to make sure that you read in the normals correctly:
Add keyboard support to switch between the spheres and the dragon by putting the spheres on the 's' key, and the dragon on 'd'. Both lighting approaches (fixed function and shader-based) need to work with the dragon. (2 point)
Add a large, flat ground plane to the scene by creating a large OpenGL quad, and place it under the dragon's feet in its coordinate system, so that it looks like the dragon sits on it. (1 point)
Add at least one additional light source to the scene. Add on/off toggle support for each additional light with the number keys ('3', '4', '5', etc.), and support them with your mouse control routines like the lights in part 1. (2 points)
Modify the light and material parameters of the scene to illuminate the dragon in an interesting way. At least one of your spot lights needs to automatically move around the dragon, creating a moving light spot on its surface. The light can move in a circle, or any other way of your choice. Add keyboard support for the 'a' key to toggle the animation on or off. (3 points)