//////////////////////////////////////////////
//				 CASTER PASS				//
//				    HEAT					//
//////////////////////////////////////////////

// vs_1_1
void HeatCaster_vp(
              // in
              float4 vPos: POSITION,
              float4 vNormal: NORMAL,
              
              // out
              out float4 oPos: POSITION,
              out float2 oNDotV: TEXCOORD0,
              
              // parameters
              uniform float4x4 worldViewProj,
              uniform float3 eyePosition        // object space
            )
{
   float4 eyeDir = float4(eyePosition - vPos.xyz, 0);
   eyeDir = normalize(eyeDir);
   oPos   = mul( worldViewProj, vPos );
   oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
}

// ps_2_0
float4 HeatCaster_fp(
                        // input from vp
                        float2 iNDotV: TEXCOORD0
                     ) : COLOR0
{
   return iNDotV.x;
}


//////////////////////////////////////////////
//				 CASTER PASS				//
//				    COLD					//
//////////////////////////////////////////////

// vs_1_1
void ColdCaster_vp(
              // in
              float4 vPos: POSITION,
              float4 vNormal: NORMAL,
              
              // out
              out float4 oPos: POSITION,
              out float2 oNDotV: TEXCOORD0,
              
              // parameters
              uniform float4x4 worldViewProj,
              uniform float3 eyePosition        // object space
            )
{
   float4 eyeDir = float4(eyePosition - vPos.xyz, 0);
   eyeDir = normalize(eyeDir);
   oPos   = mul( worldViewProj, vPos );
   oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
}

// ps_2_0
float4 ColdCaster_fp(
                        // input from vp
                        float2 iNDotV: TEXCOORD0
                     ) : COLOR0
{
   return iNDotV.x / 2;
}


//////////////////////////////////////////////
//	   PASS 1 - Light to heat conversion	//
//////////////////////////////////////////////

// vs_1_1
void LightToHeat_vp(
                    // in
                    float4 inPos: POSITION,
                    
                    uniform float flipping,

                    // out
                    out float4 Pos: POSITION,
                    out float2 uv0: TEXCOORD0
                   )
{
    Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);
    inPos.xy = sign(inPos.xy);
    uv0  = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
}


// ps_2_0
void LightToHeat_fp(
                        // input from vp
                        float4 inDiffuse: COLOR0,
                        float2 inUV0: TEXCOORD0,
                        
                        // out
                        out float4 outColor: COLOR0,
                        
                        // params
                        uniform float4 random_fractions,
                        uniform float4 heatBiasScale,
                        uniform float4 depth_modulator,

                        uniform sampler2D Input,         // output of HeatVisionCaster_fp (NdotV)
                        uniform sampler2D NoiseMap,
                        uniform sampler2D HeatLookup
                     )
{
   float  depth, heat, interference;

   //  Output constant color:
   depth = tex2D( Input, inUV0 );
   depth *= (depth * depth_modulator);

   heat  = (depth * heatBiasScale.y);

//   if (depth > 0)
   {
		interference = -0.5 + tex2D( NoiseMap, inUV0 + float2( random_fractions.x, random_fractions.y ) );
		interference *= interference;
		interference *= 1 - heat;
		heat += interference;//+ heatBiasScale.x;
   }

/*
	heatBias isn't used for now
   if (heat > 0)
       heat += heatBiasScale.x;
*/

   // Clamp UVs
   heat  = max( 0.005, min( 0.995, heat ) );
   outColor = tex2D( HeatLookup, float2( heat, 0.f ) );
}


//////////////////////////////////////////////
// PASS 2 - add simple blur (final pass)	//
//////////////////////////////////////////////

// vs_1_1
void Blur_vp(
                    // in
                    float4 inPos: POSITION,
                    
                    uniform float flipping,

                    // out
                    out float4 Pos: POSITION,
                    out float2 uv0: TEXCOORD0
                   )
{
    Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);
    inPos.xy = sign(inPos.xy);
    uv0  = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
}

// ps_2_0
void Blur_fp(
                    // input from vp
                    float4 inDiffuse: COLOR0,
                    float2 inUV0: TEXCOORD0,
                    
                    // out
                    out float4 outColor: COLOR0,
                    
                    // parameters
                    uniform sampler2D Input,             // output of HeatVision_fp1 (HeatRenderTexture)
                    uniform float4 blurAmount
                    )
{
   int i;
   float4 tmpOutColor;
   float  diffuseGlowFactor;
   const float2 offsets[4] = 
   {
/*
		// hazy blur
		-1.8, -1.8,
		-1.8, 1.8,
		1.8, -1.8,
		1.8, 1.8
*/
/*
		// less-hazy blur
	  -1.0,  2.0,
	  -1.0, -1.0,
	   1.0, -1.0,
	   1.0,  1.0
*/
/*
      -0.326212, -0.405805,
      -0.840144, -0.073580,
      -0.695914,  0.457137,
      -0.203345,  0.620716
*/

	  -0.3,  0.4,
	  -0.3, -0.4,
	   0.3, -0.4,
	   0.3,  0.4

   };

   tmpOutColor = tex2D( Input, inUV0 );	// UV coords are in image space

   // calculate glow amount
   diffuseGlowFactor = 0.0113f * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));

   // basic blur filter
   for (i = 0; i < 4; i++) {
      tmpOutColor += tex2D( Input, inUV0 + blurAmount.x * diffuseGlowFactor * offsets[i] );
   }

   tmpOutColor *= 0.25;

   // TIPS (old-skool strikes again!)
   // Pay attention here! If you use the "out float4 outColor" directly
   // in your steps while creating the output color (like you remove
   // the "tmpOutColor" var and just use the "outColor" directly)
   // your pixel-color output IS CHANGING EACH TIME YOU DO AN ASSIGNMENT TOO!
   // A temporary variable, instead, acts like a per-pixel double buffer, and
   // best of all, lead to better performance.
   outColor = tmpOutColor;
}