 #define DIFFUSE_LIGHTING_SCALE 2.0

float4 ambientColor  : register (c0);
float4 diffuseColor  : register (c1);
float4 worldLight    : register (c2);
float4 specularColor : register (c3); //power in c3.a
float4 blendPct      : register (c4); //base/cube blend pct in c4.a

struct PS_INPUT
{
   float4 Color  : COLOR0;
   float4 Omni   : COLOR1;
   float  Fog    : FOG;
   float2 Tex    : TEXCOORD0; // base
   float2 Spec   : TEXCOORD1; // spec
   float3 Normal : TEXCOORD2;
   float3 EyeVec : TEXCOORD3;
};

struct PS_OUTPUT
{
   float4 Color : COLOR0;
};

sampler2D sTex0 : register (s0);
sampler2D sSpec : register (s1);
samplerCUBE sCube : register (s2);

PS_OUTPUT ps20_blinnCmapSpecMapAddAlphaReflectFresnelTintedT0 (PS_INPUT Input) 
{
  PS_OUTPUT Out;

  // Sample the textures

  float4 tex = tex2D (sTex0, Input.Tex.xy);
  float4 spec = tex2D (sSpec, Input.Spec);
  float3 normal = normalize (Input.Normal);
  float3 normEyeVec = normalize (Input.EyeVec);

  float3 halfway = normalize (worldLight - normEyeVec); 
  half4 specular;
  specular.rgb = saturate (pow (dot (halfway, normal), specularColor.a)) * specularColor * ( 0.5 * spec  + 2.0 * tex );
  specular.a = 0;

  // Compute diffuse color
  float NdotL = saturate(dot (worldLight, normal));
  half4 diffuse =  (NdotL * diffuseColor * 1.1 + ambientColor * 0.8 + Input.Omni);

  // Compute cube map vector [E - 2(E dot N)N], then sample the cube map
  float4 cube = texCUBE (sCube, reflect (normEyeVec, normal));
  cube.a = 1.0;

  // Calculate fresnel effect for better reflections
  float dotEyeVecNormal = abs(dot(normEyeVec, normal));

  // Use the specular alpha for reflection amount and add fresnel to that
  float fresnel = 1.0 + 2.0 * pow(1 - dotEyeVecNormal, 2.0);
  
  // Calculate final reflection factor
  float reflectionFactor = min(fresnel * tex.a, 1.0);

  // Cube diffusion
  float cubeDiffuse = diffuseColor + (Input.Omni.r * 0.66) + (Input.Omni.g * 0.66) + (Input.Omni.b * 0.66);

  // Final color
  Out.Color = ((tex * diffuse) + specular + (reflectionFactor * cube * cubeDiffuse)) * Input.Color;
  //Out.Color = reflectionFactor;
  return (Out);
}
