Project4Fall11
Contents |
Project 4: Lighting, Shading, Texturing
This project is on OpenGL lighting and texturing, and includes GLSL shader programs. In contrast to project 3, where you worked on your own software rasterizer, we return to the OpenGL renderer for this and all remaining projects in this course. From now on there are also not going to be any limitations on which OpenGL functions you are allowed to use.
This project is due on Friday, October 28th at 1:30pm (the day after the midterm exam). It will be introduced in lab 250 by Alfred Tarng on Monday, October 24th at 4pm.
Note that while you are welcome to start working on this project immediately, we will not have covered all the material in class until Thursday, October 20th.
OpenGL Extensions
For Windows and Linux users, in order to expose OpenGL extensions, you must download GLee and add the glee.h and glee.c files to your project files, or tell the linker to link with glee.lib/glee.dll (Windows) or libglee.a/libglee.so (Linux). The shader code (shader.h) references glee.h. For OSX users, OpenGL extensions are available by default and shader.h will include OpenGL/gl.h
1. Lighting (30 points)
We provide base code to help you get started with the project. The code displays two simple spheres on the screen, deliberately at a low tesselation level to make the lighting effects you are implementing more obvious.
You should start by replacing the matrix class in the base code with your own. Then you should write classes to manage light and material properties (Light and Material). You will also need to add your trackball functionality from project 2 to your application. If it never worked correctly that is acceptable, as long as it rotates the object space about its origin.
To get full credit for this part of the homework project you need to do the following things:
- Display the two spheres from the base code and and give them material properties: one of them should be shiny and diffuse, the other one only diffuse (5 points).
- Create two light sources: one point light and one spot light. The spot light should point to one of the spheres and the spot diameter should be smaller than the sphere so that the outline of it can be seen, as well as the brightness gradient at the edge of it. (15 points)
- You need to support two keys: 'p' and 's': The 'p' key turns the point light on and off, the 's' key turns the spot light on and off (both are toggle keys), so that you can demonstrate the functionality of each light individually, as well as their combination. (5 points)
- You need to use your trackball routine to allow the user to rotate the point light (not the spot light) around the center point between the two spheres. The spot light can remain in place. (5 points)
This URL provides a good summary of OpenGL lighting and materials.
Note that OpenGL transforms the light position and direction with the current modelview matrix. Therefore, you need to set the modelview matrix to the correct transformations for rotating the point light source, and identity for the spot light source before setting the light position.
Note: To make sure that your normal vectors will be scaled to unit length automatically, you can use the following code:
glEnable(GL_NORMALIZE); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
2. Shader Programs (40 points)
We provide a sample shader class and three sample combinations of vertex and fragment shaders for you to get familiar 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. You will need to create separate shaders for the point light (15 points) and the spot light (20 points). You will need to demonstrate the scene with the two spheres from Part 1. Add support for the 'g' key to toggle your GLSL shader on or off, to demonstrate the difference between OpenGL's built-in shading and your custom per-pixel shader. (5 points)
Notes
- 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.
- For this project it is sufficient to support just one concurrent light source. However, you will need to support the point light as well as the spot light in your scene, just assume that they will never be enabled at the same time.
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. Texturing (30 points)
In this part of the project you will learn how to render textured surfaces and build a demo program. First, get familiar with OpenGL texturing by reading the relevant chapter in the OpenGL programming guide, available online here. An additional tutorial is available here.
We provide a sample program which loads a PPM file and uses it as a texture for a quad. We also provide a sample image file. The image file is 1024x512 pixels, so that it can readily be used as a texture without resizing to power of two widths.
Use this image as a texture to map on a cylinder. You will need to write your own algorithm to create the cylinder mesh, which you might have already done for a previous homework project. For each vertex, calculate the correct s and t coordinates for the texture, pass them to OpenGL with the glTexCoord command, and draw the texture on the cylinder (20 points). Set the cylinder's circumference to twice its height so that the texture will not get distorted (5 points). Add code to slowly spin the cylinder about its axis of symmetry by using glutIdleFunc or glutTimerFunc (5 points).
4. Extra Credit (10 points)
Modify your code for problem #3, the textured cylinder, to play back a short video clip on the cylinder and run it in a loop so that it starts over when it reaches its end. In order to load the textures for the video, use glTexImage2D only the first time you bind the texture object, and use glTexSubImage2D thereafter, updating only the texture data but not recreating the texture object, which improves rendering performance. Use either this sequence of PPM images of a galloping horse by Eadweard Muybridge, which gets you 5 points, or create your own video clip which gets you 10 points of extra credit.
Suggestions for creating your own video clip:
- Record a clip with your digital camera or cell phone.
- Download a video clip from the internet.
- create a stop-motion clip from photographs or images you create yourself or find on the internet.
The clip must consist of at least 10 frames. Note that OpenGL requires power of two textures for the glTexImage commands so you will most likely have to resize your frames. We suggest resizing to 512x256 pixels. To do this we recommend IrfanView for Windows or ImageMagick for Linux. If you have a video file and need to turn it into a series of PPM image files, we recommend the VideoMach utility for Windows, or ffmpeg for Linux. All the above mentioned software tools are freeware.