#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); }