Geometric Transformation and Viewing

Coordinates Pipeline

After reaching the window space, we will have the xy-coordinates of the fragment, and its depth (z-value) and reciprocal of

GLM Library

You can use arrays to represent the 4x4 matrix, arranged in column major order.

Lighting computation: Eye space

With a local illumination model e.g. Phong Model (i.e. ignore other objects’ reflections)

Vertex shader – Gouraud shading

// ec = eye coordinate
vec3 ecNormal = normalize(NormalMatrix * vNormal);
vec4 ecPosition4 = MVMatrix * vPosition; // homogenous coordinates
vec3 ecPosition = vec3(ecPosition4) / ecPosition4.w; // euclidean space
gl_position = MVPMatrix * vPosition; // clip space coordinates

vec3 viewVec = -normalize(ecPosition); // as eye is at origin
vec3 lightPos = vec3(LightPosition);
vec3 lightVec = normalize(lightPos - ecPosition);
vec3 reflectVec= reflect(-lightVec, ecNormal); // note lightVec must be inverted!

// our dot products
float N_dot_L = max(0.0, dot(ecNormal, lightVec));
float R_dot_V = max(0.0, dot(reflectVec, viewVec));

// exponent n
float pf = (R_dot_V == 0.0) ? 0.0 : pow(R_dot_V, MatlShininess);

v2fColor = LightAmbient * MatlAmbient + 
    LightDiffuse * MatlDiffuse * N_dot_L + 
    LightSpecular * MatlSpecular * pf;

Fragment shader

fColor = v2fColor;

Vertex shader – Phong shading

out vec3 ecPosition;
out vec3 ecNormal;
// computed as above, gl_position set as above

Fragment shader – Phong shading

uniform mat4 ViewMatrix;
uniform mat4 MVMatrix;
uniform mat4 MVPMatrix;
// matrial attrbutes

vec3 viewVec= -normalize(ecPosition); // ecPosition is the interpolated coordinate from the rasterizer
vec3 newNormal = normalize(ecNormal);
vec3 lightPos = vec3(LightPosition);
vec3 lightVec = normalize(lightPos - ecPosition);
vec3 reflectVec= reflect(-lightVec, ecNormal); // note lightVec must be inverted!

// our dot products
float N_dot_L = max(0.0, dot(ecNormal, lightVec));
float R_dot_V = max(0.0, dot(reflectVec, viewVec));

// exponent n
float pf = (R_dot_V == 0.0) ? 0.0 : pow(R_dot_V, MatlShininess);

v2fColor = LightAmbient * MatlAmbient + 
    LightDiffuse * MatlDiffuse * N_dot_L + 
    LightSpecular * MatlSpecular * pf;

Basically move the lighting computation from the vertex shader to the fragment shader.