//
// Common lighting functions
// Blinn-Phong specular shading
//

// Energy conserving diffuse/specular?
//#define ENERGY_CONSERVE

void LightingSun
(
  // Inputs
  float3 Ke,
  float3 Ka,
  float3 Kd,
  float3 Ks,
  float  shininess,
  float3 lightDirection,
  float3 lightColor,
  float3 lightAmbient,
  float3 P,               // Position (world)
  float3 N,               // Normal
  float3 eyePosW,
  
  // Outputs
  out float3 ambient,
  out float3 diffuse,
  out float3 specular
)
// Calculate mostly standard OpenGL lighting
// Use the results to modify your base texture color:
// outColor=textureCol*diffuse+ambient+emissive+specular
// The light is assumed a sun; all rays are parallel.
{
  // Ambient
  // Add a bit of sky influence, assuming down=dark and up=light
  float normalInfluence;
  //normalInfluence=(N.y+1.0)*0.5;
  normalInfluence=(N.y+4.0)*0.2;
  ambient=Ka*lightAmbient*normalInfluence;

  // Note that 'normal' is interpolated across the triangle, so it may not be normalized
  N=normalize(N);
  
  // Diffuse
  float3 L=lightDirection; //normalize(lightPosition)
  //float  diffuseLight=max(dot(N,L),0);
  float  diffuseLight=saturate(dot(N,L));
  
  // Wrapped diffuse
  //const float wrap=0.5;
  //diffuseLight=max(dot(N,L)+wrap,0)/(1.0+wrap);

  // Energy conserving requires dividing by PI
  // See also http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
  //diffuse=Kd*lightColor*diffuseLight; // /3.14159265;
#ifdef ENERGY_CONSERVE
  diffuse=Kd*lightColor*diffuseLight/3.14159265;
#else
  diffuse=Kd*lightColor*diffuseLight;
#endif

  // Specular
  float3 V=normalize(eyePosW-P);
  float3 H=normalize(L+V);          // Half vector
#ifdef ENERGY_CONSERVE
  // See also http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
  // - Original
  //float  specularLight=pow(max(dot(N,H),0),shininess);
  // - Energy conserving
  //float  specFactor=(shininess+6.0)/(8.0*3.14159265);
  // Approx of (n+8)/(8*PI) = 0.0397436*n+0.3183
  // See also http://www.wolframalpha.com/input/?i=%28%28n%2B8%29%2F%288*pi%29%29+vs+%280.0397436+*+n+%2B+0.3183%29+for+n+from+0+to+100  
  // The derivate of (n+8)/(8*PI) is 1/(8*PI), the offset at n=0 is 1/PI.
  float specFactor=0.0397887357729839*shininess+0.3183;
#else
  const float specFactor=1.0;
#endif
  float  specularLight=specFactor*pow(saturate(dot(N,H)),shininess);
  if(diffuseLight<=0)               // Convert 'if' to 'max' to avoid branch?
    specularLight=0;
  specular=Ks*lightColor*specularLight;
  // Clamp specular since Cg output values can not be too large
  //specular=min(specular,100);
//specular=float3(0,1,0);
//specular=lightColor;
}
