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

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

float4x4 worldViewProj : WorldViewProjection;
float4x4 Proj : Projection;

float3 campos : CAMERAPOS;

float  OverallBlend : OverallBlend;
float  PixelScale : PixelScale;

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

texture LastFrameDistanceTexture: LastFrameDistanceTexture;
sampler LastFrameDistanceTextureSampler = sampler_state 
{
    texture = <LastFrameDistanceTexture>;
    MIPFILTER = POINT;
    MINFILTER = POINT;
    MAGFILTER = POINT;
};

texture depthTexture : Custom0;
sampler DepthTextureSampler = sampler_state 
{
    texture = <depthTexture>;
    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;
}



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

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;
	
	float4 lastFrameVelocity = tex2D( LastFrameDistanceTextureSampler, IN.texCoordDiffuse );
	float4 thisVelocity =  tex2D( DepthTextureSampler, IN.texCoordDiffuse );

    float2 pixelVelocity;
    
    // Get this pixel's current velocity and this pixel's last frame velocity
    // The velocity is stored in .r & .g channels
    float4 curFramePixelVelocity = tex2D(DepthTextureSampler, IN.texCoordDiffuse);
    float4 lastFramePixelVelocity = tex2D(LastFrameDistanceTextureSampler, IN.texCoordDiffuse);

	// we subtract 1 because we moved the range from [-1,+1] to [0,2] to 
	//   support the 360's 32bit fp surface. then negate.
	curFramePixelVelocity -= 1; 
	lastFramePixelVelocity -= 1;
	
	curFramePixelVelocity *= -1; 
	lastFramePixelVelocity *= -1;
	
    // If this pixel's current velocity is zero, then use its last frame velocity
    // otherwise use its current velocity.  We don't want to add them because then 
    // you would get double the current velocity in the center.  
    // If you just use the current velocity, then it won't blur where the object 
    // was last frame because the current velocity at that point would be 0.  Instead 
    // you could do a filter to find if any neighbors are non-zero, but that requires a lot 
    // of texture lookups which are limited and also may not work if the object moved too 
    // far, but could be done multi-pass.
    float curVelocitySqMag = curFramePixelVelocity.r * curFramePixelVelocity.r +
                             curFramePixelVelocity.g * curFramePixelVelocity.g;
    float lastVelocitySqMag = lastFramePixelVelocity.r * lastFramePixelVelocity.r +
                              lastFramePixelVelocity.g * lastFramePixelVelocity.g;
                                   
    if( lastVelocitySqMag > curVelocitySqMag )
    {
        pixelVelocity.x =  lastFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -lastFramePixelVelocity.g * PixelScale;
    }
    else
    {
        pixelVelocity.x =  curFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -curFramePixelVelocity.g * PixelScale;    
    }
    
    // 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 / NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(DiffuseTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    // Return the average color of all the samples, blended with the scene
    //    sampling
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend); 
}




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

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;
	
	float4 lastFrameVelocity = tex2D( LastFrameDistanceTextureSampler, IN.texCoordDiffuse );
	float4 thisVelocity =  tex2D( DepthTextureSampler, IN.texCoordDiffuse );

    float2 pixelVelocity;
    
    // Get this pixel's current velocity and this pixel's last frame velocity
    // The velocity is stored in .r & .g channels
    float4 curFramePixelVelocity = tex2D(DepthTextureSampler, IN.texCoordDiffuse);
    float4 lastFramePixelVelocity = tex2D(LastFrameDistanceTextureSampler, IN.texCoordDiffuse);

	// we subtract 1 because we moved the range from [-1,+1] to [0,2] to 
	//   support the 360's 32bit fp surface. then negate.
	curFramePixelVelocity -= 1; 
	lastFramePixelVelocity -= 1;
	 
	//if( abs( curFramePixelVelocity.x ) > 0.05f )
	// return float4( sampled.xy, 1, 1 );
	// 	else
	// return float4( 1, sampled.yz, 1 );
  
	curFramePixelVelocity *= -1;
	lastFramePixelVelocity *= -1;
	
    // If this pixel's current velocity is zero, then use its last frame velocity
    // otherwise use its current velocity.  We don't want to add them because then 
    // you would get double the current velocity in the center.  
    // If you just use the current velocity, then it won't blur where the object 
    // was last frame because the current velocity at that point would be 0.  Instead 
    // you could do a filter to find if any neighbors are non-zero, but that requires a lot 
    // of texture lookups which are limited and also may not work if the object moved too 
    // far, but could be done multi-pass.
    float curVelocitySqMag = curFramePixelVelocity.r * curFramePixelVelocity.r +
                             curFramePixelVelocity.g * curFramePixelVelocity.g;
    float lastVelocitySqMag = lastFramePixelVelocity.r * lastFramePixelVelocity.r +
                              lastFramePixelVelocity.g * lastFramePixelVelocity.g;
                                   
    if( lastVelocitySqMag > curVelocitySqMag )
    {
        pixelVelocity.x =  lastFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -lastFramePixelVelocity.g * PixelScale;
    }
    else
    {
        pixelVelocity.x =  curFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -curFramePixelVelocity.g * PixelScale;    
    }
    
    // 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 / NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(DiffuseTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    // Return the average color of all the samples, blended with the scene
    //    sampling
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend); 
  
    //return float4( -curFramePixelVelocity.xy, -lastFramePixelVelocity.x,  1);
  
  	//curFramePixelVelocity -= 1; 
	//lastFramePixelVelocity -= 1;
}


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

	float4 sampled = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
	sampled.a = 1.0f;
	
	float4 lastFrameVelocity = tex2D( LastFrameDistanceTextureSampler, IN.texCoordDiffuse );
	float4 thisVelocity =  tex2D( DepthTextureSampler, IN.texCoordDiffuse );

    float2 pixelVelocity;
    
    // Get this pixel's current velocity and this pixel's last frame velocity
    // The velocity is stored in .r & .g channels
    float4 curFramePixelVelocity = tex2D(DepthTextureSampler, IN.texCoordDiffuse);
    float4 lastFramePixelVelocity = tex2D(LastFrameDistanceTextureSampler, IN.texCoordDiffuse);

	// we subtract 1 because we moved the range from [-1,+1] to [0,2] to 
	//   support the 360's 32bit fp surface. then negate.
	curFramePixelVelocity -= 1; 
	lastFramePixelVelocity -= 1;
	
	curFramePixelVelocity *= -1;
	lastFramePixelVelocity *= -1;
	
    // If this pixel's current velocity is zero, then use its last frame velocity
    // otherwise use its current velocity.  We don't want to add them because then 
    // you would get double the current velocity in the center.  
    // If you just use the current velocity, then it won't blur where the object 
    // was last frame because the current velocity at that point would be 0.  Instead 
    // you could do a filter to find if any neighbors are non-zero, but that requires a lot 
    // of texture lookups which are limited and also may not work if the object moved too 
    // far, but could be done multi-pass.
    float curVelocitySqMag = curFramePixelVelocity.r * curFramePixelVelocity.r +
                             curFramePixelVelocity.g * curFramePixelVelocity.g;
    float lastVelocitySqMag = lastFramePixelVelocity.r * lastFramePixelVelocity.r +
                              lastFramePixelVelocity.g * lastFramePixelVelocity.g;
                                   
    if( lastVelocitySqMag > curVelocitySqMag )
    {
        pixelVelocity.x =  lastFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -lastFramePixelVelocity.g * PixelScale;
    }
    else
    {
        pixelVelocity.x =  curFramePixelVelocity.r * PixelScale;   
        pixelVelocity.y = -curFramePixelVelocity.g * PixelScale;    
    }
    
    // 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 / NumSamples + IN.texCoordDiffuse;
        
        // Lookup the color at this new spot
        float4 Current = tex2D(DiffuseTextureSampler, lookup);
        
        // Add it with the other samples
        Blurred += Current.rgb;
    }
    
    // Return the average color of all the samples, blended with the scene
    //    sampling
    return lerp( sampled, float4(Blurred / NumSamples, 1.0f), OverallBlend); 
}

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

