CS155 Computer Graphics
Cheesy Shadow Labs
Today you'll build a little scene with simple shadows.
-
Create a new visual studio project with the following code: shadow.cpp.
Compile the program and run it. You'll see a red floor, a blue cube, and a white background.
-
The next step is to draw a basic shadow. To do so you need to
- Create the shadow projection matrix. There is actually a routine that does this for you, all you need to do is call it.
- Next push the current matrix.
- Now multiply the current matrix by the shadow matrix. (Check out glMultMatrixf().)
- Declare the diffuse and ambient material properties for the shadow; i.e. black.
- Redraw the cube.
- Pop the current matrix.
Compile and run the code. Problem? Currently the shadow occupies the same place as the floor so you may not see it.
To check that it is there, comment out the floor-drawing code, re-compile and run the program. You should see now be able to see the shadow.
-
Of course we want to have a floor. The problem of drawing two things in the same place is not uncommon and OpenGL
provides a solution, called polygon offset. You need to use the command glPolygonOffset(f,u), which
can be done in the init routine. (Check out the documentation to help figure out good values for f and u.)
You also need to enable polygon offset, glEnable(GL_POLYGON_OFFSET_FILL), before
drawing the shadow an disable it after, glDisable(GL_POLYGON_OFFSET_FILL).
-
Rather than drawing a black shadow, we'd like to blend it with the floor. To do this you need to
define a blending function, glBlendFunc(sFactor,dFactor), set the alpha channel of the shadow color, and enable blending, glEnable(GL_BLEND)
. Be sure to disable alpha blending when you are done with the shadow.
-
The shadow will not look right because each polygon of the cube is producing its own shadow. The final
shadow is darker in regions where several polygon shadows are drawn. To avoid this you need to use the stencil
buffer. Enable the stencil buffer before the floor is originally drawn. Whenever a pixel is drawn to the
frame buffer, you should write a "3" to the stencil buffer. When drawing the shadow, compare the stencil
buffer to 2. If the stencil value is greater than 2 then draw the shadow pixel and replace the stencil value
by 2. A shadow will never be drawn more than once for any pixel and only on pixels where the floor has
been drawn.
That is it!