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

134 lines
3.1 KiB
PostScript

#include "common.h"
// Check Modules
#include "check_screenspace.h"
#undef ULTRA_SHADOWS_ON
#undef USE_ULTRA_SHADOWS
#define RAY_PATH 2.0h
#define JITTER_TEXTURE_SIZE 64.0f
#ifdef SUN_SHAFTS_QUALITY
#if SUN_SHAFTS_QUALITY==1
#define FILTER_LOW
#define RAY_SAMPLES 15
#elif SUN_SHAFTS_QUALITY==2
#define RAY_SAMPLES 25
#elif SUN_SHAFTS_QUALITY==3
#define RAY_SAMPLES 30
#endif
#endif
#ifndef FILTER_LOW
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#endif
#include "shadow.h"
float4 volume_range; // x - near plane, y - far plane
float4 sun_shafts_intensity;
uniform float4 ssfx_volumetric;
#ifdef MSAA_OPTIMIZATION
float4 main (v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main (v2p_volume I) : SV_Target
#endif
{
#ifndef SUN_SHAFTS_QUALITY
return float4(0,0,0,0);
#else // SUN_SHAFTS_QUALITY
float2 tc = I.tc.xy / I.tc.w;
float4 pos2d = I.hpos;
float ResScale = 1.0f;
#ifdef SSFX_SHADOWS
ResScale = ssfx_volumetric.w;
#endif
pos2d *= ResScale;
gbuffer_data gbd = gbuffer_load_data( GLD_P(tc, pos2d, ISAMPLE) );
float3 P = gbd.P;
// Variable ray length, variable step dencity, use jittering
float4 J0 = jitter0.Sample( smp_jitter, tc * (screen_res.x / ResScale ) * 1.0 / JITTER_TEXTURE_SIZE );
float coeff = (RAY_SAMPLES - 1*J0.x)/(RAY_SAMPLES*RAY_SAMPLES);
float3 direction = P*coeff;
float depth = P.z;
float deltaDepth = direction.z;
float4 current = mul (m_shadow,float4(P,1.0));
float4 delta = mul (m_shadow, float4(direction,0.0));
float res = 0.0;
float max_density = sun_shafts_intensity;
float density = max_density/RAY_SAMPLES;
// SUN VOLUMETRIC FIXES - SSS Update 14.7
// - Added weapon fade
// - Discard out of bound shadow map sampling
// - Fade volumetric edge
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Volumetric offset when used with SSS extended shadows.
#ifdef SSFX_SHADOWS
current.z += 0.001f * (1.0 + ssfx_volumetric.w * saturate(P.z * 0.1f) * 0.1f);
#else
current.z += 0.001f;
#endif
// Fade Weapon
density *= saturate(depth * 0.8f);
if (depth < 0.0001)
res = max_density;
[unroll (RAY_SAMPLES)]
for ( int i=0; i<RAY_SAMPLES; ++i )
{
// Don't sample out of bounds
if (current.x >= 0 && current.x <= 1 && current.y >= 0 && current.y <= 1)
{
if (depth > 0.1f)
res += density * sample_hw_pcf(current, float4(0.0,0.0,0.0,0.0));
}
depth -= deltaDepth;
current -= delta;
}
float fSturation = -Ldynamic_dir.z;
// Normalize dot product to
fSturation = 0.5*fSturation+0.5;
// Map saturation to 0.2..1
fSturation = 0.80*fSturation+0.20;
res *= fSturation;
// Use fog near/far to fade the sun rays
float fog = saturate(length(P) * fog_params.w + fog_params.x);
#ifdef USE_STRICT_GAMMA_CORRECTION
res = SRGBToLinear(res);
float3 SunColor = SRGBToLinear(Ldynamic_color.rgb);
#else
float3 SunColor = Ldynamic_color.rgb;
#endif
// Fade from "res" to "max_density" using squared fog to get a nice curve
float3 result = lerp(SunColor * max_density * fSturation, SunColor * res, 1.0f - fog * fog);
return float4(result, 1);
#endif // SUN_SHAFTS_QUALITY
}