uniform sampler2D Normal;   // eye space normal

varying vec3 lightPos;
varying vec3 eyePos;
varying vec3 lightColor;
varying vec4 projPos;

varying float invRadius;
varying float extraParam;

const vec2 bitSh = vec2(1.0 / 256.0, 1.0);

void main()
{
  vec2 texCoord = projPos.xy / projPos.w * .5 + .5;
  
  // normalize eye vector
  vec3 e = normalize( eyePos );

  vec4 buff = texture2D( Normal, texCoord );
  
  // recover position from gbuffer
  float depth = buff.w;
  vec3 objPos = e * depth;
  
  // distance from light to geometry
  vec3 l = objPos - lightPos;
  float attenuation = length( l ) * invRadius; // radius is 1 over radius
  // discard if outside radius
  attenuation = 0.95 - attenuation;

  //if( attenuation < 0.0 ) discard;

  attenuation = max( attenuation, 0.0 );
  // quadric vs linear fall off
  attenuation *= attenuation;//

  //attenuation = 0.1;
  
  // unpack normal
  vec3 norm = 2.0 * buff.xyz - 1.0;
  
  // standard ndotl
  l = normalize( l );
  float ndotl = max( dot( norm, -l ), 0.0 );

  vec3 h = -normalize( e + l );
  float ndoth = max( dot( norm, h ), 0.0 );

  // n of 32
  //float spec = pow( ndoth, 32.0 );
  //spec *= (1.521919 * ndotl * attenuation); // scaling by normalization factor (n+2)(n+4)/8pi(2^(-n/2)+n), with an n of 32
  
  // n of 4
  float spec = pow(ndoth, 4.0);
  spec *= (0.449379 * ndotl * attenuation);
  spec *= extraParam;

  // n of 128
  //float spec = pow(ndoth, 128.0);
  //spec *= (5.334177 * ndotl * attenuation);
  
  //spec *= (0.33 * ndotl * attenuation); // arbitrary scaling.
  
  // apply! factor of 2 to push the light
  vec3 color = ( attenuation * ndotl ) * lightColor;// + spec;//vec3( spec, spec, spec );
  //color *= 2.54;
  
  gl_FragColor = vec4( color, spec );
}
