float2 ViewSize : ViewSize;

float2 DownFilterSamples[9] =
{
    { -1,  -1 },
    { -1,  0  },
    { -1,  1  },
    { 0,   1  },
    { 1,   1  },
    { 1,   0  },
    { 1,   -1 },
    { 0,   -1 },
    { 0,   0  },
};

static const int FilterSize = 13;
float2 PixelOffsets [ FilterSize ] =
{
    { -6, 0 },
    { -5, 0 },
    { -4, 0 },
    { -3, 0 },
    { -2, 0 },
    { -1, 0 },
    {  0, 0 },
    {  1, 0 },
    {  2, 0 },
    {  3, 0 },
    {  4, 0 },
    {  5, 0 },
    {  6, 0 },
};

static const float BlurWeights [ FilterSize ] = 
{
    0.002216,
    0.008764,
    0.026995,
    0.064759,
    0.120985,
    0.176033,
    0.200496,
    0.176033,
    0.120985,
    0.064759,
    0.026995,
    0.008764,
    0.002216,
};






float ImageBrightness<
	string UIWidget = "slider";
	float UIMax = 1.0;
	float UIMin = -1.0;
	float UIStep = 0.01;
> = 0;

float ImageContrast<
	string UIWidget = "slider";
	float UIMax = 1.0;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = 0;

float ImageOffset<
	string UIWidget = "slider";
	float UIMax = 1.0;
	float UIMin = -1.0;
	float UIStep = 0.01;
> = 0;

float ImageStatic<
	string UIWidget = "slider";
	float UIMax = 1.0;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = 0;

float ImageStaticX<
	string UIWidget = "slider";
	float UIMax = 1.0;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = 0;



float VolumeBlur <
	string UIWidget = "slider";
	float UIMax = .1;
	float UIMin = 0;
	float UIStep = 0.001;
> = .0125;

float VolumeStrength<
	string UIWidget = "slider";
	float UIMax = 1;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = .25;

float VolumeX<
	string UIWidget = "slider";
	float UIMax = 1;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = .5;
float VolumeY<
	string UIWidget = "slider";
	float UIMax = 1;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = .5;



float BloomBlur<
	string UIWidget = "slider";
	float UIMax = 1;
	float UIMin = 0;
	float UIStep = 0.01;
> = 1;

float BloomStrength<
	string UIWidget = "slider";
	float UIMax = 1;
	float UIMin = 0.0;
	float UIStep = 0.01;
> = 1;







texture frameImg : RENDERCOLORTARGET
< 
	string ResourceName = "";
	float2 ViewportRatio = { 1.0, 1.0 };
>;

sampler2D FrameMap = sampler_state {
    Texture = < frameImg >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Clamp; AddressV = Mirror;
};





texture Volume1Img : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.5, 0.5 };
>;

sampler2D Volume1Map = sampler_state {
    Texture = < Volume1Img >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Border; AddressV = Border;
};

texture Volume2Img : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.5, 0.5 };
>;

sampler2D Volume2Map = sampler_state {
    Texture = < Volume2Img >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Border; AddressV = Border;
};

texture Volume3Img : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.5, 0.5 };
>;

sampler2D Volume3Map = sampler_state {
    Texture = < Volume3Img >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Clamp; AddressV = Clamp;
};





texture DownImg : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.25, 0.25 };
>;

sampler2D DownMap = sampler_state {
    Texture = < DownImg >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Clamp; AddressV = Clamp;
};

texture Bloom1Img : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.1, 0.1 };
>;

sampler2D Bloom1Map = sampler_state {
    Texture = < Bloom1Img >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Clamp; AddressV = Clamp;
};

texture Bloom2Img : RENDERCOLORTARGET 
< 
	string ResourceName = ""; 
	float2 ViewportRatio = { 0.1, 0.1 };
>;

sampler2D Bloom2Map = sampler_state {
    Texture = < Bloom2Img >;
    MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
    AddressU = Clamp; AddressV = Clamp;
};










struct input 
{
	float4 pos : POSITION;
	float2 uv : TEXCOORD0;
};
 
struct output {

	float4 pos: POSITION;
	float2 uv: TEXCOORD0;

};

output VS( input IN ) 
{
	output OUT;
	float4 oPos = float4( IN.pos.xy + float2( -1.0f/ViewSize.x, 1.0f/ViewSize.y ),0.0,1.0 );
	OUT.pos = oPos;

	float2 uv = (IN.pos.xy + 1.0) / 2.0;
	uv.y = 1 - uv.y;
	
	OUT.uv = uv+float2(0,ImageOffset);
	
	return OUT;	
}



 
 
 






float4 PSDown( output IN, uniform sampler2D Image, uniform float reduceRatio ) : COLOR
{
    float color = 0;
    float2 scale = reduceRatio/ViewSize;
    
    for (int i = 0; i < 9; i++)
    {
        float ColorAdd = tex2D( Image, (IN.uv + DownFilterSamples[i].xy*scale)-float2(0,ImageOffset) );
		//color += saturate(ColorAdd-.75)*4;
		color += ColorAdd;
    }
	
    return color/9;
}




float4 PSBloomX( output IN, uniform sampler2D Image ) : COLOR 
{
    float color = 0;
    float2 scale = 1.0f/ViewSize;
	
    for (int i = 0; i < FilterSize; i++) {   
		color += tex2D( Image , (IN.uv + PixelOffsets[i].xy*scale*BloomBlur)-float2(0,ImageOffset) ).x * BlurWeights[i];
    }
	
    return color;
}

float4 PSBloomY( output IN, uniform sampler2D Image ) : COLOR
{
    float color = 0;
    float2 scale = 1.0f/ViewSize;
	
    for (int i = 0; i < FilterSize; i++) {
		float ColorAdd = tex2D( Image , (IN.uv + PixelOffsets[i].yx*scale*BloomBlur)-float2(0,ImageOffset) ).x * BlurWeights[i];
		color += ColorAdd*BloomStrength;
    }
	
    return color;
}





float4 PSVolume( output IN, uniform sampler2D Image , uniform bool Start , uniform float Stretch ) : COLOR
{
    float color = 0;
    float2 scale = 1.0f/ViewSize;
	
    for (int i = 0; i < 8; i++) {
    	float2 VolumeUV=IN.uv-float2(0,ImageOffset);
    	
    	VolumeUV-=float2(VolumeX,VolumeY);
    	VolumeUV/=1+(i*VolumeBlur*Stretch);
    	VolumeUV+=float2(VolumeX,VolumeY);
    	
    	float4 colorAdd=tex2D( Image, VolumeUV ).x;
    	
    	//if (Start==1) colorAdd=smoothstep(.9,1,colorAdd);
    	if (Start==1) colorAdd=saturate(colorAdd-.95)*20;
		colorAdd*=(1-((1.0/8)*i))*VolumeStrength;
		color += colorAdd;
    }
	
    return color;
}





float4 PS( output IN, uniform sampler2D Image, uniform sampler2D VolumeMap, uniform sampler2D BloomMap) : COLOR 
{
	float color=tex2D(Image,IN.uv).x;
	
	color+=saturate(tex2D(Image,float2(ImageStaticX,IN.uv.y)).x-(1-ImageStatic));
	
	color+=tex2D(VolumeMap,IN.uv).x;
	color+=tex2D(BloomMap,IN.uv).x*(1-color);
	
	color = saturate(color)+ImageBrightness;
	float contrast=ImageContrast;
	
	color=color-.5;
	color/=lerp(1,length(color),ImageContrast);
	color=color+.5;
	
    return float4(color,color,color,1);
}












technique Default
<
	string RenderColorTarget = "frameImg";
>
{
	pass Volume1 < string RenderColorTarget = "Volume1Img"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSVolume(FrameMap,1,.5);
	}
	pass Volume2 < string RenderColorTarget = "Volume2Img"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSVolume(Volume1Map,0,2);
	}
	pass Volume3 < string RenderColorTarget = "Volume3Img"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSVolume(Volume2Map,0,8);
	}
	
	
	pass Down < string RenderColorTarget = "DownImg"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSDown(FrameMap,4);
	}
	pass BloomX < string RenderColorTarget = "Bloom1Img"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSBloomX(DownMap);
	}
	pass BloomY < string RenderColorTarget = "Bloom2Img"; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PSBloomY(Bloom1Map);
	}
	
	
	pass Final < string RenderColorTarget = ""; >
	{
		ZEnable = False;
		VertexShader = compile vs_1_1 VS();
		PixelShader = compile ps_2_0 PS( FrameMap , Volume3Map , Bloom2Map );
	}
}