float4 ambientColor  : register (c0);
float4 diffuseColor  : register (c1);
float4 worldLight    : register (c2);
float4 specularColor : register (c3); //power in c3.a

struct PS_INPUT
{
   float4 Color  : COLOR0;
#ifdef OMNISCALE
   float4 Omni   : COLOR1;
#endif
   float  Fog    : FOG;

   float2 Tex0    : TEXCOORD0; // base0
   float3 Normal  : TEXCOORD1; // world space vertex normal
   float3 EyeVec  : TEXCOORD2; // world space eye vec

   float3 Basis1 : TEXCOORD4; // tangent space eye vec
   float3 Basis2 : TEXCOORD5; // tangent space eye vec
   float3 Basis3 : TEXCOORD6; // tangent space eye vec
};

struct PS_OUTPUT
{
   float4 Color : COLOR0;
};

sampler2D sTex0: register (s0);
sampler2D sBump: register (s1);

PS_OUTPUT MAINFUNCTION (PS_INPUT Input)
{
  PS_OUTPUT Out;

  float4 tex = tex2D (sTex0, Input.Tex0.xy);        // sample base tex

#ifdef ALPHATEST
  if (tex.a < ALPHATEST)
  {
    discard;
  }
#endif

  float3 bump = (tex2D (sBump, Input.Tex0.xy) - 0.5) * 2.0;  // sample and unbias normal

  // put the normal into eye space using transpose texture basis
  float3 viewBump;
  viewBump.x = dot (Input.Basis1, bump);
  viewBump.y = dot (Input.Basis2, bump);
  viewBump.z = dot (Input.Basis3, bump);

  float3 normal = normalize (viewBump);
  float3 normEyeVec = normalize (Input.EyeVec);

  // compute specular color
  float3 lightVec = normalize(worldLight); 
  float3 reflected = reflect(normEyeVec, normal);

  half4 specular;
  half fspecular = max(dot (lightVec, reflected), 0.0);
  specular.rgb = float3(0.8, 0.8, 0.8);
  specular.rgb -= float3(0.6, 0.5, 0.35) * pow(max(reflected.y, 0.0), 0.5);
  specular.rgb -= float3(1.0, 1.0, 1.0) * pow(max(-reflected.y, 0.0), 0.5);
  specular.rgb = specular.rgb * SKYREFLECTSCALE;
  specular.rgb += float3(1.0, 0.9, 0.75) * pow(fspecular, SPECULARPOWER2) * SPECULARSCALE2;
  specular.rgb += float3(1.0, 0.96, 0.92) * pow(fspecular, SPECULARPOWER1) * SPECULARSCALE1;
  specular.rgb = max(specular.rgb, float3(0.1, 0.1, 0.1));

  specular.a = 0;

  // compute diffuse color
  half4 diffuse = saturate(dot (worldLight, normal)) * diffuseColor * DIFFUSESCALE + ambientColor * AMBIENTSCALE;
#ifdef OMNISCALE
  diffuse = diffuse + Input.Omni * OMNISCALE;
#endif
  diffuse = saturate (diffuse);
  
  float dotEyeVecNormal = abs(dot(normEyeVec, normal));
  float fresnel = min(1.0, FRESNELBASE + FRESNELSCALE * pow(1 - dotEyeVecNormal, FRESNELPOWER));

  //less reflection during night
  float day = (diffuseColor.r + diffuseColor.g + diffuseColor.b) / 3.0;
  fresnel *= day;

  Out.Color = (tex * diffuse + specular * fresnel) * Input.Color;
  Out.Color.a = tex.a + ALPHABIAS;

  return (Out);
}
