#include "common.h"

#define BLUR_QUALITY 2
#define BLUR_DIRECTIONS 8
#define BLUR_SIZE 8
#define BLUR_DIST 0.5

uniform float4 m_hud_params;
float4 ogse_c_screen;

float4 SSFX_get_position(float2 tc, uint iSample : SV_SAMPLEINDEX)
{
	#ifndef USE_MSAA
		return s_position.SampleLevel(smp_nofilter, tc, 0);
	#else
		return s_position.Load(int3(tc * screen_res.xy, 0), iSample);
	#endif
}

float depth_to_weight(float depth) {
	if (depth < SKY_EPS || depth > 200)
		depth = 200;
	
	return lerp(0, max(BLUR_DIST - depth, 0) / BLUR_DIST, m_hud_params.x);
}

float pixel_weight(float w) {
	if (w < 0.01)
		return 0.05;
	return 1;
}

float3 weapon_blur(float2 tc)
{	
	float2 Radius = float2(BLUR_SIZE / screen_res.x, BLUR_SIZE / screen_res.y);
	float Pi = 6.28318530718;
	
	float3 Orig = s_image.Sample(smp_rtlinear, tc).rgb;
	if (m_hud_params.x == 0)
		return Orig;
	
	float Weight = depth_to_weight(SSFX_get_position(tc, 0).z);
	
	float W = Weight * pixel_weight(Weight);
	float C = pixel_weight(Weight);

	for(int i=BLUR_QUALITY; i>=1; i-=1)
	{
		for(int d=BLUR_DIRECTIONS; d>=1; d-=1)
		{
			float2 curTc = tc + float2(cos(Pi / BLUR_DIRECTIONS * d), sin(Pi / BLUR_DIRECTIONS * d)) * Radius / BLUR_QUALITY * i;
			float w = depth_to_weight(SSFX_get_position(curTc, 0).z);

			W += w * pixel_weight(w);
			C += pixel_weight(w);
		}
	}
	
	W /= C;
	W = max(W, Weight);
	
	return lerp(Orig, s_blur_2.SampleLevel(smp_rtlinear, tc, 0).rgb, W);
}

float4 main(p_screen I) : SV_TARGET
{
	return float4(weapon_blur(I.tc0), 1);
}