//Particle shader

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

#define SOFT_PARTICLES
//#define PARTICLE_CSM

// Vertex to pixel shader structure
struct v2p
{
  //float4 position       : POSITION;
  float3 position       : TEXCOORD4;
  float2 uv				: TEXCOORD0;
  float4 color			: COLOR;
 
  float3 Direction		: TEXCOORD1;
  float4 RayleighColor	: TEXCOORD2;
  float4 MieColor     	: TEXCOORD3;
  
  float  extinction     : TEXCOORD6;
  //float3 wpos           : WPOS;
#ifdef SOFT_PARTICLES
  // Test Z
  float4 wpos           : WPOS;
#endif
};

float LinearizeDepth(float depth, float near, float far)
{
  return (2 * near) / (far + near - depth * (far - near));
}

void main
(
  in v2p IN,

  out float4 outColor : COLOR0,
#ifdef CSM_MRT
  out float4 outShadow : COLOR1,
#endif

  // Constants
  uniform sampler2D baseMap 	: TEXUNIT0,
  //uniform sampler2D normalMap 	: TEXUNIT1,
#ifdef SOFT_PARTICLES
  uniform sampler2D curDepthTex	: TEXUNIT6,
  uniform float     frustumNear,
  uniform float     frustumFar,
  uniform float2    resolution,
#endif
  
   
  uniform float3    lightDirection,
  uniform float3    lightColor,
  uniform float3    lightAmbient,
  uniform float     atmosRayleigh,
  uniform float     atmosMie,
  
#ifdef CSM
#ifdef PARTICLE_CSM
	uniform sampler2D    shadowArray  : TEXUNIT7,
  uniform float4x4     smTexMatArray[SM_MAX_SPLITS],  
  uniform float smSplits, 
#endif
#endif
  
  // uniform float3    eyePosW,
  uniform float3    Ke,
  uniform float3    Ka,
  uniform float3    Kd,
  uniform float3    Ks,
  uniform float     shininess,
  uniform float     sunny
  // uniform float     exposure
)
{ 
  float shadow=sunny;
#ifdef CSM
#ifdef PARTICLE_CSM
  float shadow;
  //float3 pos=IN.position;
  // Output shadowing and normals
  shadow=GetShadowFactor(IN.position, float3(0,1,0),shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;
  //outShadow.rgb = IN.normal;
#endif
#endif

//shadow+=0.1f;
//shadow=saturate(shadow);

//shadow=0.1f;

  float3 skyColor=GetSkyColor(lightDirection,IN.Direction,IN.RayleighColor,IN.MieColor,atmosRayleigh,atmosMie,lightColor,lightAmbient);

  // Fast when close up
  if(IN.color.a<0.01)discard;
  
  //Lighting is not used -> heavy + particles are flat anyway
  //float3 normal = tex2D(normalMap, IN.uv);
  //LightingSun(Ke,Ka,Kd,Ks,shininess,lightDirection,lightColor,lightAmbient,IN.Position,N,IN.eyePosTS,
    //ambient,diffuse,specular);
  
    // Get base texture color
  float4 baseCol=tex2D(baseMap,IN.uv);
  float3 lighting = (lightColor*shadow)+lightAmbient;  //*0.5f + float3(1,1,1)*0.5f;
  float3 coloring = IN.color; //*0.5f + float3(1,1,1)*0.5f;
  
  float3 tempColor = baseCol * coloring * lighting; // + lightAmbient*0.25f;
  
//tempColor=baseCol;
  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor, tempColor,IN.extinction);
//outColor.rgb=IN.wpos.z;
  //outColor.rgb=tempColor.rgb;
  //outColor.rgb=baseCol.rgb;

  //pixelPos.z=IN.wpos.w;
  
  outColor.a = baseCol.a * IN.color.a;
  //outColor.rgb=(1.0-tex2D(curDepthTex,pixelPos.xy).x)*50.0f;
  //outColor.rgb=;
  //outColor.rgb=(1.0f-pixelPos.z)*50.0f;
  //outColor.b=0.0f;
#ifdef SOFT_PARTICLES
  float3 pixelPos=IN.wpos.xyz;
  pixelPos.xy/=resolution;
  pixelPos.z=LinearizeDepth(pixelPos.z,frustumNear,frustumFar);
  pixelPos.z=LinearizeDepth(tex2D(curDepthTex,pixelPos.xy).x,frustumNear,frustumFar)-pixelPos.z;
  // depth should be made linear
  outColor.a*=pow(saturate(pixelPos.z*1.0*(frustumFar-frustumNear)),2);
  //outColor.a*=shadow;
#endif

#ifdef CSM_MRT
  //outShadow.a=shadow;
  outShadow.rgba=0;
  //outShadow.rgba=float4(0,0,0,0);
#endif
}
