#version 400

in vec4 fragNormal;
in vec4 fragPos;
in vec4 eyePos;

uniform float     filterWidth;
uniform sampler2D mirrorTex;

out vec4 result;

float SchlickReflectionCoef( float NdotL )
{
	return 0.05 + 0.95 * pow( (1.0f-NdotL), 5.0 );
}

// This is the actual code that is executed.
void main( void )
{
  // We have a texture (for the reflection) computed from the eye's position.
  //    that means our texture coordinate depends on where this fragment falls
  //    in the framebuffer.  Use it's normalized device coordinate (in [-1..1])
  //    directly as a texture coordinate (but first scale and bias to [0..1])
  vec2  texCoord = 0.5 * ( fragPos.xy / fragPos.w ) + 0.5;
  
  // From fragment, compute the surface normal and the direction to the eye
  vec3  norm = normalize( fragNormal.xyz );
  vec3  toEye = normalize( -eyePos.xyz );
  
  // We need N dot E to compute our Fresnel approximation
  float NdotE = dot(norm,toEye);
  
  // Find the color of our mirror from a texture
  vec2 texSz        = vec2( textureSize( mirrorTex, 0 ) );
  
  vec4 avgColor     = texture( mirrorTex, texCoord + vec2(+filterWidth,+filterWidth)/texSz ) -
                      texture( mirrorTex, texCoord + vec2(-filterWidth,+filterWidth)/texSz ) -
                      texture( mirrorTex, texCoord + vec2(+filterWidth,-filterWidth)/texSz ) +
                      texture( mirrorTex, texCoord + vec2(-filterWidth,-filterWidth)/texSz );
                      
  avgColor          = avgColor / (4*filterWidth*filterWidth);
  
  // On back side of mirror, draw constant grey of 0.05.
  //    On front side, copy from the mirror texture & reflect 80% of the light.
  //    Also add in a slight bluish-tint based on the Fresnel reflection.  Here we
  //    use the Schlick approximation to the Fresnel term.
  result = gl_FrontFacing ? SchlickReflectionCoef(NdotE)*vec4(0,1,0,1) + avgColor*vec4(0.9,0.1,0.9,1)
                          : vec4(0.05);
}