// CSM Shadowmapping + Bloom + Colorgrade
// HDR version

#include "../common/constants.cg"
#include "../common/hdr.cg"
#include "../common/utils.cg"
#include "bloom.cg"
#include "common_fs.cg"

// Visually show the bloom maps in the top half of the image?
//#define DEV_SHOW_BLOOM_MAPS

struct VertOut
{
  float4 pos : POSITION;
  float4 col : COLOR0;
  float2 tc0 : TEXCOORD0;
};

struct FragOut
{
  float4 col : COLOR;
};

float BlurTexture(sampler2D tex, float2 vin, float blur, sampler2D depthMap)
// With Z sampling
{
  return tex2D(tex,vin).a;
  
  /*
  float sum=0;
  const float blurT2=2.0*blur;
  const float blurT3=3.0*blur;
  const float blurT4=4.0*blur;

  float pixeldepth = tex2D(depthMap,vin).z;
  float threshold= (1.0f-pixeldepth)*0.2f;

  // add shadowValue
  float shadowValue = tex2D(tex, vin).a;
  
  sum = shadowValue * 2.0f;  // *0.16?
  
  // blur in y (horizontal)
  sum += abs(tex2D(depthMap, float2(vin.x - blurT4, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.05 :
                  tex2D(tex, float2(vin.x - blurT4, vin.y)).a * 0.05;         
  sum += abs(tex2D(depthMap, float2(vin.x - blurT3, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.09 :        
                  tex2D(tex, float2(vin.x - blurT3, vin.y)).a * 0.09;  
  sum += abs(tex2D(depthMap, float2(vin.x - blurT2, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.12 :
                  tex2D(tex, float2(vin.x - blurT2, vin.y)).a * 0.12;
  sum += abs(tex2D(depthMap, float2(vin.x - blur, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.15 :
                  tex2D(tex, float2(vin.x - blur, vin.y)).a * 0.15;
  sum += abs(tex2D(depthMap, float2(vin.x + blurT4, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.15 :
                  tex2D(tex, float2(vin.x + blurT4, vin.y)).a * 0.15;
  sum += abs(tex2D(depthMap, float2(vin.x + blurT3, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.12 :
                  tex2D(tex, float2(vin.x + blurT3, vin.y)).a * 0.12;
  sum += abs(tex2D(depthMap, float2(vin.x + blurT2, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.09 :
                  tex2D(tex, float2(vin.x + blurT2, vin.y)).a * 0.09;
  sum += abs(tex2D(depthMap, float2(vin.x + blur, vin.y)).z - pixeldepth)>threshold? shadowValue * 0.05 :
                  tex2D(tex, float2(vin.x + blur, vin.y)).a * 0.05;
  
  // blur in y (vertical)
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y - blurT4)).z - pixeldepth)>threshold? shadowValue * 0.05 :  
                  tex2D(tex, float2(vin.x, vin.y - blurT4)).a * 0.05;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y - blurT3)).z - pixeldepth)>threshold? shadowValue * 0.09 :  
                  tex2D(tex, float2(vin.x, vin.y - blurT3)).a * 0.09;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y - blurT2)).z - pixeldepth)>threshold? shadowValue * 0.12 :  
                  tex2D(tex, float2(vin.x, vin.y - blurT2)).a * 0.12;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y - blur)).z - pixeldepth)>threshold? shadowValue * 0.15 :  
                  tex2D(tex, float2(vin.x, vin.y - blur)).a * 0.15;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y + blur)).z - pixeldepth)>threshold? shadowValue * 0.15 :  
                  tex2D(tex, float2(vin.x, vin.y + blur)).a * 0.15;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y + blurT2)).z - pixeldepth)>threshold? shadowValue * 0.12 :  
                  tex2D(tex, float2(vin.x, vin.y + blurT2)).a * 0.12;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y + blurT3)).z - pixeldepth)>threshold? shadowValue * 0.09 :  
                  tex2D(tex, float2(vin.x, vin.y + blurT3)).a * 0.09;
  sum += abs(tex2D(depthMap, float2(vin.x, vin.y + blurT4)).z - pixeldepth)>threshold? shadowValue * 0.05 :  
                  tex2D(tex, float2(vin.x, vin.y + blurT4)).a * 0.05;
         
  
  float blurdepth=min((1-pixeldepth)*50,3);
  
  sum += tex2D(tex, float2(vin.x - blurT4*blurdepth, vin.y)).a * 0.05;
  sum += tex2D(tex, float2(vin.x - blurT3*blurdepth, vin.y)).a * 0.09;
  sum += tex2D(tex, float2(vin.x - blurT2*blurdepth, vin.y)).a * 0.12;
  sum += tex2D(tex, float2(vin.x - blur*blurdepth, vin.y)).a * 0.15;
  
  sum += tex2D(tex, float2(vin.x + blur*blurdepth, vin.y)).a * 0.15;
  sum += tex2D(tex, float2(vin.x + blurT2*blurdepth, vin.y)).a * 0.12;
  sum += tex2D(tex, float2(vin.x + blurT3*blurdepth, vin.y)).a * 0.09;
  sum += tex2D(tex, float2(vin.x + blurT4*blurdepth, vin.y)).a * 0.05;
  
  sum += tex2D(tex, float2(vin.x, vin.y - blurT4*blurdepth)).a * 0.05;
  sum += tex2D(tex, float2(vin.x, vin.y - blurT3*blurdepth)).a * 0.09;
  sum += tex2D(tex, float2(vin.x, vin.y - blurT2*blurdepth)).a * 0.12;
  sum += tex2D(tex, float2(vin.x, vin.y - blur*blurdepth)).a * 0.15;
  //sum += tex2D(tex, float2(vin.x, vin.y)).a * 0.16;
  sum += tex2D(tex, float2(vin.x, vin.y + blur*blurdepth)).a * 0.15;
  sum += tex2D(tex, float2(vin.x, vin.y + blurT2*blurdepth)).a * 0.12;
  sum += tex2D(tex, float2(vin.x, vin.y + blurT3*blurdepth)).a * 0.09;
  sum += tex2D(tex, float2(vin.x, vin.y + blurT4*blurdepth)).a * 0.05;
  

  return sum*0.5f;
  */
}

FragOut main(
  VertOut vin,
  uniform sampler2D sceneMap    : TEXUNIT0,
  //uniform sampler2D velocityMap : TEXUNIT1,
  /// Z in TEXUNIT5
  uniform sampler2D bloomMap1   : TEXUNIT2,
  uniform sampler2D bloomMap2   : TEXUNIT3,
  uniform sampler2D bloomMap3   : TEXUNIT4,
#ifdef CSM_MRT
  uniform sampler2D depthMap    : TEXUNIT5,
  uniform sampler2D shadowMap   : TEXUNIT6,
  uniform sampler3D gradeMap    : TEXUNIT7,
#else
  uniform sampler3D gradeMap    : TEXUNIT5,   // 3D texture for color grading
#endif
  uniform float alpha,              // Amount of blur
  uniform float exposure
)
{
  FragOut fout;

  float4 ambientColor,
         sdColor;                 // Specular+diffuse
  float4 color;

  // Single render-target (RT)
  color=tex2D(sceneMap,vin.tc0);
  
  float4 bloomColor=BloomCombineMaps3(bloomMap1,bloomMap2,bloomMap3,vin.tc0);
  bloomColor=bloomColor/(exposure*5.0);
  bloomColor=pow(bloomColor,1.1);

  //bloomColor=0;
  color=BloomMix(color,bloomColor);

#ifdef DEV_SHOW_BLOOM_MAPS
// Show the 3 bloom stages and the end-result in 1 view
  if(vin.tc0.y>0.5)
{
 if(vin.tc0.x>0.666)color=tex2D(bloomMap3,vin.tc0);
 else if(vin.tc0.x>0.333)color=tex2D(bloomMap2,vin.tc0);
 else color=tex2D(bloomMap1,vin.tc0);
  } else
#endif
  {
  // HDR -> LDR tonemap
  color.rgb=ToneMapHDR(color,exposure);
  }

  // Color grading
  color.rgb=ColorGrade(color.rgb,gradeMap);

//color.rgb=float3(0,1,0);
  fout.col.rgb=color;
  // Motion blur blend
  fout.col.a=alpha;

  return fout;
} 
