------------------ VERTEX shader ------------------
#version 420
in vec4 vVertex; // Incoming vertex attribute
in vec3 vNormal; // Incoming normal attribute
smooth out vec3 vVaryingNormal; // NEW: Outgoing interpolated normal
smooth out vec3 vVaryingLightDir; // NEW: Outgoing interpolated direction to light source
uniform mat4 pMatrix; // Projection matrix
uniform mat4 vMatrix; // View matrix
uniform mat4 mMatrix; // Model matrix
uniform mat3 normalMatrix; // Normal matrix (3x3)
void main(void)
{
// Specify light position
vec3 vLightPosition = vec3(0.0, 0.0, 10.0);
// Get vertex normal in eye coodinates and output to fragment shader for interpolation
vVaryingNormal = normalMatrix * vNormal;
// Create the ModelView matrix
mat4 mvMatrix = vMatrix * mMatrix;
// Get vertex position in eye coordinates and normalize it by dividing by w
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
// Get vector to light source to output to fragment shader for interpolation
vVaryingLightDir = normalize(vLightPosition - vPosition3);
// Calculate the final vertex screen position
gl_Position = pMatrix * mvMatrix * vVertex;
}
----------------- FRAGMENT shader ---------------------------
#version 420
// Input from our vertex shader
in vec3 vVaryingNormal;
in vec3 vVaryingLightDir;
// Output fragments
out vec4 vFragColour;
void main(void)
{
vec4 ambientColour = vec4(0.2, 0.2, 0.2, 1.0);
vec4 diffuseColour = vec4(0.6, 0.6, 0.6, 1.0);
vec4 specularColour = vec4(1.0, 1.0, 1.0, 1.0);
// Start by adding in ambient colour
vFragColour = ambientColour;
// Calculate the diffuse intensity by getting the dot product of the normal and the light direction
float diffuseIntensity = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
// Add in diffuse colour calculated as multiplication of diffuse intensity and diffuse colour
vFragColour += diffuseIntensity * diffuseColour;
// Specular light
vec3 vReflectionVector = normalize(reflect(normalize(-vVaryingNormal), normalize(vVaryingLightDir)));
float specularIntensity = max(0.0, dot(normalize(vVaryingNormal), vReflectionVector));
// If the diffuse light is more than zero then (and only then) calculate specular contribution (pow function is expensive!)
if (diffuseIntensity > 0.0)
{
float fSpec = pow(specularIntensity, 32.0);
vFragColour.rgb += vec3(fSpec * specularColour.rgb);
}
}