CS 351 Assignment 9: Shading
Justin Russell, Nicki Ciociolo-Hinkell, & Adam Lowenstein
In this assignment, we implemented Gouraud shading for polygons with ambient and point light sources. To do so, we created functions called Module_shade, Polygon_shadeFill, and Color_calcShading. Module_shade and Polygon_shade fill were similar to functions we had created earlier in the semester (Module_draw and Polygon_drawFill, respectively), but the new implementation accommodated different light sources (defined by the light source data type) to allow shading. We also created a Color structure that defines colors as three floats (r, g, and b) between 0 and 1. To be able to make use of Color and Pixel datatypes interchangeably, we created two additional functions to convert between the two: Color2Pixel and Pixel2Color. The image below shows the a cube with point and ambient light sources generated using test code provided by Professor Maxwell:
In order to implement fully the Gouraud shading technique, we added and modified a number of previously-existing functions and added some new ones. Because shading is based heavily in vectors, we created a number of new vector functions. We also created light and color datatypes and adapted our library to accommodate them. Additionally, we spent a great deal of time going through our Polygon functions to make sure that all normals were created, initialized, and maintained throughout our execution. To generate correct normals, we modified Polygon_init to use the first three vertices in its vertex list to generate the appropriate surface normals for all vertices using the plane equation.
Algorithms & Pictures
Creating the light sources and properly shining light onto the polygons was one of the more challenging aspects of this project. To create a point light source, we used the algorithm provided in the course graphics specification. This algorithm takes in a body color, a surface color, the color of the light source, a light vector indicating the direction of the source, the surface normal, and a view vector. First, we calculated the halfway vector by summing the light and view vectors and halving the result (to approximate dividing by the size of the sum of their lengths). Then, we took the dot product of this value, H, and the surface normal, N, and raised that result to the power of the surface coefficient. After multiplying by the direct illuminant color (the color of the light) and the surface color, we had the surface component of point lighting. To generate the body component, we took the dot product of the light vector and the surface normal and multiplied by the direct illuminant color and the body color. Finally, we added the sums of the body and surface to get the appropriate color and shading of the point light source. This image shows the cube provided by Professor Maxwell rotated:
And this image is the rotating cubism graphic first generated in the z-buffer assignment. This time, however, it has shading:
This project taught us to implement Gouraud shading and solidified our understanding of illumination techniques. We are now capable of generating truly three-dimensional images.