//
// Standard with bumpmap (2 textures); HDR
// 16-03-09, RvG
//
// UNTESTED (RvG 25-5-10): may require additional code to handle CSM correctly!!!!!!!!!!!!!!!!
//
//

#include "atmosphere.cg"
#include "lighting.cg"
#include "shadowmapping.cg"
#include "../common/utils.cg"

// Vertex to pixel shader structure
struct v2p
{
	float3 tc0            : TEXCOORD0;
	float3 Direction      : TEXCOORD1;
	float3 RayleighColor  : TEXCOORD2;
	float3 MieColor			  : TEXCOORD3;
  float3 Position		    : TEXCOORD4;
	//float3 normal         : TEXCOORD5;
	float4 normalExtinction : TEXCOORD6;
  float3 lightDirTS     : TEXCOORD7;    // Light direction in texture space
  //float3 eyeDirTS       : TEXCOORD8;    // Eye direction in texture space
  float3 eyePosTS       : TEXCOORD5;    // Eye position in texture space
};

void main(
  // In
  in v2p IN,

  // Out
#ifdef CSM_MRT
  out float4 outShadow : COLOR1,
#endif
  out float4 outColor : COLOR0,
  
  // Constants
  uniform sampler2D baseMap   : TEXUNIT0,
  uniform sampler2D normalMap : TEXUNIT1,
  uniform sampler2D detailMap : TEXUNIT2,
  uniform float3    lightDirection,
  uniform float3    lightColor,
  uniform float3    lightAmbient,
  uniform float3    eyePosW,
  uniform float     atmosRayleigh,
  uniform float     atmosMie,
  uniform float3    Ke,
  uniform float3    Ka,
  uniform float3    Kd,
  uniform float3    Ks,
  uniform float     shininess,
#ifdef CSM
	uniform sampler2D    shadowArray  : TEXUNIT7,
  uniform float4x4     smTexMatArray[SM_MAX_SPLITS],
  uniform float smSplits,
#endif
  uniform float     sunny,
  uniform float     exposure
)
{
  float3 skyColor;

  // Extract variables from vertex shader
  float extinction=IN.normalExtinction.a;
  float3 orgNormal=IN.normalExtinction.xyz;
  
#ifdef CSM
  // Output shadowing and normals
  float shadow=GetShadowFactor(IN.Position, orgNormal,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;
#else
  const float shadow=1;
#endif
  
  // Get sky gradient color
  skyColor.rgb=GetSkyColor(lightDirection,IN.Direction,IN.RayleighColor,IN.MieColor,atmosRayleigh,atmosMie,lightColor,lightAmbient);

  // Get base texture color
  float4 baseCol=tex2D(baseMap,IN.tc0);

  // Detail map
  //baseCol+=tex2D(detailMap,IN.tc0*8);
  baseCol+=0.8*(tex2D(detailMap,IN.tc0*12)-0.5);
  //baseCol=0.8*(tex2D(detailMap,IN.tc0*12)-0.5)+0.3;

  // Bumpmap (delta from original normal)
  // Assume its normalized
  float3 N=UnpackNormal(tex2D(normalMap,IN.tc0).xyz);

  // Compute diffuse term (in tangent space)
  float3 L=IN.lightDirTS;

  // Lighting (in tangent space!)
  float3 ambient,diffuse,specular;
  LightingSun(Ke,Ka,Kd,Ks,shininess,L,lightColor,lightAmbient,IN.Position,N,IN.eyePosTS,
    ambient,diffuse,specular);
  float3 sdColor=baseCol*diffuse+specular;
  float3 ambientColor=baseCol*(ambient+Ke);
  //baseCol.rgb=baseCol*(ambient+Ke)+baseCol*diffuse+specular;

  // Mix sky with texture color based on atmospheric influence
#ifdef CSM_MRT
  outColor.rgb=lerp(skyColor,ambientColor,extinction);
  //outShadow.rgb=lerp(skyColor,sdColor,extinction);
  outShadow.rgb=sdColor*extinction;
  outShadow.a=shadow;

  // Blending
  outColor.a=baseCol.a;
#else
  outColor.rgb=lerp(skyColor,ambientColor+sdColor*shadow,extinction);
  outColor.a=baseCol.a;
#endif
}
