#include "atmosphere.cg"
#include "lighting.cg"
#include "shadowmapping.cg"

// Vertex to pixel shader structure
struct v2p
{
  float4 Position       : TEXCOORD4; //POSITION;
  float3 normal         : TEXCOORD5;
  float3 RayleighColor	: TEXCOORD2;
  float3 MieColor       : TEXCOORD3;
  float3 tc0            : TEXCOORD0;
  float3 Direction      : TEXCOORD1;
  float  extinction     : TEXCOORD6;
  //float2 vpos           : VPOS;
};

void main(

  // In
  in v2p IN,

  // Out
  out float4 outColor   : COLOR0,
#ifdef CSM_MRT
  out float4 outShadow  : COLOR1,
#endif
	  
  // Constants
  uniform sampler2D texMap1     : TEXUNIT0,
  uniform sampler2D texMap2     : TEXUNIT1,
  uniform sampler2D controlMap  : 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,
  uniform float     exposure,  
#ifdef CSM
  // shadow mapping
	uniform sampler2D    shadowArray  : TEXUNIT7,
  uniform float4x4     smTexMatArray[SM_MAX_SPLITS],  
  uniform float smSplits, 
#endif
  uniform float     sunny,
  uniform float     scale            // Texcoord scaling
)
{  
  float3 skyColor;
  
#ifdef CSM
  // Output shadowing and normals
  float shadow=GetShadowFactor(IN.Position, IN.normal,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;
  //outShadow.rgb = IN.normal;
#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 colors
  float4 ctrl=tex2D(controlMap,IN.tc0);
  // Use world planar mapping for both textures
  float2 tc=float2(IN.Position.x,IN.Position.z)*scale;
  float4 tex1=tex2D(texMap1,tc);
  float4 tex2=tex2D(texMap2,tc);

  float4 baseCol;
  
  // Mix
  baseCol=ctrl.a*tex1+(1-ctrl.a)*tex2;
  // Darken & lighten - 50% gray is neutral
  baseCol.rgb*=ctrl.rgb*2.0;
  
  // Lighting
  float3 ambient,diffuse,specular;
  LightingSun(Ke,Ka,Kd,Ks,shininess,lightDirection,lightColor,lightAmbient,IN.Position.xyz,IN.normal,eyePosW,
    ambient,diffuse,specular);

  // Store shadowed color in COLOR0, lit color additions (spec+diff) in COLOR1
  float3 sdColor=baseCol*diffuse+specular;
  float3 ambientColor=baseCol*(ambient+Ke);

  // HDR toning of sky (for LDR shaders)
  //skyColor.rgb=1.0-exp(-exposure*skyColor.rgb);
 
#ifdef CSM_MRT
  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor,ambientColor,IN.extinction);
  //outShadow.rgb=lerp(skyColor*(IN.extinction),sdColor,IN.extinction);
  outShadow.rgb=sdColor*IN.extinction;
  outShadow.a=shadow;
  
//outColor.rgb=float3(1,1,0);
//outShadow.rgb=float3(0,0,0);

  // Blending
  outColor.a=1; //baseCol.a;
  //outShadow.a=1; //baseCol.a;
#else
  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor,ambientColor+sdColor*shadow,IN.extinction);
  // Blending - leave some alpha
  outColor.a=tex2; //baseCol.a;
#endif
}
