I recently wrote a program for class the compared Phong and Gouard shading using the OpenGL shader language GLSL. To sum it up in a couple of sentences, Gouard shading uses per-vertex shading and Phong uses per fragment/pixel shading. Gouard will look more flat shading because the triangles (triangle mesh) will have a solid color. Phong shading colors per pixel so the triangles can vary in color inside the triangles. In GLSL the lightening calculation will be calculated in the vertex shader for Gouard and in the fragment shader for Phong.

I typical post the program, but it does not seem to work going through the browser. Here is an image of the program. I was not able to get the Phong to completely respond to changing the ambient, specular, and diffuse lightening. We used Processing as the host to run the vertex and fragment shaders. Here is the code I used in shaders to get it to run.

### Gouraud:

Vertex shader:

varying vec4 color; varying vec3 N; varying vec3 v; varying vec4 diffuse; varying vec4 spec; void main() { vec4 diffuse; vec4 spec; vec4 ambient; v = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec3 L = normalize(gl_LightSource[0].position.xyz - v); vec3 E = normalize(-v); vec3 R = normalize(reflect(-L,N)); ambient = ambientMat; diffuse = clamp( diffuseMat * max(dot(N,L), 0.0) , 0.0, 1.0 ) ; spec = clamp ( specMat * pow(max(dot(R,E),0.0),0.3*specPow) , 0.0, 1.0 ); color = ambient + diffuse + spec; }

Fragment shader:

varying vec4 color; void main() { gl_FragColor = color; }

### Phong:

Vertex shader:

uniform vec4 ambientMat; uniform vec4 diffuseMat; uniform vec4 specMat; uniform float specPow; varying vec3 N; varying vec3 v; void main(void) { v = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }

Fragment shader:

uniform vec4 ambientMat; uniform vec4 diffuseMat; uniform vec4 specMat; uniform float specPow; varying vec3 N; varying vec3 v; void main (void) { vec4 diffuse; vec4 spec; vec4 ambient; vec3 L = normalize(gl_LightSource[0].position.xyz - v); vec3 E = normalize(-v); vec3 R = normalize(reflect(-L,N)); ambient = ambientMat; diffuse = clamp( diffuseMat * max(dot(N,L), 0.0) , 0.0, 1.0 ) ; spec = clamp ( specMat * pow(max(dot(R,E),0.0),0.3*specPow) , 0.0, 1.0 ); gl_FragColor = ambient + diffuse + spec; }

I removed the code that controlled turning off certain lightning since it would not make too much sense without the host code. Here is a close up to show the difference.

**Checkout my other GLSL posts:**

Getting Started with GLSL

Setting up a program to run OpenGL GLSL

GLSL Bump Mapping

GLSL Normal Mapping

GLSL Desert Mirage/Heat Wave Effect

GLSL Edge Detection