/*********************************************************************NVMH3****

******************************************************************************/

float4x4 worldViewProj : WorldViewProjection;
float4x4 Proj : Projection;

float3 campos : CAMERAPOS;

float  OverallBlend : OverallBlend;
float  PixelScale : PixelScale;
float  FalloffExponent : FalloffExponent;
float2 BlurCenter : BlurCenter;

//
float3 ColorLight : ColorLight;
float3 ColorDark : ColorDark;
float  Desaturate : Desaturate;
float  ColorMap : ColorMap;
float  ColorBlendAmount : ColorBlendAmount;


texture diffuseTexture : DiffuseTexture;
sampler DiffuseTextureSampler = sampler_state 
{
    texture = <diffuseTexture>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = POINT;
    MINFILTER = POINT;
    MAGFILTER = POINT;
};


texture ReducedTexture : ReducedTexture;
sampler ReducedTextureSampler = sampler_state 
{
    texture = <ReducedTexture>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = POINT;
    MINFILTER = POINT;
    MAGFILTER = POINT;
};





struct vertexInput {
    float4 position				: POSITION;
    float2 texCoordDiffuse		: TEXCOORD0;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
};


vertexOutput VS_Screen(vertexInput IN) 
{
    vertexOutput OUT;
    OUT.hPosition = mul( IN.position, Proj );    
    OUT.texCoordDiffuse = IN.texCoordDiffuse;
    return OUT;
}


float3 DoColorBlend( float3 sampled )
{
  	float3 sceneColor = ColorLight * sampled;
  	
    float3 grayXfer = float3(0.3,0.59,0.11);
    float gray = dot(grayXfer,sceneColor);
    float3 muted = lerp(sceneColor,gray.xxx, Desaturate ); 
        
    float3 blended = lerp(ColorDark,ColorLight,gray);  
    float3 result = lerp(muted, blended, ColorMap); //Toned    

	return result;
}
    


float4 PS_Blur8( vertexOutput IN): COLOR
{	
	static const float NumSamples = 8.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	

#if PerVertexPreference	  // no blur
	return sampled;
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter );
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend);    
#endif
}




float4 PS_Blur12( vertexOutput IN): COLOR
{	
	
	static const float NumSamples = 12.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	
	
#if PerVertexPreference	  // no blur
	return sampled;
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend);    
#endif
}


float4 PS_Blur16( vertexOutput IN): COLOR
{	
	static const float NumSamples = 16.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	

#if PerVertexPreference	  // no blur
	return sampled;
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend); 
#endif   
}





static const float NumSamples24 = 24.0f;

float4 PS_Blur24( vertexOutput IN): COLOR
{	
	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	
	
#if PerVertexPreference	  // no blur
	return sampled;
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	//where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples24; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples24 + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        //Blurred += Current.rgb;
        Blurred += Current.rgb / (NumSamples24 + i*.5f); //the falloff isn't properly normalized
        //Blurred += Current.rgb / (NumSamples24); //i+4);
    }
    
   // return lerp( sampled, float4(Blurred / NumSamples24, 1.0f), OverallBlend);    
    return lerp( sampled, float4(Blurred, 1.0f), OverallBlend);    
#endif
}



float4 PS_Blur8blend( vertexOutput IN): COLOR
{	
	static const float NumSamples = 8.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	
	
#if PerVertexPreference	  // no blur
	float4 outColor = sampled;
	outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount ); 
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
   
    float4 outColor = lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend);        
    outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount );
#endif    
    return outColor;
}




float4 PS_Blur12blend( vertexOutput IN): COLOR
{	
	
	static const float NumSamples = 12.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	
#if PerVertexPreference	  // no blur
	float4 outColor = sampled;
	outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount ); 
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
  
    float4 outColor = lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend);    
    
    outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount );
#endif
    
    return outColor;
    
}


float4 PS_Blur16blend( vertexOutput IN): COLOR
{	
	static const float NumSamples = 16.0f;

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;	
	
#if PerVertexPreference	  // no blur
	float4 outColor = sampled;
	outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount ); 
#else	
    float2 pixelVelocity;    
  
    float where;
	where = length( IN.texCoordDiffuse - BlurCenter);
	where /= length( float2(0.5f, 0.5f) );

	pixelVelocity = BlurCenter - IN.texCoordDiffuse;
	pixelVelocity = normalize( pixelVelocity );
	
	// should be normalized to 1 texel!!!
	pixelVelocity *= 0.1f; 	
	
	where = pow( where, FalloffExponent );
	
    // For each sample, sum up each sample's color in "Blurred" and then divide
    // to average the color after all the samples are added.
    float3 Blurred = 0;    
    for(float i = 0; i < NumSamples; i++)
    {   
        // Sample texture in a new spot based on pixelVelocity vector 
        // and average it with the other samples        
        float2 lookup = pixelVelocity * i * where * PixelScale/ NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(ReducedTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    float4 outColor = lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend);    
    
    outColor.xyz = lerp( outColor.xyz, DoColorBlend( outColor.xyz ), ColorBlendAmount );
#endif
    
    return outColor;
}





//-----------------------------------
technique blur8
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur8();
    }
}


//-----------------------------------
technique blur12
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur12();
    }
}


//-----------------------------------
technique blur16
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur16();
    }
}

//-----------------------------------
technique blur24
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur24();
    }
}


//-----------------------------------
technique blur8blend
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur8blend();
    }
}


//-----------------------------------
technique blur12blend
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur12blend();
    }
}


//-----------------------------------
technique blur16blend
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_Screen();
		PixelShader  = compile ps_2_0 PS_Blur16blend();
    }
}

