///////////////////////////////////////////////////////////////////
// DG V1 .FX file
// Original Bloom File by iCE La GlacE
// Fully worked reconfigured by PacketOverload
//
// Credits: iCE La GlacE, DKT70, gp65cj04
// PacketOverload, LPF312, Boris Vorontsov & Fabriciuz
///////////////////////////////////////////////////////////////////


float4	BloomParameters;
float4	TempParameters;
float4	ScreenSize;
float BloomRadius3 = 64;
float BloomRadius4 = 128;
float MixFactor = 1.0;
float3 violetpremierepasse = float3(1.0, 1.0, 1.0);
float3 violetsoleil = float3(0.75, 0.75, 0.68);
float3 couleurglobale = float3(1.0, 1.0, 1.0);

//quad
struct VS_OUTPUT_POST
{
	float4 vpos  : POSITION;
	float2 txcoord0 : TEXCOORD0;
};
struct VS_INPUT_POST
{
	float3 pos  : POSITION;
	float2 txcoord0 : TEXCOORD0;
};



texture2D texBloom1;
texture2D texBloom2;
texture2D texBloom3;
texture2D texBloom4;
texture2D texBloom5;

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

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

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

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

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



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

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

	OUT.txcoord0.xy=IN.txcoord0.xy+TempParameters.xy;//1.0/(bloomtexsize*2.0)

	return OUT;
}


//zero pass HQ, input texture is fullscreen
//SamplerBloom1 - fullscreen texture
//zero pass HQ, input texture is fullscreen
//SamplerBloom1 - fullscreen texture
float4 PS_BloomPrePass(VS_OUTPUT_POST In) : COLOR
{
	float4	bloomuv;
	float4	overbright;
	float	bthreshold = 40;



	float4 bloom=tex2D(SamplerBloom1, In.txcoord0);
const float2 offset[16]=
{
float2(-0.94201624, -0.39906216),
float2( 0.94558609, -0.76890725),
float2(-0.09418410, -0.92938870),
float2( 0.34495938,  0.29387760),
float2(-0.91588581,  0.45771432),
float2(-0.81544232, -0.87912464),
float2(-0.38277543,  0.27676845),
float2( 0.97484398,  0.75648379),
float2( 0.44323325, -0.97511554),
float2( 0.53742981, -0.47373420),
float2(-0.26496911, -0.41893023),
float2( 0.79197514,  0.19090188),
float2(-0.24188840,  0.99706507),
float2(-0.81409955,  0.91437590),
float2( 0.19984126,  0.78641367),
float2(-0.14383161, -0.14100790)
};

	float2 screenfact=1;
	screenfact.y*=ScreenSize.z;
	screenfact.xy*=TempParameters.z*6;
	float4 srcbloom=bloom;

	for (int i=0; i<16; i++)
	{
		bloomuv.xy= In.txcoord0.xy;

		//bloomuv.xy=offset[i];
		//bloomuv.xy=(bloomuv.xy*screenfact.xy)+In.txcoord0.xy;//-(1.0/256.0);//-(1.0/512.0);
			
		bloomuv.x = bloomuv.x - 0.5;
		bloomuv.y = 0.5 - bloomuv.y;

		bloomuv.xy -= bloomuv.xy* floor(i*0.35) *0.35;
		bloomuv.xy = -bloomuv.xy;

		bloomuv.xy *= 0.25 + i * 1;

		bloomuv.x = bloomuv.x + 0.5;
		bloomuv.y = 0.5 - bloomuv.y;		

		bloomuv.xy = saturate(bloomuv.xy);

		overbright = tex2D(SamplerBloom1, bloomuv.xy);
		overbright.w = dot(overbright.xyz, 0.3333);
		overbright.w = saturate(overbright.w - bthreshold);
		if(overbright.w)	bloom.xyz += overbright.xyz;
		else
		{
			bloomuv.xy=offset[i];
			bloomuv.xy=(bloomuv.xy*screenfact.xy)+In.txcoord0.xy;//-(1.0/256.0);//-(1.0/512.0);
			bloom+=tex2D(SamplerBloom1, bloomuv.xy);
		}
	}
	bloom*=0.1;//0.125;

	float3 violet=violetsoleil;
	float ttt=dot(bloom.xyz, 0.333)-dot(srcbloom.xyz, 0.333);
	ttt=max(ttt, 0.0);
	float gray=BloomParameters.z*ttt;//max(srcbloom.x, max(srcbloom.y, srcbloom.z));
	float mixfact=(gray/(1.0+gray));
	mixfact*=1.0-saturate((TempParameters.w-1.0)*0.5);
	violet.xy+=saturate((TempParameters.w-1.0)*0.5);
	violet.xy=saturate(violet.xy);
	bloom.xyz*=lerp(1.0, violet.xyz, mixfact);



	bloom.w=1.0;
	return bloom;
}



//first and second passes draw to every texture
//twice, after computations of these two passes,
//result is set as input to next cycle

//first pass
//SamplerBloom1 is result of prepass or second pass from cycle
float4 PS_BloomTexture1(VS_OUTPUT_POST In) : COLOR
{
	float4 bloomuv;
	float4 bloomuv2;

	float4 bloom=tex2D(SamplerBloom1, In.txcoord0);
const float2 offset[16]=
{
float2(-0.94201624, -0.39906216),
float2( 0.94558609, -0.76890725),
float2(-0.09418410, -0.92938870),
float2( 0.34495938,  0.29387760),
float2(-0.91588581,  0.45771432),
float2(-0.81544232, -0.87912464),
float2(-0.38277543,  0.27676845),
float2( 0.97484398,  0.75648379),
float2( 0.44323325, -0.97511554),
float2( 0.53742981, -0.47373420),
float2(-0.26496911, -0.41893023),
float2( 0.79197514,  0.19090188),
float2(-0.24188840,  0.99706507),
float2(-0.81409955,  0.91437590),
float2( 0.19984126,  0.78641367),
float2( 0.14383161, -0.14100790)
};
	float2 screenfact=1.0;
	screenfact.y*=ScreenSize.z;
	screenfact.xy/=ScreenSize.x;
	float4 srcbloom=bloom;
	float step=(TempParameters.w-0.5);//*1.5;
	screenfact.xy*=step;

	float4 bloomadd=bloom;
	for (int i=0; i<16; i++)
	{
		bloomuv.xy=offset[i]*BloomParameters.x;
		bloomuv.xy=(bloomuv.xy*screenfact.xy)+In.txcoord0.xy;//-(1.0/256.0);//-(1.0/512.0);

		bloomuv2.xy=offset[i]*BloomRadius3;
		bloomuv2.xy=(bloomuv2.xy*screenfact.xy)+In.txcoord0.xy;

		//v2
		float4 tempbloom1=tex2D(SamplerBloom1, bloomuv.xy);
		float4 tempbloom2=tex2D(SamplerBloom1, bloomuv2.xy);

		float4 tempbloom = lerp(tempbloom1, tempbloom2, MixFactor);
		bloomadd+=tempbloom;
		
		bloom.xyz = max(bloom.xyz, tempbloom.xyz*0.99);




	}
	//v1
	bloomadd*=0.111111;
	//v0
	bloom.xyz=lerp(bloomadd.xyz, bloom.xyz, BloomParameters.w);


	float3 violet=float3(0.91, 0.7, 0.52);
	//float3 violet=float3(0.6, 0.4, 1.0);//v2
	//float3 violet=violetpremierepasse;//v3

	//this applies when white
	//float gray=0.104*dot(srcbloom.xyz, 0.333);//max(srcbloom.x, max(srcbloom.y, srcbloom.z));
	//this applies on dark and when contrast
	float ttt=dot(bloom.xyz, 0.333)-dot(srcbloom.xyz, 0.333);
	ttt=max(ttt, 0);
	float gray=BloomParameters.z*ttt;//max(srcbloom.x, max(srcbloom.y, srcbloom.z));
	float mixfact=(gray/(1.0+gray));
	mixfact*=1.0-saturate((TempParameters.w-1.0)*0.3);
	violet.xy+=saturate((TempParameters.w-1.0)*0.3);
	violet.xy=saturate(violet.xy);
	bloom.xyz*=lerp(1.0, violet.xyz, mixfact);

	bloom.w=1.0;
	return bloom;
}


//second pass
//SamplerBloom1 is result of first pass
float4 PS_BloomTexture2(VS_OUTPUT_POST In) : COLOR
{
	float4 bloomuv;
	float4 bloomuv2;

	float4 bloom=tex2D(SamplerBloom1, In.txcoord0);
const float2 offset[16]=
{
float2(-0.94201624, -0.39906216),
float2( 0.94558609, -0.76890725),
float2(-0.09418410, -0.92938870),
float2( 0.34495938,  0.29387760),
float2(-0.91588581,  0.45771432),
float2(-0.81544232, -0.87912464),
float2(-0.38277543,  0.27676845),
float2( 0.97484398,  0.75648379),
float2( 0.44323325, -0.97511554),
float2( 0.53742981, -0.47373420),
float2(-0.26496911, -0.41893023),
float2( 0.79197514,  0.19090188),
float2(-0.24188840,  0.99706507),
float2(-0.81409955,  0.91437590),
float2( 0.19984126,  0.78641367),
float2( 0.14383161, -0.14100790)
};
	float2 screenfact=1.0;
	screenfact.y*=ScreenSize.z;
	screenfact.xy/=ScreenSize.x;
	float4 srcbloom=bloom;

	float step=(TempParameters.w-0.5)*1.2;//v3
	screenfact.xy*=step;
	float4 rotvec=0.0;
	sincos(0.19635, rotvec.x, rotvec.y);
	for (int i=0; i<16; i++)
	{

		bloomuv.xy=offset[i];
		bloomuv.xy=reflect(bloomuv.xy, rotvec.xy);
		bloomuv.xy*=BloomParameters.y;
		//separate code is much faster without constant table operations
		bloomuv.xy=(bloomuv.xy*screenfact.xy)+In.txcoord0.xy;//-(1.0/256.0);//-(1.0/512.0);

		float4 tempbloom1 = tex2D(SamplerBloom1, bloomuv.xy);



		bloomuv2.xy=offset[i];
		bloomuv2.xy=reflect(bloomuv2.xy, rotvec.xy);
		bloomuv2.xy*=BloomRadius4;
		bloomuv2.xy=(bloomuv2.xy*screenfact.xy)+In.txcoord0.xy;//-(1.0/256.0);//-(1.0/512.0);
		float4 tempbloom2 = tex2D(SamplerBloom1, bloomuv2.xy);

		float4 tempbloom = lerp(tempbloom1, tempbloom2, MixFactor);

		bloom+=tempbloom;

	}
	float3 violet=couleurglobale;
	float ttt=dot(bloom.xyz, 0.333)-dot(srcbloom.xyz, 0.333);
	ttt=max(ttt, 0.0);
	float gray=BloomParameters.z*ttt;//max(srcbloom.x, max(srcbloom.y, srcbloom.z));
	float mixfact=(gray/(1.0+gray));
	mixfact*=1.0-saturate((TempParameters.w-1.0)*0.3);
	violet.xy+=saturate((TempParameters.w-1.0)*0.3);
	violet.xy=saturate(violet.xy);
	bloom.xyz*=lerp(1.0, violet.xyz, mixfact);
	bloom*=0.046;//0.125;

	bloom.w=1.0;
	return bloom;
}



//last pass, mix several bloom textures
//SamplerBloom5 is the result of prepass
float4 PS_BloomPostPass(VS_OUTPUT_POST In) : COLOR
{
	float4 bloom;
	float4 temp;
	//v1
	bloom =tex2D(SamplerBloom1, In.txcoord0);
	bloom+=tex2D(SamplerBloom2, In.txcoord0);
	bloom+=tex2D(SamplerBloom3, In.txcoord0);
	bloom+=tex2D(SamplerBloom4, In.txcoord0);
	bloom+=tex2D(SamplerBloom5, In.txcoord0);
	bloom*=0.3;
	temp = bloom;

	//v2
	float4 bloom1=tex2D(SamplerBloom1, In.txcoord0);
	float4 bloom2=tex2D(SamplerBloom2, In.txcoord0);
	float4 bloom3=tex2D(SamplerBloom3, In.txcoord0);
	float4 bloom4=tex2D(SamplerBloom4, In.txcoord0);
	float4 bloom5=tex2D(SamplerBloom5, In.txcoord0);
	bloom=max(bloom1, bloom2);
	bloom=max(bloom, bloom3);
	bloom=max(bloom, bloom4);
	bloom=max(bloom, bloom5);

	bloom = lerp(temp, bloom, 0.3);

	//bloom =tex2D(SamplerBloom1, In.txcoord0);

	bloom.w=1.0;
	return bloom;
}



technique BloomPrePass
{
    pass p0
    {
	VertexShader = compile vs_3_0 VS_Bloom();
	PixelShader  = compile ps_3_0 PS_BloomPrePass();

	COLORWRITEENABLE=ALPHA|RED|GREEN|BLUE;
	CullMode=NONE;
	AlphaBlendEnable=TRUE;
	AlphaTestEnable=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
	}
}

technique BloomTexture1
{
    pass p0
    {
	VertexShader = compile vs_3_0 VS_Bloom();
	PixelShader  = compile ps_3_0 PS_BloomTexture1();

	COLORWRITEENABLE=ALPHA|RED|GREEN|BLUE;
	CullMode=NONE;
	AlphaBlendEnable=TRUE;
	AlphaTestEnable=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
	}
}


technique BloomTexture2
{
    pass p0
    {
	VertexShader = compile vs_3_0 VS_Bloom();
	PixelShader  = compile ps_3_0 PS_BloomTexture2();

	COLORWRITEENABLE=ALPHA|RED|GREEN|BLUE;
	CullMode=NONE;
	AlphaBlendEnable=TRUE;
	AlphaTestEnable=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
	}
}

technique BloomPostPass
{
    pass p0
    {
	VertexShader = compile vs_3_0 VS_Bloom();
	PixelShader  = compile ps_3_0 PS_BloomPostPass();

	COLORWRITEENABLE=ALPHA|RED|GREEN|BLUE;
	CullMode=NONE;
	AlphaBlendEnable=TRUE;
	AlphaTestEnable=FALSE;
	SEPARATEALPHABLENDENABLE=FALSE;
	FogEnable=FALSE;
	SRGBWRITEENABLE=FALSE;
	}
}



