//++++++++++++++++++++++++++++++++++++++++++++
// ENBSeries effect file
// visit http://enbdev.com for updates
// Copyright (c) 2007-2012 Boris Vorontsov
//++++++++++++++++++++++++++++++++++++++++++++
//THIS IS HLSL FILE FORMAT FOR EXECUTING ADDITIONAL
//POST PROCESSING EFFECTS. MAKE THE COPY BEFORE CHANGING IT!

//kind of old black-white tv filter

//enable separation by 625 scanlines
//#define ESCANLINE


//+++++++++++++++++++++++++++++
//internal parameters, can be modified
//+++++++++++++++++++++++++++++
float3 GrayFilter=float3(1.0, 0.7, 0.4);
float Brightness=0.4;
float ClampLow=0.03;
float ClampHigh=0.95;

float NoiseMixCurve=0.8;
float NoiseMixMultiplier=1.5;
float AdditiveNoiseFactor=0.2;
float MultiplicativeNoiseMin=0.5;
float MultiplicativeNoiseMax=1.5;

float BlurSamplingRange=1.0;//horizontal blur




//+++++++++++++++++++++++++++++
//external parameters, do not modify
//+++++++++++++++++++++++++++++
//keyboard controlled temporary variables (in some versions exists in the config file). Press and hold key 1,2,3...8 together with PageUp or PageDown to modify. By default all set to 1.0
float4	tempF1; //0,1,2,3
float4	tempF2; //5,6,7,8
float4	tempF3; //9,0
//x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4	Timer;
//x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
float4	ScreenSize;



//textures
texture2D texColor;
texture2D texNoise;

sampler2D SamplerColor = sampler_state
{
	Texture   = <texColor>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = NONE;//NONE;
	AddressU  = Clamp;
	AddressV  = Clamp;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};

sampler2D SamplerNoise = sampler_state
{
	Texture   = <texNoise>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = NONE;//NONE;
	AddressU  = Wrap;
	AddressV  = Wrap;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};


struct VS_OUTPUT_POST
{
	float4 vpos  : POSITION;
	float2 txcoord : TEXCOORD0;
};

struct VS_INPUT_POST
{
	float3 pos  : POSITION;
	float2 txcoord : TEXCOORD0;
};



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
	VS_OUTPUT_POST OUT;

	float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

	OUT.vpos=pos;
	OUT.txcoord.xy=IN.txcoord.xy;

	return OUT;
}




//1
float4 PS_ProcessColor(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;
	coord.xy=IN.txcoord.xy;

	float4 origcolor=tex2Dlod(SamplerColor, coord);

	//black-white filter
	origcolor.xyz=dot(origcolor.xyz, GrayFilter.xyz);
	//scale
	origcolor.xyz*=Brightness;
	//limit
	origcolor.xyz=clamp(origcolor.xyz, ClampLow, ClampHigh);


	//noise
	coord.xy=IN.txcoord.xy*ScreenSize.y*4000.0;
	coord.y+=frac(Timer.x * 140000.0);
	float4 noisebig=tex2D(SamplerNoise, coord);
	float mixfact=noisebig.x;
	mixfact=saturate((mixfact-0.5)*16.0);

	coord.xy=IN.txcoord.xy*ScreenSize.x*0.008;
	coord.x+=frac((noisebig.y)*frac(Timer.x*100000.0)*1.3);
	coord.y+=frac(Timer.x*160000.0);
	float4 noisecolor=tex2D(SamplerNoise, coord);
	noisecolor.w=lerp(noisecolor.x, noisecolor.y, mixfact);


	//mix gray with noise
	mixfact=dot(origcolor.xyz, 0.333);
	mixfact=pow(saturate(NoiseMixMultiplier*mixfact), NoiseMixCurve);
	noisecolor.x=noisecolor.w*AdditiveNoiseFactor;
	noisecolor.w=lerp(MultiplicativeNoiseMin, MultiplicativeNoiseMax, noisecolor.w);
	res.xyz=lerp(origcolor.xyz*noisecolor.w+noisecolor.x, origcolor.xyz, mixfact);

	res.w=1.0;
	return res;
}



//2
float4 PS_ProcessHorizontalBlur(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;

	coord.xy=IN.txcoord.xy;

	coord.w=0.0;

	int i=0;

	float4 tcol=0.0;
	float2 invscreensize=ScreenSize.y;
	float offset=-2.0;
	for (i=0; i<5; i++)
	{
		coord.x=IN.txcoord.x+offset*invscreensize*BlurSamplingRange;
		float4 ct=tex2Dlod(SamplerColor, coord);

		tcol+=ct;
		offset+=1.0;
	}
	res.xyz=tcol.xyz*0.2;

	res.w=1.0;
	return res;
}



//3
float4 PS_ProcessScanlines(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;

	coord.xy=IN.txcoord.xy;
	float4 origcolor;
	coord.w=0.0;

	coord.y=floor(coord.y*625.0)*0.0016;//625 vertical lines
	res=tex2Dlod(SamplerColor, coord);

	res.w=1.0;
	return res;
}




//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
technique PostProcess
{
	pass P0
	{
		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessColor();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}


technique PostProcess2
{
	pass P0
	{

		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessHorizontalBlur();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}

#ifdef ESCANLINE
technique PostProcess3
{
	pass P0
	{

		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessScanlines();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}
#endif //ESCANLINE


