gluLookAt
gives OpenGL $u,v,n$ vectors to perform view transformationAfter reaching the window space, we will have the xy-coordinates of the fragment, and its depth (z-value) and reciprocal of
You can use arrays to represent the 4x4 matrix, arranged in column major order.
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.