//
// Standard with bumpmap (2 textures); HDR
// 16-03-09, RvG
//

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

// Vertex to pixel shader structure
struct v2p
{
	float2 tc0            : TEXCOORD0;
	float3 Direction      : TEXCOORD1;
	float3 RayleighColor  : TEXCOORD2;
	float3 MieColor			  : TEXCOORD3;
  float4 Position		    : TEXCOORD4;
  float4 posWC_extinction: TEXCOORD6;   // xyz=positionWC, w=extinction
  float3 lightDirTS     : TEXCOORD7;    // Light direction in texture space
  //float3 eyeDirTS       : TEXCOORD8;    // Eye direction in texture space
  float3 eyePosTS       : TEXCOORD5;    // Eye position in texture space
	float3 normalWC       : COLOR;        // Clamped to 0..1
  //float3 positionWC     : ATTR9;
};

void main(
  // In
  in v2p IN,

  // Out
  out float4 outColor : COLOR0,
#ifdef CSM_MRT
  out float4 outShadow : COLOR1,
#endif
  
  // Constants
  uniform sampler2D baseMap   : TEXUNIT0,
  uniform sampler2D normalMap : TEXUNIT1,
  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
  // shadow mapping
	uniform sampler2D    shadowArray  : TEXUNIT7,
  uniform float4x4     smTexMatArray[SM_MAX_SPLITS],  
  uniform float smSplits, 
#endif
  uniform float     sunny,
  uniform float     scale,
  uniform float     exposure
)
{
  float3 skyColor;
  
#ifdef CSM
  float  shadow;  
#else
  const float shadow=1;
#endif

  // Retrieve normal - scale normal back from 0..1 -> -1..1
  float3 normalWC=(IN.normalWC*2.0)-1.0;

  // 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);

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

  float  reflectiveNess=bumpColor.a;

#ifdef CSM
  // Output shadowing and normals (should be IN.PositionWC! now buggy)
  // Retrieve world position
  float3 posW;
  posW.xyz=IN.posWC_extinction.xyz;
  shadow=GetShadowFactor(posW,normalWC,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;
//shadow=1;
  //outShadow.rgb = IN.normal;
#endif

  // 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*shadow*reflectiveNess;
  float3 ambientColor=baseCol*(ambient+Ke);

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

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