The goal of this project was to implement Gouraud shading into our graphics system to simulate realistic polygon shading in 3D images. The idea behind this shading algorithm is to use point light sources to determine the color of each vertex of a polygon, and then fill the polygon using our standard fill algorithm, interpolating the shading across each vertex.
Description of the Task
Shading is an important part of making a realistic graphics engine. One of the simplest shading algorithms is Gouraud shading. In this method, one or more light sources are identified. Each object in the scene is defined as polygons with multiple vertices, each vertex has its own surface normal. The angle between the surface normal and the light source is used to determine how to shade the surface. For example, if a surface is pointed directly at a light source it will be fully shaded, but if the normal is pointed in the opposite direction, it will be dark. After calculating the color at each vertex, the color is interpolated across the entire polygon to create a realistic shading effect.
How the Task Was Solved
The first part of this code was defining the light source structure. This structure holds the variables that define the light source, which are the type of light, the color of light, the position of the light, and a float alpha. For our system, there are two types of light, ambient light, and point light. Ambient light sources effect all surfaces equally, while point sources have different effects depending on the angle between the light and the surface.
The colors used to shade each surface were calculated in the "color_calcShading" function, which uses two different functions to calculate the shading based on the type of light. Ambient light is calculated by the equation:
I = CLaCv
where CLa is the light associated with the ambient light source, and Cv is the color of the vertex.
The point light shading is calculated by the formula:
I = CbCLd(L- N) + CLdCs(H- N)n
Where CLd is the color of the light source, Cb is the color of the polygon's body, Cs is the color of the surface, L is the light source vector, H is the halfway vector, 45º from the normal, and N is the normal vector, and n is the surface coefficient, which describes how the light reflects off the surface.
What We Learned
We learned how to implement a simple version of shading by calculating the color at each vertex and then interpolating across. The concepts used in this implementation can be applied to other forms of shading, such as phong shading, which uses the same idea, but interpolates the surface normal across the polygon, and calculates the shading at each point.
The example of clean interpolation of colors in the image with borders of square being R=1.0, G=1.0, B=1.0 respectively and one being black.
The first problematic redering of the cube. As you can see, the polygons flicker.
With a lot of repairs in the code, we got a second, better looking cube:
Also, shaded cubism looks fairly OK, but for the weird edging effect.
Lastly, the starfuries were rendered, but for some reason, only a piece is visible.
Afterwards, I (Bogo) figured out with Professor Maxwell's help, that the problem was in the normals of the cube. After fixing them and a number of small amendments in the math, I obtained the following images. The cube remains moved, although it's center is at 0,0.
Lastly, the wrapping effect was repaired.
Also the furies were rendered. For an unknown reason, either adding the second one or rotating the system causes the rendering to stop after the first 94 polygons. The cause is under investigation, but in the meantime we managed to obtain this two images. First one is not rotated, the second one is just of one fury with weird artifacts (inspired by the Last Starfighter?)