Divergent/mods/Screen Space Shaders/gamedata/shaders/r3/ssfx_ssr.ps

99 lines
2.8 KiB
PostScript
Raw Normal View History

/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 21
* @ Description: SSR
* @ Modified time: 2024-06-03 09:01
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
//uniform float4 shader_param_7;
#include "screenspace_reflections.h"
float4x4 m_current; // Current projection matrix
float4x4 m_previous; // Previous projection matrix
float4 cam_pos;
Texture2D ssr_image;
Texture2D s_prev_pos;
Texture2D s_gloss_data;
Texture2D s_hud_mask;
float4 main(p_screen I) : SV_Target
{
// Sample buffers and prepare all requiered data ------------------
// Scale TexCoor
float2 tc = I.tc0 * ssr_setup.x;
float2 Pos2D = I.hpos * ssr_setup.x;
// Sample buffers
#ifndef USE_MSAA
float4 Pos = s_position.Sample( smp_nofilter, tc );
#else
float4 Pos = s_position.Load( int3( Pos2D, 0 ), 0 );
#endif
float4 GlossData = s_gloss_data.Sample( smp_linear, tc );
float HUD_mask = s_hud_mask.Sample(smp_nofilter, tc).r;
// Reconstruct Position, Normal and Material
float3 P = float3( Pos.z * ( Pos2D * pos_decompression_params.zw - pos_decompression_params.xy ), Pos.z );
float3 N = gbuf_unpack_normal( Pos.xy );
float mtl = gbuf_unpack_mtl( Pos.w );
// SSR ------------------------------------------------------------
float4 ssr_result = 0;
float2 noise = 0;
// Do the SSR
SSFX_ScreenSpaceReflections(tc, float4(P, mtl), N, GlossData, ssr_result, HUD_mask, noise, 0);
// Accumulation ---------------------------------------------------
// Position
float4 P4 = float4(P, 1.0);
// Get current
float4 p_current = mul(m_current, P4);
// Get previous
float4 p_previous = mul(m_previous, P4);
float3 current = p_current.xyz / p_current.w;
float3 previous = p_previous.xyz / p_previous.w;
// Reprojection UV
float2 uv_rp = float2(current.x - previous.x, current.y - previous.y) * HUD_mask;
uv_rp = float2(uv_rp.x, -uv_rp.y) * 0.5f;
// Prev Position + Reprojection UV
float4 prev_P = s_prev_pos.Sample( smp_linear, (tc - uv_rp) ); //
uv_rp /= ssr_setup.x;
// Disocclusion
float docc = abs(1.0f - P.z / prev_P.z) * 5.0f;
//float vel = saturate(distance(current.xy, previous.xy) * 10.0f);
// Offscreen check
int outoffsrc = any((I.tc0 - uv_rp) < 0) + any((I.tc0 - uv_rp) > (1.0 / ssr_setup.x));
// Previous frame + Reprojection UV
float4 prev = ssr_image.Sample(smp_linear, I.tc0 - uv_rp);
// 0 Current frame ~ 1 Prev frame 1 - 2 - 4
float weight = saturate((0.5f + (ssr_setup.x * 0.1f * HUD_mask)) - (outoffsrc + docc)); // + vel
// Apply gloss intensity data to avoid leaking
ssr_result.rgb *= saturate(GlossData.a * 10.0f); // 0.1f == 1.0f
// ----------------------------------------------------------------
// Mix with previous SSR results. Higher weight more of the previous frame used
return float4(lerp(ssr_result.rgb, prev.rgb, weight ), 1.0f);
}