float2 screenSize : Screen;
float texel = 	0.5f;

const float gaussianCoefs[7] = { 
0.036634443338442654485719345599775f,
0.11128549298842362175553017858187f,
0.21675429864898149448661500349083f,
0.27069427735675071601741647481243f,
0.21675429864898149448661500349083f,
0.11128549298842362175553017858187f,
0.036634443338442654485719345599775f
};

texture renderTexture;
texture texture_0;
texture texture_1;
texture texture_2;

sampler textureSampler = sampler_state 
{
    texture = <renderTexture>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = NONE;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

sampler texture_0Sampler = sampler_state 
{
    texture = <texture_0>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = NONE;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};
sampler texture_1Sampler = sampler_state 
{
    texture = <texture_1>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = NONE;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};
sampler texture_2Sampler = sampler_state 
{
    texture = <texture_2>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = NONE;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

struct VertexInput {
    float3 Position	: POSITION;
    float2 uvCoord	: TEXCOORD0;
};

struct VertexOutput {
    float4 Position	: POSITION;
    float2 uvCoord	: TEXCOORD0;
};

struct VertexOutput_final {
    float4 Position	: POSITION;
    float2 uvCoord1	: TEXCOORD0;
    float2 uvCoord2	: TEXCOORD1;
    float2 uvCoord3	: TEXCOORD2;
};

struct GlowVertexOutput {
    float4 Position	: POSITION;
    half2 uvCoord0	: TEXCOORD0;
    half2 uvCoord1	: TEXCOORD1;
    half2 uvCoord2	: TEXCOORD2;
    half2 uvCoord3	: TEXCOORD3;
    half2 uvCoord4	: TEXCOORD4;
    half2 uvCoord5	: TEXCOORD5;
    half2 uvCoord6	: TEXCOORD6;
};



VertexOutput QuadProjection(VertexInput IN) {
    VertexOutput OUT;
    
    OUT.Position = float4( IN.Position - float3( (0.5f/screenSize.x), (0.5f/screenSize.y), 0.0f ) , 1.0f );
    OUT.uvCoord = IN.uvCoord;
    
    return OUT;
}

VertexOutput_final QuadProjection_final(VertexInput IN) {
    VertexOutput_final OUT;
    
    OUT.Position = float4( IN.Position  , 1.0f );
    OUT.uvCoord1 = IN.uvCoord + float2( 2.0/screenSize.x, 2.0/screenSize.y );
    OUT.uvCoord2 = IN.uvCoord + float2( 4.0/screenSize.x, 4.0/screenSize.y );
    OUT.uvCoord3 = IN.uvCoord + float2( 8.0/screenSize.x, 8.0/screenSize.y );
    
    return OUT;
}

float4 Combination( VertexOutput IN ) : COLOR
{
	return 	(tex2D( texture_0Sampler, IN.uvCoord ) +
			tex2D( texture_1Sampler, IN.uvCoord ) +
			tex2D( texture_2Sampler, IN.uvCoord ));
}

float4 Combination_final( VertexOutput_final IN ) : COLOR
{
	return 	(tex2D( texture_0Sampler, IN.uvCoord1 ) +
			tex2D( texture_1Sampler, IN.uvCoord2 ) +
			tex2D( texture_2Sampler, IN.uvCoord3 ));
}

GlowVertexOutput VS_QuadHorizontal(VertexInput IN) {
    GlowVertexOutput OUT;
    
    OUT.Position = float4( IN.Position , 1.0f );
    
    float2 coords = IN.uvCoord;
    float2 addCoords = float2( 1.0f/(screenSize.x*texel), 0.0f );
    
    OUT.uvCoord0 = coords - addCoords*3;
    OUT.uvCoord1 = coords - addCoords*2;
    OUT.uvCoord2 = coords - addCoords;
    OUT.uvCoord3 = coords;
    OUT.uvCoord4 = coords + addCoords;
    OUT.uvCoord5 = coords + addCoords*2;
    OUT.uvCoord6 = coords + addCoords*3;
    
    return OUT;
}

GlowVertexOutput VS_QuadVertical(VertexInput IN) {
    GlowVertexOutput OUT;
    
    OUT.Position = float4( IN.Position , 1.0f );
    
    float2 coords = IN.uvCoord;
    float2 addCoords = float2( 0.0f, 1.0f/(screenSize.y*texel) );
    
    OUT.uvCoord0 = coords - addCoords*3;
    OUT.uvCoord1 = coords - addCoords*2;
    OUT.uvCoord2 = coords - addCoords;
    OUT.uvCoord3 = coords;
    OUT.uvCoord4 = coords + addCoords;
    OUT.uvCoord5 = coords + addCoords*2;
    OUT.uvCoord6 = coords + addCoords*3;
    
    return OUT;
}

half4 GaussianBlur( GlowVertexOutput IN ) : COLOR
{
	float3 color = tex2D( textureSampler, IN.uvCoord0 ) * gaussianCoefs[0];
	color += tex2D( textureSampler, IN.uvCoord1 ) * gaussianCoefs[1];
	color += tex2D( textureSampler, IN.uvCoord2 ) * gaussianCoefs[2];
	color += tex2D( textureSampler, IN.uvCoord3 ) * gaussianCoefs[3];
	color += tex2D( textureSampler, IN.uvCoord4 ) * gaussianCoefs[4];
	color += tex2D( textureSampler, IN.uvCoord5 ) * gaussianCoefs[5];
	color += tex2D( textureSampler, IN.uvCoord6 ) * gaussianCoefs[6];
	
	return float4(color,0.0f);
}

float4 PS_CopyTexture( VertexOutput IN ) : COLOR
{
	return tex2D( textureSampler, IN.uvCoord );
}


technique BlurX
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_QuadHorizontal();
		PixelShader = compile ps_2_0 GaussianBlur();
		
		ZWriteEnable = false;
		
		AlphaBlendEnable = true;
		srcBlend = one;
		destBlend =zero;
    }
}

technique BlurY
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_QuadVertical();
		PixelShader = compile ps_2_0 GaussianBlur();
		
		ZWriteEnable = false;
		
		AlphaBlendEnable = true;
		srcBlend = one;
		destBlend =invsrcColor;
    }
}

technique Combine
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 QuadProjection_final();
		PixelShader = compile ps_2_0 Combination_final();
		
		ZWriteEnable = false;
		
		AlphaBlendEnable = true;
		srcBlend = one;
		destBlend =invsrcColor;
    }
}

technique CopyTexture
{
	pass p0
	{
		VertexShader = compile vs_2_0 QuadProjection();
		PixelShader = compile ps_2_0 PS_CopyTexture();
		
		ZWriteEnable = false;
	}
}