3.9 - Surface Normals

From the previous section you learned how to model the appearance of an object’s surface using reflected light. The fundamental property of the surface that was used to calculate the colors was the surface normal. Tricks can be done with the surface normals to enhance the visual rendering of objects. The following introduces a few of these “tricks”.


One normal per face

One Normal Vector Per Triangle

This is the default behaviour. Every pixel on a face will have the same color. This is referred as “flat shading”. (If a normal vector for a triangle is not specified, it can be calculated by taking the cross-product of two of the triangle’s edges.)

One Normal Vector Per Vertex


One normal per vertex

If you specify a different normal vector for each vertex, you can calculate a different color for each vertex. Then the colors for each pixel across the face can be interpolated from the vertex colors. If the vertex normal vectors are set correctly, the face will have a curved appearance (as opposed to a flat appearance). (This technique is named after its inventor and is called Gouraud shading)

You will get more accurate coloring across a face if you interpolate the normal vectors from the vertices across the face and then recalculate the fragment color using the interpolated normal vector. This method takes longer to compute, but gives smoother color gradients. This is called Phong shading.

Both techniques are called “smooth shading”.

One Normal Vector Per Pixel


One normal per pixel

You can control the color of individual pixels on the surface of a triangle by specifying a unique normal vector for each pixel. This is done by creating an image, where each “pixel” in the image is not treated as a RGB value, but rather as an <dx,dy,dz> normal vector. This is called a bump map. Here is an example rendering using bump maps.


A “bump mapped” object. (1)

WebGL Implementation

A programmer can implement any of these techniques in their shader programs. One normal vector per face and one normal vector per vertex are implemented in vertex shaders. Phong shading and bump maps are implemented in fragment shaders because they calculate the color of individual pixels.


flat shading
A single color is calculated for face.
Gouraud shading
A different color is calculated for each vertex.
Phong shading
A different normal vector is used at each pixel to calculate a new color.
smooth shading
Use either Gouraud shading or Phong shading to vary the colors over a face.
bump map
Use a unique normal vector at each pixel to calculate a color. The surface can be made to appear to have bumps.
Next Section - 3.10 - Lines