#version 330

// Uniforms

uniform vec4 ambientColour;

uniform vec4 diffuseColour;

uniform vec4 specularColour;

uniform sampler2D colourMap;

uniform sampler2D normalMap;

uniform float qUniform; // A value to manipulate our lighting by when surface is facing away from light source

// Input from our vertex shader

smooth in vec3 vVaryingNormal;

smooth in vec3 vVaryingLightDir;

smooth in vec2 vTexCoords;

// Output fragments

out vec4 vFragColour;

void main(void)

{

const float maxVariance = 2.0; // Mess around with this value to increase/decrease Normal pertubation

const float minVariance = maxVariance / 2.0;

// Create a normal which is our standard normal + the normal map perturbation (which is going to be either positive or negative)

vec3 normalAdjusted = vVaryingNormal + normalize(texture2D(normalMap, vTexCoords.st).rgb * maxVariance - minVariance);

// Get our diffuse intensity as a dot product which is NOT limited 0..1

float diffuseIntensity = dot(normalize(normalAdjusted), normalize(vVaryingLightDir));

vec3 colour = vec3(0.0);

// If the surface is facing the light then shade as normal

if (diffuseIntensity > 0.0)

{

colour = (diffuseIntensity * diffuseColour.rgb) * texture2D(colourMap, vTexCoords.st).rgb + ambientColour.rgb;

}

else // Otherwise use the modified light model

{

colour = (diffuseIntensity * diffuseColour.rgb * ambientColour.rgb * qUniform) + ambientColour.rgb;

}

// Set the almost final output color as a vec4 - only specular to go

vFragColour = vec4(colour, 1.0);

// Specular light

vec3 vReflection = normalize(reflect(-normalize(normalAdjusted), normalize(vVaryingLightDir)));

float specularIntensity = max(0.0, dot(normalize(normalAdjusted), vReflection));

// Add in specular component

if (diffuseIntensity > 0.0)

{

float fSpec = pow(specularIntensity, 64.0);

vFragColour.rgb += vec3(fSpec * specularColour.rgb);

}

}