As I understand it, Gouraud shading calculates light color for each vertex and does interpolation on that color, whereas Phong shading interpolates the normal for each pixel and calculates light color based on that interpolated value.
However, when I tried to derive the light color mathematically, I ended up with the same formula for both ways!
(Where n1 and n2 are the normals of the two vertices, t is the coefficient for interpolation, L is the light direction, and the plane on the top and the dotted line means screen and a pixel.)
The light colors for the two methods are derived as:
Gouraud:
L = t*dot(n1,L) + (1-t)*dot(n2,L)
Phong:
L = dot(t*n1+(1-t)*n2,L)
and the results are the same.
Can anyone tell me what's wrong with my derivations?
While at Gouraud shading the light is calculates per vertex (Vertex shader), at Phong shading the light is calculates per fragment (fragment shader).
Therefore, Gouraud shading calculates the light for the vertices (corners) of a primitive and interpolates the light for the fragments covered by the primitive.
With Phong shading, the light is calculated separately for each fragment.
In general a light is computed by the Bidirectional reflectance distribution function. The function computes the reflectance of the light on a surface and depends on the vector of the incident light, the point of view and the normal vector of the surface.
At Gouraud shading the vertex color (reflectance) is interpolated and at Phong shading the 3 vectors are interpolated. That won't make any difference if the function c = brdf(l, v, n) is linear, where c is the color, l is the light direction, v is the view vector and n is the normal vector (e.g. Lambertian reflectance). But if the light model is not linear (e.g. Blinn–Phong), then the linear interpolation of Gouraud shading leads to different results.
Compare Gouraud shading and Phong shading
See also:
GLSL fixed function fragment program replacement
Phong and Gouraud Shading
Gouraud shading / Phong shading