Added New Mods and Profiles Folders

This is a complete rebuild of the modpack, with all new mods and updates for 1.5.3 of Anomaly.
This commit is contained in:
2025-01-14 05:07:53 -05:00
parent 85c665b107
commit 376b4b9689
21217 changed files with 546254 additions and 0 deletions
@@ -0,0 +1,101 @@
#include "common.h"
#include "lmodel.h"
#include "shadow.h"
// Check Screen Space Shaders modules & addons
#include "check_screenspace.h"
#ifdef SSFX_SSS
int sss_id;
Texture2D s_ssfx_sss;
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// This is the basic primitive used by convex, volumetric lights
// for example spot-lights, one face of the omni lights, etc.
//////////////////////////////////////////////////////////////////////////////////////////
// following options are available to configure compilation:
// USE_LMAP
// USE_LMAPXFORM
// USE_SHADOW
//////////////////////////////////////////////////////////////////////////////////////////
float4 m_lmap[2];
#ifdef MSAA_OPTIMIZATION
float4 main(p_volume I, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main(p_volume I, float4 pos2d : SV_Position ) : SV_Target
#endif
{
float2 tcProj = I.tc.xy / I.tc.w;
gbuffer_data gbd = gbuffer_load_data(GLD_P(tcProj, pos2d, ISAMPLE) );
float4 _P = float4(gbd.P, gbd.mtl );
float4 _N = float4(gbd.N, gbd.hemi );
float4 _C = float4(gbd.C, gbd.gloss );
float m = xmaterial ;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
// FLORA FIXES & IMPROVEMENTS - SSS Update 14.2
// Fix Flora ilumination ( Align normal to light )
#ifdef SSFX_FLORAFIX
if(abs(m - MAT_FLORA) <= 0.05)
{
_N.rgb = -normalize(_P - Ldynamic_pos.xyz);
_C.w *= 0.3f;
}
#endif
// ----- light-model
float rsqr;
float4 light = plight_local(m, _P, _N, _C, Ldynamic_pos, Ldynamic_pos.w, rsqr );
// ----- shadow
float3 Offset = 0;
#ifdef SSFX_SHADOWS
// Biasing ( Use the nDotL from plight_local... )
float bias_int = (1.0 - saturate(dot(_N, -normalize(_P - Ldynamic_pos.xyz)))) * rsqr * Ldynamic_pos.w;
Offset = _N * (0.025f + bias_int * ssfx_shadow_bias.x);
#endif
float4 P4 = float4(_P.xyz + Offset, 1);
float4 PS = mul(m_shadow, P4 );
float s = 1.h;
#ifdef USE_SHADOW
s = shadow( PS );
#endif
// ----- lightmap
float4 lightmap= 1.h;
#ifdef USE_LMAP
#ifdef USE_LMAPXFORM
PS.x = dot(P4, m_lmap[0] );
PS.y = dot(P4, m_lmap[1] );
#endif
// Can use linear with mip point
lightmap = s_lmap.SampleLevel(smp_rtlinear, PS.xy / PS.w, 0 );
#endif
#ifdef SSFX_SSS
if (sss_id > -1)
{
float2 offset = (sss_id < 4 ? float2(0,0) : float2(0.5f,0));
float4 SSS_Sample = s_ssfx_sss.Sample( smp_rtlinear, tcProj * float2(0.5f, 1.0f) + offset ); // (sss_id < 3 ? float2(0,0) : float2(0.5f,0))
s *= SSS_Sample[sss_id % 4];
}
#endif
#ifdef SSFX_ENHANCED_SHADERS
return float4(SRGBToLinear(Ldynamic_color.rgb * lightmap.rgb * s.xxx),1) * light;
#else
return float4( Ldynamic_color * light * s * lightmap);
#endif
}
@@ -0,0 +1,45 @@
#include "common.h"
#include "lmodel.h"
// Check Screen Space Shaders modules & addons
#include "check_screenspace.h"
// TODO: DX10: Move to Load
#ifdef MSAA_OPTIMIZATION
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position ) : SV_Target
#endif
{
const float bias_mul = 0.999f;
// Sample the fat framebuffer:
float2 tcProj = tc.xy / tc.w;
gbuffer_data gbd = gbuffer_load_data( GLD_P(tcProj, pos2d, ISAMPLE) );
float4 _P = float4( gbd.P,gbd.mtl );
float4 _N = float4( gbd.N,gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
float m = xmaterial ;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
// FLORA FIXES & IMPROVEMENTS - SSS Update 14.2
// Fix Flora ilumination ( Align normal to light )
if(abs(m - MAT_FLORA) <= 0.05)
{
_N.rgb = -normalize(_P - Ldynamic_pos.xyz);
_C.w *= 0.3f;
}
float rsqr;
float4 light = plight_local( m, _P, _N, _C, Ldynamic_pos, Ldynamic_pos.w, rsqr );
#ifdef SSFX_ENHANCED_SHADERS
return float4(float4( SRGBToLinear(Ldynamic_color.rgb),1) * light);
#else
return float4(Ldynamic_color * light);
#endif
}
@@ -0,0 +1,104 @@
#include "common.h"
#include "lmodel.h"
// Check Screen Space Shaders modules & addons
#include "check_screenspace.h"
#ifdef SSFX_SSS
#include "screenspace_shadows.h"
Texture2D s_ssfx_sss;
uniform float4 ssfx_issvp;
#endif
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#if SUN_QUALITY>2
#define ULTRA_SHADOWS_ON
#endif // SUN_QUALITY>2
#ifdef ULTRA_SHADOWS_ON
#define USE_ULTRA_SHADOWS
#endif
#include "shadow.h"
uniform float3 view_shadow_proj; // Unused
#ifdef USE_SUNFILTER
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, 1.0);
float4 PS = mul( m_shadow, _P );
float s = shadowtest_sun( PS, I.tcJ ) * sunmask( _P );
return s;
}
#else
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc.xy/I.tc.w, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, gbd.mtl );
float4 _N = float4( gbd.N, gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
// ----- light-model
float m = xmaterial;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float4 light = plight_infinity ( m, _P, _N, _C, Ldynamic_dir );
// ----- shadow
// SHADOWS FIXES - SSS Update 19
// Normal Offset for biasing
float3 NormalOffset = 0;
#ifdef SSFX_SHADOWS
NormalOffset = _N * ssfx_shadow_bias.y;
#endif
float4 P4 = float4( _P.xyz + NormalOffset, 1.0);
float4 PS = mul( m_shadow, P4 );
// SHADOWS FIXES - SSS Update 14.7
// New far edge fading code
float s = shadow( PS ); // Far Shadows
float shadows = sunmask( P4 ); // Clouds. Don't fade clouds.
// Fade UV
float2 FadeUV = PS.xy / PS.w;
// Fade calc
float4 fade = smoothstep(0.0f, 0.1f, float4(FadeUV.x, 1.0f - FadeUV.x, FadeUV.y, 1.0f - FadeUV.y));
float f = fade.x * fade.y * fade.z * fade.w;
s += ( 1.0f - s ) * ( 1.0f - f );
#ifdef SSFX_SSS
s *= saturate(s_ssfx_sss.Sample( smp_nofilter, I.tc.xy / I.tc.w ).b + ssfx_issvp.x);
#endif
// Add Shadows
shadows *= s;
#ifdef SSFX_ENHANCED_SHADERS
return blend( float4( SRGBToLinear( Ldynamic_color.rgb * shadows.xxx ), 1.0f ) * light, I.tc );
#else
return blend( Ldynamic_color * light * shadows, I.tc );
#endif
}
#endif
@@ -0,0 +1,89 @@
#include "common.h"
#include "lmodel.h"
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#if SUN_QUALITY>2
#define ULTRA_SHADOWS_ON
#endif // SUN_QUALITY>2
#ifdef ULTRA_SHADOWS_ON
#define USE_ULTRA_SHADOWS
#endif
#include "shadow.h"
// Check Screen Space Shaders modules & addons
#include "check_screenspace.h"
#ifdef SSFX_SSS
#include "screenspace_shadows.h"
Texture2D s_ssfx_sss;
uniform float4 ssfx_issvp;
#endif
#ifdef USE_SUNFILTER
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, 1.0);
float4 PS = mul( m_shadow, _P );
float s = shadowtest_sun( PS, I.tcJ ) * sunmask( _P );
return s;
}
#else
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc.xy/I.tc.w, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, gbd.mtl );
float4 _N = float4( gbd.N, gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
// ----- light-model
float m = xmaterial;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float4 light = plight_infinity ( m, _P, _N, _C, Ldynamic_dir );
// ----- shadow
// SHADOWS FIXES - SSS Update 19
// Normal Offset for biasing
float3 NormalOffset = 0;
#ifdef SSFX_SHADOWS
NormalOffset = _N * ssfx_shadow_bias.y;
#endif
float4 P4 = float4( _P.xyz + NormalOffset, 1.0);
float4 PS = mul( m_shadow, P4 );
float s = sunmask( P4 );
s *= shadow( PS );
#ifdef SSFX_SSS
s *= saturate(s_ssfx_sss.Sample( smp_nofilter, I.tc.xy / I.tc.w ).b + ssfx_issvp.x);
#endif
#ifdef SSFX_ENHANCED_SHADERS // We have Enhanced Shaders installed
return float4( SRGBToLinear(Ldynamic_color.rgb * s.xxx),1) * light;
#else
return float4( Ldynamic_color * light * s);
#endif
}
#endif
@@ -0,0 +1,74 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 20
* @ Description: Non-directional volumetric shader
* @ Modified time: 2024-02-20 07:26
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
// Remember: If you need new textures or samplers, remember to edit both `accum_volumetric.s` and `accum_volumetric_nomsaa.s`
#include "common.h"
#include "shadow.h"
#ifndef ISAMPLE
#define ISAMPLE 0
#endif
struct v2p
{
float3 lightToPos : TEXCOORD0; // light center to plane vector
float3 vPos : TEXCOORD1; // position in camera space
float fDensity : TEXCOORD2; // plane density along Z axis
};
float4 m_lmap[2];
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
#ifndef MSAA_OPTIMIZATION
float4 main ( v2p I ) : SV_Target
#else
float4 main ( v2p I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#endif
{
// Screen UV ( view to uv ) // TODO : Use the Matrix mul from the vertex shader
float4 Postc = mul(m_P, float4(I.vPos, 1));
float2 tc = (Postc.xy / Postc.w) * float2(0.5f, -0.5f) + 0.5f;
// Shadow matrix
float4 P4 = float4(I.vPos, 1);
float4 PS = mul( m_shadow, P4);
PS.xyz /= PS.w;
// Occlusion from light perspective.
float occ = s_smap.SampleCmpLevelZero( smp_smap, PS.xy, PS.z).x;
// Occlusion from player perspective.
float _depth = 0;
#ifndef USE_MSAA
_depth = s_position.Sample(smp_nofilter, tc).z;
#else
_depth = s_position.Load(int3(tc * screen_res.xy, 0), iSample).z;
#endif
_depth = _depth <= SKY_EPS ? 10000 : _depth; // Sky
occ *= _depth < Postc.z ? 0.0f : 1.0f;
// Texture mask
PS.x = dot( P4, m_lmap[0]);
PS.y = dot( P4, m_lmap[1]);
PS.xy /= PS.w;
float4 lightmap = s_lmap.Sample(smp_jitter, PS.xy);
// Attenuate ( Vanilla light attenuation )
float rsqr = dot( I.lightToPos, I.lightToPos); // distance 2 light (squared)
float att = saturate( 1.0f - rsqr * Ldynamic_pos.w ); // q-linear attenuate
// Add extra attenuation when passing through.
att *= saturate(Postc.z * 2.5f);
// Result
float3 result = I.fDensity * occ * att * lightmap * Ldynamic_color;
return float4( result, 0);
}
@@ -0,0 +1,15 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("accum_volumetric", "accum_volumetric")
: fog (false)
: zb (true,false)
: blend (true,blend.one,blend.one)
: sorting (2, false)
shader:dx10texture ("s_lmap", t_base)
shader:dx10texture ("s_smap", "null")
shader:dx10texture ("s_position", "$user$position")
shader:dx10sampler ("smp_rtlinear")
shader:dx10sampler ("smp_smap")
shader:dx10sampler ("smp_jitter")
end
@@ -0,0 +1,42 @@
#include "common.h"
cbuffer VolumetricLights
{
float3 vMinBounds;
float3 vMaxBounds;
float4 FrustumClipPlane[6];
}
struct v2p
{
float3 lightToPos : TEXCOORD0; // light center to plane vector
float3 vPos : TEXCOORD1; // position in camera space
float fDensity : TEXCOORD2; // plane density alon Z axis
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 hpos : SV_Position;
};
//float4x4 m_texgen;
v2p main ( float3 P : POSITION )
{
v2p o;
float4 vPos;
vPos.xyz = lerp( vMinBounds, vMaxBounds, P); // Position in camera space
vPos.w = 1.0;
o.hpos = mul(m_P, vPos); // xform, input in camera coordinates
o.lightToPos = vPos.xyz - Ldynamic_pos.xyz;
o.vPos = vPos;
o.fDensity = 1.0 / 40.0;
for (int i=0; i<3; ++i)
{
o.clip0[i] = dot( o.hpos, FrustumClipPlane[i]);
o.clip1[i] = dot( o.hpos, FrustumClipPlane[i+3]);
}
return o;
}
@@ -0,0 +1,15 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("accum_volumetric", "accum_volumetric")
: fog (false)
: zb (true,false)
: blend (true,blend.one,blend.one)
: sorting (2, false)
shader:dx10texture ("s_lmap", t_base)
shader:dx10texture ("s_smap", "null")
shader:dx10texture ("s_position", "$user$position")
shader:dx10sampler ("smp_rtlinear")
shader:dx10sampler ("smp_smap")
shader:dx10sampler ("smp_jitter")
end
@@ -0,0 +1,123 @@
#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;
#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;
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.
current.z += 0.001f;
// 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, 0);
#endif // SUN_SHAFTS_QUALITY
}
@@ -0,0 +1,16 @@
#include "check_screenspace_ES.h"
#include "check_screenspace_SSR.h"
#include "check_screenspace_AO.h"
#include "check_screenspace_NVG.h"
#include "check_screenspace_DEBAND.h"
#include "check_screenspace_FOG.h"
#include "check_screenspace_IL.h"
#include "check_screenspace_FLORA.h"
#include "check_screenspace_INTER_GRASS.h"
#include "check_screenspace_NEWGLOSS.h"
#include "check_screenspace_WIND.h"
#include "check_screenspace_SHADOWS.h"
#include "check_screenspace_SSS.h"
#include "check_screenspace_LUT.h"
#include "check_screenspace_PUDDLES.h"
#include "check_screenspace_BLOOM.h"
@@ -0,0 +1 @@
#define SSFX_AO
@@ -0,0 +1 @@
#define SSFX_BLOOM
@@ -0,0 +1 @@
#define SSFX_DEBAND
@@ -0,0 +1 @@
#define SSFX_ENHANCED_SHADERS
@@ -0,0 +1 @@
#define SSFX_FLORAFIX
@@ -0,0 +1 @@
#define SSFX_FOG
@@ -0,0 +1 @@
#define SSFX_INDIRECT_LIGHT
@@ -0,0 +1 @@
#define SSFX_INTER_GRASS
@@ -0,0 +1 @@
#define SSFX_LUT_INUSE
@@ -0,0 +1 @@
#define SSFX_NEWGLOSS
@@ -0,0 +1 @@
#define SSFX_BEEFS_NVG
@@ -0,0 +1 @@
#define SSFX_PUDDLES
@@ -0,0 +1 @@
#define SSFX_SHADOWS
@@ -0,0 +1 @@
#define SSFX_SSR
@@ -0,0 +1 @@
#define SSFX_SSS
@@ -0,0 +1 @@
#define SSFX_WIND
@@ -0,0 +1,295 @@
#include "anomaly_shaders.h"
#include "common.h"
#include "lmodel.h"
#include "hmodel.h"
// Check Addons
#include "check_screenspace.h"
#ifdef SSFX_BEEFS_NVG
#include "night_vision.h"
#endif
#ifdef SSFX_FOG
#include "screenspace_fog.h"
#endif
#ifdef SSFX_AO
#include "settings_screenspace_AO.h"
uniform float4 ssfx_ao_setup;
uniform float4 ssfx_ao_setup2;
Texture2D ssfx_ao;
#endif
#ifdef SSFX_INDIRECT_LIGHT
#include "settings_screenspace_IL.h"
Texture2D ssfx_il;
uniform float4 ssfx_il_setup;
uniform float4 ssfx_il_setup2;
#endif
uniform float4 ssfx_hud_hemi;
Texture2D s_hud_mask;
Texture2D s_half_depth;
#include "ssao.ps"
#ifdef HDAO
#define USE_HDAO 1
#endif
#ifdef SM_5
Texture2D<float> s_occ;
#endif // SM_5
#if SSAO_QUALITY <=3
//#include "ssdo.ps"
#else
#ifndef USE_HDAO
#define USE_HDAO
#endif
#endif
#ifdef USE_HDAO
#if SSAO_QUALITY > 3
#include "ssao_hdao_new.ps"
#endif
#define USE_HDAO_CODE
#if SSAO_QUALITY <=3
#define g_f2RTSize ( screen_res.xy )
#define g_txDepth s_position
#define g_txNormal s_position
#include "ssao_hdao.ps"
#endif
#else // USE_HDAO
#ifdef USE_HBAO
#include "ssao_hbao.ps"
#endif // USE_HBAO
#endif // USE_HDAO
struct _input
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
float2 tcJ : TEXCOORD1; // jitter coords
float4 pos2d : SV_Position;
};
struct _out
{
float4 low : SV_Target0;
float4 high : SV_Target1;
};
// TODO: DX10: Replace Sample with Load
#ifndef MSAA_OPTIMIZATION
_out main ( _input I )
#else
_out main ( _input I, uint iSample : SV_SAMPLEINDEX )
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc0, I.pos2d, ISAMPLE) );
// Sample the buffers:
float4 P = float4( gbd.P, gbd.mtl ); // position.(mtl or sun)
float4 N = float4( gbd.N, gbd.hemi ); // normal.hemi
float4 D = float4( gbd.C, gbd.gloss ); // rgb.gloss
#ifndef USE_MSAA
float4 L = s_accumulator.Sample( smp_nofilter, I.tc0); // diffuse.specular
#else
float4 L = s_accumulator.Load( int3( I.tc0 * screen_res.xy, 0 ), ISAMPLE );
#endif
#ifndef SSFX_NEWGLOSS
if (abs(P.w - MAT_FLORA) <= 0.05) {
// Reapply distance factor to fix overtly glossy plants in distance
// Unfortunately some trees etc don't seem to use the same detail shader
float fAtten = 1 - smoothstep(0, 50, P.z);
D.a *= (fAtten * fAtten);
}
#endif
// static sun
float mtl = P.w;
#ifdef USE_R2_STATIC_SUN
float sun_occ = P.w*2;
mtl = xmaterial;
L += SRGBToLinear(D.rgb * Ldynamic_color.rgb * sun_occ) * plight_infinity (mtl, P.xyz, N.xyz, D.xyzw, Ldynamic_dir);
#endif
// Calculate SSAO
#ifdef USE_MSAA
int2 texCoord = I.pos2d;
#endif
float3 occ = float3(1.0,1.0,1.0);
#ifdef USE_HDAO
#ifdef SM_5
#if SSAO_QUALITY > 3
occ = s_occ.Sample( smp_nofilter, I.tc0);
#else // SSAO_QUALITY > 3
occ = calc_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#endif // SSAO_QUALITY > 3
#else // SM_5
#if SSAO_QUALITY > 3
occ = calc_new_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#else // SSAO_QUALITY > 3
occ = calc_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#endif // SSAO_QUALITY > 3
#endif // SM_5
#else // USE_HDAO
#ifdef USE_HBAO
occ = calc_hbao( P.z, N, I.tc0, I.pos2d );
#else // USE_HBAO
occ = 0;//calc_ssdo(P, N, I.tc0, I.pos2d, ISAMPLE);
#endif
#endif // USE_HDAO
#ifdef SSAO_QUALITY
occ = compute_colored_ao(occ.x, D.xyz);
#endif
L.rgb += L.a * SRGBToLinear(D.rgb); //illum in alpha
// HUD Mask
float HudMask = s_hud_mask.Sample(smp_linear, I.tc0).r;
// HUD hemi
float env_fac = 1.0 - saturate(dot(env_color.rgb, 0.15f));
float hud_hemi = N.w + ssfx_hud_hemi.x * env_fac;
// hemisphere
float3 hdiffuse, hspecular;
hmodel (hdiffuse, hspecular, mtl, lerp(hud_hemi, N.w, HudMask), D, P.xyz, N.xyz);
// IL Implementation
#ifdef SSFX_INDIRECT_LIGHT
float3 IL_sample = ssfx_il.Sample(smp_linear, I.tc0 / ssfx_il_setup.x).rgb;
// Lower highs ~ Higher lows.
IL_sample *= 1.0f / (1.0 + IL_sample);
// Apply HUD intensity
IL_sample *= lerp(ssfx_il_setup2.y, 1.0f, HudMask);
// Vibrance
IL_sample = vibrance( IL_sample, ssfx_il_setup.z );
hdiffuse *= lerp(1.0f, IL_sample * (30.0f * ssfx_il_setup.y), IL_sample); // 30
#endif
// AO implementation
#ifdef SSFX_AO
hdiffuse.rgb *= ssfx_ao.Sample(smp_linear, I.tc0).www;
#else
hdiffuse *= occ;
#endif
hdiffuse.rgb = saturate(hdiffuse.rgb);
float3 color = L.rgb + hdiffuse.rgb;
color = LinearTosRGB(color); //gamma correct
#ifdef SSFX_BEEFS_NVG
//// SOME NVG SHIT ////
float lua_param_nvg_generation = floor(shader_param_8.x); // 1, 2, or 3
float lua_param_nvg_num_tubes = frac(shader_param_8.x) * 10.0f; // 1, 2, 4, 1.1, or 1.2
float lua_param_nvg_gain_current = floor(shader_param_8.y) / 10.0f;
float lua_param_vignette_current = floor(shader_param_8.z) / 100.0f;
// NVG reduces gloss to 0 inside mask
D.a *= (1.0 - compute_lens_mask(aspect_ratio_correction(I.tc0), lua_param_nvg_num_tubes));
//// END NVG SHIT ////
#endif
////////////////////////////////////////////////////////////////////////////////
// here should be distance fog
#ifdef SSFX_FOG
float3 WorldP = mul(m_inv_V, float4(P.xyz, 1));
float fog = SSFX_HEIGHT_FOG(P.xyz, WorldP.y, color);
#else
float distance = length (P.xyz);
float fog = saturate (distance*fog_params.w + fog_params.x);
color = lerp (color,fog_color,fog);
#endif
float skyblend = saturate (fog*fog);
float tm_scale = I.tc0.w; // interpolated from VS
_out o;
#ifndef SSFX_BEEFS_NVG
tonemap(o.low, o.high, color, tm_scale);
o.low.a = skyblend;
o.high.a = skyblend;
return o;
#else
/////////// BEEFS NVGS CHANGES ///////////
if (lua_param_nvg_generation > 0.0f && compute_lens_mask(aspect_ratio_correction(I.tc0), lua_param_nvg_num_tubes) == 1.0f)
{
float lua_param_nvg_gain_offset = floor(shader_param_8.w) / 10.0f;
tonemap(o.low, o.high, color, 10.0f * lua_param_nvg_gain_offset);
// Turn split tonemapping data to YUV and discard UV
o.low.r = dot(o.low.rgb, luma_conversion_coeff);
o.high.r = dot(o.high.rgb, luma_conversion_coeff);
o.low.r *= 4.0f;
o.high.r *= 4.0f;
// Turn s_accumulator data in to YUV and discard UV
o.low.g = pow(dot(L.rgb, luma_conversion_coeff),2.0f)*1.3f;
o.high.g = o.low.g;
// Turn albedo into YUV and discard UV
o.low.b = dot(D.rgb, luma_conversion_coeff);
o.high.b = o.low.b;
o.low *= lua_param_nvg_gain_current;
o.high *= lua_param_nvg_gain_current;
// Extra
o.low.a = skyblend;
o.high.a = skyblend;
// APPLY VIGNETTE
float vignette = calc_vignette(lua_param_nvg_num_tubes, I.tc0, lua_param_vignette_current+0.02);
o.high = clamp(o.high,0.0,1.0);
o.low= clamp(o.low,0.0,1.0);
o.high.rgb *= vignette;
o.low.rgb *= vignette;
}
else
{
tonemap(o.low, o.high, color, tm_scale);
o.low.a = skyblend;
o.high.a = skyblend;
}
return o;
#endif
}
@@ -0,0 +1,178 @@
#include "common.h"
#include "anomaly_shaders.h"
// Check Screen Space Shaders modules
#include "check_screenspace.h"
#ifdef SSFX_BEEFS_NVG
#include "night_vision.h"
#endif
#ifdef SSFX_DEBAND
#include "screenspace_debanding.h"
#endif
// Used by FOG and IL. Keep it here for the moment...
uniform float4 fakescope_params3;
#ifdef SSFX_FOG
#include "screenspace_fog.h"
#include "settings_screenspace_FOG.h"
#endif
#ifdef SSFX_LUT_INUSE
#include "screenspace_lut.h"
#endif
#ifdef SSFX_BLOOM
Texture2D s_ssfx_bloom;
#endif
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef USE_MSAA
Texture2D s_distort;
#define EPSDEPTH 0.001
#else
#ifndef SM_5
Texture2DMS<float4,MSAA_SAMPLES> s_distort;
#else
Texture2DMS<float4> s_distort;
#endif
#define EPSDEPTH 0.001
#endif
//////////////////////////////////////////////////////////////////////////////////////////
float4 e_barrier; // x=norm(.8f), y=depth(.1f), z=clr
float4 e_weights; // x=norm, y=depth, z=clr
float4 e_kernel; // x=norm, y=depth, z=clr
//////////////////////////////////////////////////////////////////////////////////////////
#include "mblur.h"
#include "img_corrections.h"
#include "tonemapping.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
struct c2_out
{
float4 Color : SV_Target;
#ifdef USE_MSAA
float Depth : SV_Depth;
#endif
};
c2_out main( v2p_aa_AA I )
{
c2_out res;
res.Color = float4(0,0,0,0);
int iSample = 0;
gbuffer_data gbd = gbuffer_load_data(I.Tex0, I.HPos, iSample );
float depth = gbd.P.z;
#ifdef USE_DISTORT
#ifndef USE_MSAA
float4 distort = s_distort.Sample(smp_nofilter, I.Tex0);
#else // USE_MSAA
float4 distort = s_distort.Load( int3( I.Tex0 * screen_res.xy, 0 ), iSample );
#endif // USE_MSAA
float2 offset = (distort.xy-(127.0h/255.0h))*def_distort; // fix newtral offset
float2 center = I.Tex0 + offset;
gbuffer_data gbdx = gbuffer_load_data_offset(I.Tex0, center, I.HPos, iSample);
float depth_x = gbdx.P.z;
if ((depth_x+EPSDEPTH)<depth) center = I.Tex0; // discard new sample
#else // USE_DISTORT
float2 center = I.Tex0;
#endif
float3 img = s_image.Load(int3(center.xy * screen_res.xy, 0),0);
#ifdef SSFX_BLOOM
float4 bloom = s_ssfx_bloom.Sample(smp_rtlinear, center);
#else
float4 bloom = s_bloom.Sample(smp_rtlinear, center);
#endif
img = mblur( center, ( gbd ).P, img.rgb);
#ifdef SSFX_FOG
// Calc Fog
float fogresult = SSFX_CALC_FOG(gbd.P);
fogresult *= fogresult;
// Fog Scattering -----------------------
#ifdef G_FOG_USE_SCATTERING
// Blur sample
float3 foggg = s_blur_2.Sample(smp_rtlinear, center);
// Scopes
int disablefog = (fakescope_params3.x > 0 ? 0 : 1);
// NVGs
#ifdef SSFX_BEEFS_NVG
disablefog *= (shader_param_8.x > 0 ? 0 : 1);
#endif
// Blend
img = lerp(img, max(img, foggg), smoothstep(0.2f, 0.8f, fogresult) * disablefog);
#endif
// --------------------------------------
#endif
#ifdef SSFX_DEBAND
#ifdef SSFX_FOG
float Debanding = depth <= SKY_EPS ? 1.0 : fogresult;
#else
float Debanding = depth <= SKY_EPS ? 1.0 : 0;
#endif
// Debanding - SCREEN SPACE SHADERS - UPDATE 12.5
img = lerp(img, ssfx_debanding(img, I.Tex0.xy), Debanding);
#endif
#ifdef SSFX_BEEFS_NVG
// NVG CHANGE TO PREVENT WEIRD COLORS, ONLY APPLY BLOOM WHEN WE'RE NOT IN NVG MASK
float lua_param_nvg_generation = floor(shader_param_8.x); // 1, 2, or 3
float lua_param_nvg_num_tubes = frac(shader_param_8.x) * 10.0f; // 1, 2, 4, 1.1, or 1.2
if (lua_param_nvg_generation < 0.01f && compute_lens_mask(aspect_ratio_correction(I.Tex0), lua_param_nvg_num_tubes) == 0.0f)
{
img = blend_soft(img, bloom.xyz*bloom.w);
}
#else
img = blend_soft(img, bloom.xyz*bloom.w);
#endif
// Color grading --------------------------------
#ifndef SSFX_ENHANCED_SHADERS
if (tnmp_onoff == 1.0)
{
img = Uncharted2ToneMapping(img);
}
#endif
// Vanilla color grading ( Exposure, saturation and gamma )
img = img_corrections(img);
#ifdef SSFX_LUT_INUSE
img = ssfx_lut_pp(img);
#endif
// ----------------------------------------------
#ifdef USE_DISTORT
float3 blurred = bloom*def_hdr ;
img = lerp (img,blurred,distort.z);
#endif
res.Color = float4(img,1.0);
#ifdef USE_MSAA
float4 ptp = mul(m_P, float4(gbd.P, 1));
res.Depth = ptp.w==0?1:ptp.z/ptp.w;
#endif
return res;
}
@@ -0,0 +1,69 @@
#include "common.h"
Texture2D noise_tex;
// Igor: used for volumetric light
#ifndef USE_MSAA
Texture2D s_vollight;
#else
#ifndef SM_5
Texture2DMS<float4,MSAA_SAMPLES> s_vollight;
#else
Texture2DMS<float4> s_vollight;
#endif
#endif
struct _input
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
};
struct _out
{
float4 low : SV_Target0;
float4 high : SV_Target1;
};
// TODO: DX10: Use load instead of sample
_out main( _input I )
{
_out o;
float4 color;
#ifndef USE_MSAA // Get Volumetric Buffer [ No MSAA ]
color = s_vollight.SampleLevel( smp_linear, I.tc0.xy, 0);
// Read Depth
float _depth = s_position.Sample(smp_nofilter, I.tc0.xy).z;
#else // Get Volumetric Buffer [ MSAA ]
float2 tc = I.tc0.xy * screen_res.xy;
color = s_vollight.Load(int3(tc, 0), 0);
[unroll] for(int iSample = 1; iSample < MSAA_SAMPLES; ++iSample)
{
color += s_vollight.Load(int3(tc, 0), iSample);
}
color /= MSAA_SAMPLES;
// Read Depth [ MSAA ]
float _depth = s_position.Load(int3(tc, 0), iSample).z;
#endif
// Noise TC
float2 uv_noise = I.tc0.xy;
uv_noise.x *= screen_res.x / screen_res.y;
// Add noise to dither the result
color = saturate(color - noise_tex.Sample( smp_linear, uv_noise * 2.5).xxxx * 0.01f);
// Discard Sky.
color *= _depth < 0.001 ? 1.0f : saturate(_depth * 1.5f);
tonemap(o.low, o.high, color, I.tc0.w );
return o;
}
@@ -0,0 +1,17 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("combine_1", "combine_volumetric")
: fog (false)
: zb (false,false)
: blend (true,blend.one,blend.one)
-- : aref (true,0) -- enable to save bandwith?
: sorting (2, false)
shader:dx10texture ("s_vollight", "$user$generic2")
shader:dx10texture ("s_tonemap", "$user$tonemap")
shader:dx10texture ("noise_tex", "fx\\blue_noise")
shader:dx10texture ("s_position", "$user$position")
shader:dx10sampler ("smp_linear")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,24 @@
/*
Common functions used by lighting
Material table
/////////////////
Anomaly Team 2020
/////////////////
*/
#include "common.h"
// SSS Settings
#include "settings_screenspace_FLORA.h"
////////////////////////
//Material table
#define MAT_FLORA 0.15f
#define MAT_FLORA_ELIPSON 0.04f
// Simple subsurface scattering
float3 SSS(float3 N, float3 V, float3 L)
{
float S = saturate(dot(V, -(L + N))) * ssfx_florafixes_2.x;
return S * lerp(float3(1.0f, 1.0f, 1.0f), L_sun_color.rgb, ssfx_florafixes_2.y);
}
@@ -0,0 +1,461 @@
#ifndef common_iostructs_h_included
#define common_iostructs_h_included
////////////////////////////////////////////////////////////////
// This file contains io structs:
// v_name : input for vertex shader.
// v2p_name: output for vertex shader.
// p_name : input for pixel shader.
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// TL0uv
struct v_TL0uv_positiont
{
float4 P : POSITIONT;
float4 Color : COLOR;
};
struct v_TL0uv
{
float4 P : POSITION;
float4 Color : COLOR;
};
struct v2p_TL0uv
{
float4 Color : COLOR;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_TL0uv
{
float4 Color : COLOR;
// float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// TL
struct v_TL_positiont
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
};
struct v_TL
{
float4 P : POSITION;
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
};
struct v2p_TL
{
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_TL
{
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
// float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// TL2uv
struct v_TL2uv
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
};
struct v2p_TL2uv
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_TL2uv
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
};
////////////////////////////////////////////////////////////////
// postpr
struct v_postpr
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
};
struct v2p_postpr
{
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_postpr
{
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
// float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// build (bloom_build)
struct v_build
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
};
struct v2p_build
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_build
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
};
////////////////////////////////////////////////////////////////
// filter (bloom_filter)
struct v_filter
{
float4 P : POSITIONT;
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
};
struct v2p_filter
{
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
struct p_filter
{
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
};
////////////////////////////////////////////////////////////////
// aa_AA
struct v_aa_AA
{
float4 P :POSITIONT;
float2 Tex0 :TEXCOORD0;
float2 Tex1 :TEXCOORD1;
float2 Tex2 :TEXCOORD2;
float2 Tex3 :TEXCOORD3;
float2 Tex4 :TEXCOORD4;
float4 Tex5 :TEXCOORD5;
float4 Tex6 :TEXCOORD6;
};
struct v2p_aa_AA
{
float2 Tex0 :TEXCOORD0;
float2 Tex1 :TEXCOORD1;
float2 Tex2 :TEXCOORD2;
float2 Tex3 :TEXCOORD3;
float2 Tex4 :TEXCOORD4;
float4 Tex5 :TEXCOORD5;
float4 Tex6 :TEXCOORD6;
float4 HPos :SV_Position; // Clip-space position (for rasterization)
};
struct p_aa_AA
{
float2 Tex0 :TEXCOORD0;
float2 Tex1 :TEXCOORD1;
float2 Tex2 :TEXCOORD2;
float2 Tex3 :TEXCOORD3;
float2 Tex4 :TEXCOORD4;
float4 Tex5 :TEXCOORD5;
float4 Tex6 :TEXCOORD6;
};
struct p_aa_AA_sun
{
float2 tc :TEXCOORD0;
float2 unused :TEXCOORD1;
float2 LT :TEXCOORD2;
float2 RT :TEXCOORD3;
float2 LB :TEXCOORD4;
float2 RB :TEXCOORD5;
};
////////////////////////////////////////////////////////////////
// dumb
struct v_dumb
{
float4 P :POSITION; // Clip-space position (for rasterization)
};
struct v2p_dumb
{
float4 HPos :SV_Position; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// Volume
struct v2p_volume
{
float4 tc :TEXCOORD0;
#ifdef USE_SJITTER
float4 tcJ :TEXCOORD1;
#endif
float4 hpos :SV_Position; // Clip-space position (for rasterization)
};
struct p_volume
{
float4 tc :TEXCOORD0;
#ifdef USE_SJITTER
float4 tcJ :TEXCOORD1;
#endif
};
////////////////////////////////////////////////////////////////
// Static
struct v_static
{
float4 Nh :NORMAL; // (nx,ny,nz,hemi occlusion)
float4 T :TANGENT; // tangent
float4 B :BINORMAL; // binormal
int2 tc :TEXCOORD0; // (u,v)
#ifdef USE_LM_HEMI
int2 lmh :TEXCOORD1; // (lmu,lmv)
#endif
float4 P :POSITION; // (float,float,float,1)
};
struct v_static_color
{
float4 Nh :NORMAL; // (nx,ny,nz,hemi occlusion)
float4 T :TANGENT; // tangent
float4 B :BINORMAL; // binormal
int2 tc :TEXCOORD0; // (u,v)
#ifdef USE_LM_HEMI
int2 lmh :TEXCOORD1; // (lmu,lmv)
#endif
float4 color :COLOR0; // (r,g,b,dir-occlusion) // Swizzle before use!!!
float4 P :POSITION; // (float,float,float,1)
};
////////////////////////////////////////////////////////////////
// Defer bumped
struct v2p_bumped
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position: TEXCOORD1; // position + hemi
float3 M1 : TEXCOORD2; // nmap 2 eye - 1
float3 M2 : TEXCOORD3; // nmap 2 eye - 2
float3 M3 : TEXCOORD4; // nmap 2 eye - 3
float4 RDrops : TEXCOORD7; // SSS Update 17 - HUD raindrops
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD5; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD6; // lm-hemi
#endif
float4 hpos : SV_Position;
};
struct p_bumped
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position: TEXCOORD1; // position + hemi
float3 M1 : TEXCOORD2; // nmap 2 eye - 1
float3 M2 : TEXCOORD3; // nmap 2 eye - 2
float3 M3 : TEXCOORD4; // nmap 2 eye - 3
float4 RDrops : TEXCOORD7; // SSS Update 17 - HUD raindrops
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD5; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD6; // lm-hemi
#endif
};
////////////////////////////////////////////////////////////////
// Defer flat
struct v2p_flat
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position: TEXCOORD1; // position + hemi
float3 N : TEXCOORD2; // Eye-space normal (for lighting)
float4 RDrops : TEXCOORD7; // SSS Update 17 - HUD raindrops
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD3; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD4; // lm-hemi
#endif
float4 hpos : SV_Position;
};
struct p_flat
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position: TEXCOORD1; // position + hemi
float3 N : TEXCOORD2; // Eye-space normal (for lighting)
float4 RDrops : TEXCOORD7; // SSS Update 17 - HUD raindrops
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD3; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD4; // lm-hemi
#endif
};
////////////////////////////////////////////////////////////////
// Shadow
struct v_shadow_direct_aref
{
float4 P : POSITION; // (float,float,float,1)
int4 tc : TEXCOORD0; // (u,v,frac,???)
};
struct v_shadow_direct
{
float4 P : POSITION; // (float,float,float,1)
};
struct v2p_shadow_direct_aref
{
float2 tc0 : TEXCOORD1; // Diffuse map for aref
float4 hpos : SV_Position; // Clip-space position (for rasterization)
};
struct v2p_shadow_direct
{
float4 hpos : SV_Position; // Clip-space position (for rasterization)
};
struct p_shadow_direct_aref
{
float2 tc0 : TEXCOORD1; // Diffuse map for aref
};
////////////////////////////////////////////////////////////////
// Model
struct v_model
{
float4 P : POSITION; // (float,float,float,1)
float3 N : NORMAL; // (nx,ny,nz)
float3 T : TANGENT; // (nx,ny,nz)
float3 B : BINORMAL; // (nx,ny,nz)
float2 tc : TEXCOORD0; // (u,v)
};
////////////////////////////////////////////////////////////////
// Tree
struct v_tree
{
float4 P : POSITION; // (float,float,float,1)
float4 Nh : NORMAL; // (nx,ny,nz)
float3 T : TANGENT; // tangent
float3 B : BINORMAL; // binormal
int4 tc : TEXCOORD0; // (u,v,frac,???)
};
////////////////////////////////////////////////////////////////
// Details
struct v_detail
{
float4 pos : POSITION; // (float,float,float,1)
int4 misc : TEXCOORD0; // (u(Q),v(Q),frac,matrix-id)
};
////////for screenspace transformation
struct p_screen
{
float4 hpos : SV_Position;
float2 tc0 : TEXCOORD0; // Texture coordinates (for sampling maps)
};
struct v2p_screen
{
float2 tc0 : TEXCOORD0;
#ifdef SM_2_0
float4 HPos : POSITION; // Clip-space position (for rasterization)
#else
float4 HPos : POSITIONT; // Clip-space position (for rasterization)
#endif
};
//////for fucking sunshafts kurwa
struct v_ssss
{
float4 P : POSITIONT;
float2 tc0 : TEXCOORD0;
};
struct v2p_ssss
{
float2 tc0 : TEXCOORD0;
float4 HPos : SV_Position; // Clip-space position (for rasterization)
};
#endif // common_iostructs_h_included
@@ -0,0 +1,111 @@
#if ( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
#define EXTEND_F_DEFFER
#endif
#include "common.h"
#include "sload.h"
Texture2D s_rain_tex;
// SSS Settings
#include "settings_screenspace_FLORA.h"
#ifdef ATOC
float4 main ( p_bumped I ) : SV_Target
{
surface_bumped S = sload (I);
S.base.w = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
return S.base;
}
#else // ATOC
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I, float4 pos2d : SV_Position )
#else // MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I )
#endif // MSAA_ALPHATEST_DX10_1_ATOC
{
f_deffer O;
#if !defined(MSAA_ALPHATEST_DX10_1)
surface_bumped S = sload (I);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_0_ATOC) )
clip (S.base.w-def_aref);
#endif // !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1_ATOC) )
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
float alpha = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
uint mask = alpha_to_coverage ( alpha, pos2d );
#endif // MSAA_ALPHATEST_DX10_1_ATOC
#else // !defined(MSAA_ALPHATEST_DX10_1)
uint mask = 0x0;
surface_bumped S = sload (I,MSAAOffsets[0]*(1.0/16.0));
if( S.base.w-def_aref >= 0 ) mask |= 0x1;
[unroll] for( int i = 1; i < MSAA_SAMPLES; ++i )
{
surface_bumped SI = sload (I,MSAAOffsets[i]*(1.0/16.0));
if( SI.base.w-def_aref >= 0 ) mask |= ( uint(0x1) << i );
}
if( mask == 0x0 )
discard;
#endif // !defined(MSAA_ALPHATEST_DX10_1)
// FLORA FIXES & IMPROVEMENTS - SSS Update 18
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
//S.normal.xy += float2(.02f, .02f);
S.normal.xy *= max(5.0f * rain_params.y, 3.0f);
// FLORA FIXES & IMPROVEMENTS - SSS Update 14
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Normal from texture and force Y vector to generate a nice fake SSS and specular
// Sun works extremly well with this fake normal, but point lights and others need a fix later on 'accum_base.ps' and 'accum_omni_unshadowed.ps'
float3 Ne = mul(m_WV, (float3(S.normal.x, 1.0f, S.normal.y)));
Ne = normalize (Ne);
// Material value ( MAT_FLORA )
float ms = 0.15f;
// Gloss
S.gloss = lerp(ssfx_florafixes_1.z, ssfx_florafixes_1.w, rain_params.y);
// -----------------------------------------------------------------------
#ifdef USE_LM_HEMI
// float4 lm = tex2D (s_hemi, I.lmh);
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
//float h = dot (lm.rgb,1.h/3.h);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
#ifndef EXTEND_F_DEFFER
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.rgb, S.gloss) );
#else
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.rgb, S.gloss),
mask );
#endif
return O ;
}
#endif // ATOC
@@ -0,0 +1 @@
#include "deffer_base_hud_aref_bump.ps"
@@ -0,0 +1,125 @@
#if ( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
#define EXTEND_F_DEFFER
#endif
#include "common.h"
#include "sload.h"
#include "screenspace_hud_raindrops.h"
#include "check_screenspace.h"
#ifdef ATOC
float4 main ( p_bumped I ) : SV_Target
{
surface_bumped S = sload(I);
S.base.w = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
return S.base;
}
#else // ATOC
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I, float4 pos2d : SV_Position )
#else // MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I )
#endif // MSAA_ALPHATEST_DX10_1_ATOC
{
f_deffer O;
#if !defined(MSAA_ALPHATEST_DX10_1)
surface_bumped S = sload (I);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_0_ATOC) )
clip (S.base.w-def_aref);
#endif // !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1_ATOC) )
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
float alpha = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
uint mask = alpha_to_coverage ( alpha, pos2d );
#endif // MSAA_ALPHATEST_DX10_1_ATOC
#else // !defined(MSAA_ALPHATEST_DX10_1)
uint mask = 0x0;
surface_bumped S = sload (I,MSAAOffsets[0]*(1.0/16.0));
if( S.base.w-def_aref >= 0 ) mask |= 0x1;
[unroll] for( int i = 1; i < MSAA_SAMPLES; ++i )
{
surface_bumped SI = sload (I,MSAAOffsets[i]*(1.0/16.0));
if( SI.base.w-def_aref >= 0 ) mask |= ( uint(0x1) << i );
}
if( mask == 0x0 )
discard;
#endif // !defined(MSAA_ALPHATEST_DX10_1)
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
float4 drops = 0; // xy = Normal | z = Overall str | w = reflection str
if (ssfx_hud_drops_1.y > 0)
{
// Calc droplets
drops.xyz = ssfx_hud_raindrops(s_hud_rain, I.RDrops.xyz, 1.0f);
// Only apply to facing up surfaces [ World Y+ ]
drops.xyz *= saturate(I.RDrops.w);
// Intensity from script ( Cover + Rain intensity )
drops.xyz *= ssfx_hud_drops_1.y;
// Refraction
I.tcdh.xy = I.tcdh.xy + drops.xy * ssfx_hud_drops_1.w;
// Reflection adjustments
#ifdef SSFX_SSS
drops.w = ssfx_hud_drops_1.z;
#else
drops.w = ssfx_hud_drops_1.z * dot(L_hemi_color, SSFX_HUD_LIGHTVECTOR);
#endif
drops.w = max(drops.w, 3.0f);
}
// Sample normal, rotate it by matrix, encode position
float3 Ne = mul (float3x3(I.M1, I.M2, I.M3), S.normal + float3(drops.xy * drops.w, 1.0f));
Ne = normalize (Ne);
S.gloss += (ssfx_hud_drops_1.y * ssfx_hud_drops_2.z) + drops.z * ssfx_hud_drops_2.w;
// hemi,sun,material
float ms = xmaterial ;
#ifdef USE_LM_HEMI
// float4 lm = tex2D (s_hemi, I.lmh);
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
//float h = dot (lm.rgb,1.h/3.h);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
#ifndef EXTEND_F_DEFFER
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.xyz, S.gloss));
#else
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.xyz, S.gloss),
mask );
#endif
return O ;
}
#endif // ATOC
@@ -0,0 +1,107 @@
#if ( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
#define EXTEND_F_DEFFER
#endif
#include "common.h"
#include "sload.h"
#ifdef ATOC
float4 main ( p_flat I ) : SV_Target
{
float4 D = s_base.Sample (smp_linear, I.tcdh); //tbase (I.tcdh);
D.w = (D.w-def_aref*0.5f)/(1-def_aref*0.5f);
return D;
}
#else // ATOC
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_flat I, float4 pos2d : SV_Position )
#else // MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_flat I )
#endif // MSAA_ALPHATEST_DX10_1_ATOC
{
f_deffer O;
// 1. Base texture + kill pixels with low alpha
#if !defined(MSAA_ALPHATEST_DX10_1)
float4 D = tbase (I.tcdh);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_0_ATOC) )
clip (D.w-def_aref);
#endif // !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1_ATOC) )
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
float alpha = (D.w-def_aref*0.5f)/(1-def_aref*0.5f);
uint mask = alpha_to_coverage ( alpha, pos2d );
#endif // MSAA_ALPHATEST_DX10_1_ATOC
#else
uint mask = 0x0;
float2 ddx_base = ddx( I.tcdh );
float2 ddy_base = ddy( I.tcdh );
float2 pixeloffset = MSAAOffsets[0]*(1.0/16.0);
float2 texeloffset = pixeloffset.x * ddx_base + pixeloffset.y * ddy_base;
float4 D = tbase(I.tcdh+texeloffset);
if( D.w-def_aref >= 0 ) mask |= 0x1;
[unroll] for( int i = 1; i < MSAA_SAMPLES; ++i )
{
pixeloffset = MSAAOffsets[i]*(1.0/16.0);
texeloffset = pixeloffset.x * ddx_base + pixeloffset.y * ddy_base;
float4 DI = tbase(I.tcdh+texeloffset);
if( DI.w-def_aref >= 0 ) mask |= ( uint(0x1) << i );
}
if( mask == 0x0 )
discard;
#endif
#ifdef USE_TDETAIL
// D.rgb = 2*D.rgb*tex2D (s_detail, I.tcdbump).rgb;
D.rgb = 2*D.rgb * s_detail.Sample( smp_base, I.tcdbump ).rgb;
#endif
// hemi,sun,material
float ms = xmaterial ;
#ifdef USE_LM_HEMI
// float4 lm = tex2D (s_hemi, I.lmh);
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
// float h = dot (lm.rgb,1.h/3.h);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w ;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
// 2. Standart output
float4 Ne = float4(normalize((float3)I.N.xyz), h);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
O = pack_gbuffer(
Ne,
float4(I.position.xyz + Ne.xyz*def_virtualh/2.h, ms),
float4(D.rgb, def_gloss));
#else
O = pack_gbuffer(
Ne,
float4(I.position.xyz + Ne.xyz*def_virtualh/2.h, ms),
float4(D.rgb, def_gloss),
mask );
#endif
return O;
}
#endif // ATOC
@@ -0,0 +1 @@
#include "deffer_base_hud_bump.ps"
@@ -0,0 +1,68 @@
#include "common.h"
#include "sload.h"
#include "screenspace_hud_raindrops.h"
#include "check_screenspace.h"
f_deffer main ( p_bumped I )
{
f_deffer O;
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
float4 drops = 0; // xy = Normal | z = Overall str | w = reflection str
if (ssfx_hud_drops_1.y > 0)
{
// Calc droplets
drops.xyz = ssfx_hud_raindrops(s_hud_rain, I.RDrops.xyz, 1.0f);
// Only apply to facing up surfaces [ World Y+ ]
drops.xyz *= saturate(I.RDrops.w);
// Intensity from script ( Cover + Rain intensity )
drops.xyz *= ssfx_hud_drops_1.y;
// Refraction
I.tcdh.xy = I.tcdh.xy + drops.xy * ssfx_hud_drops_1.w;
// Reflection adjustments
#ifdef SSFX_SSS
drops.w = ssfx_hud_drops_1.z;
#else
drops.w = ssfx_hud_drops_1.z * dot(L_hemi_color, SSFX_HUD_LIGHTVECTOR);
#endif
drops.w = max(drops.w, 3.0f);
}
surface_bumped S = sload(I);
// Add sampled normal and droplets
float3 Ne = mul(float3x3(I.M1, I.M2, I.M3), S.normal + float3(drops.xy * drops.w, 1.0f));
Ne = normalize (Ne);
// hemi,sun,material
float ms = xmaterial;
S.gloss += (ssfx_hud_drops_1.y * ssfx_hud_drops_2.z) + drops.z * ssfx_hud_drops_2.w;
#ifdef USE_LM_HEMI
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne * S.height * def_virtualh, ms),
float4 (S.base.xyz, S.gloss));
return O;
}
@@ -0,0 +1,2 @@
#define USE_PARALLAX
#include "deffer_base_hud_bump_d.ps"
@@ -0,0 +1,4 @@
#define USE_TDETAIL //- shader defined
#include "deffer_base_hud_bump.ps"
@@ -0,0 +1,2 @@
#define USE_TDETAIL_BUMP
#include "deffer_base_hud_bump_d-hq.ps"
@@ -0,0 +1,75 @@
#include "common.h"
#include "sload.h"
#include "screenspace_hud_raindrops.h"
#include "check_screenspace.h"
f_deffer main( p_flat I )
{
f_deffer O;
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
float4 drops = 0; // xy = Normal | z = Overall str | w = reflection str
if (ssfx_hud_drops_1.y > 0)
{
// Calc droplets
drops.xyz = ssfx_hud_raindrops(s_hud_rain, I.RDrops.xyz, 1.0f);
// Only apply to facing up surfaces [ World Y+ ]
drops.xyz *= saturate(I.RDrops.w);
// Intensity from script ( Cover + Rain intensity )
drops.xyz *= ssfx_hud_drops_1.y;
// Refraction
I.tcdh.xy = saturate(I.tcdh.xy + drops.xy * ssfx_hud_drops_1.w * 0.1f);
// Reflection adjustments
#ifdef SSFX_SSS
drops.w = ssfx_hud_drops_1.z;
#else
drops.w = ssfx_hud_drops_1.z * dot(L_hemi_color, SSFX_HUD_LIGHTVECTOR);
#endif
drops.w = max(drops.w * 0.1f, 3.0f);
}
float gloss = drops.z * ssfx_hud_drops_2.w * 0.25f;
// diffuse
float3 D = tbase (I.tcdh); // IN: rgb.a
#ifdef USE_TDETAIL
// D.rgb = 2*D.rgb*tex2D (s_detail, I.tcdbump).rgb;
D.rgb = 2*D.rgb * s_detail.Sample( smp_base, I.tcdbump ).rgb;
#endif
// hemi,sun,material
float ms = xmaterial ;
#ifdef USE_LM_HEMI
// float4 lm = tex2D( s_hemi, I.lmh );
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh );
// float h = dot( lm.rgb, 1.h/3.h );
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w ;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
// 2. Standart output
float4 Ne = float4(normalize((float3)I.N.xyz + float3(drops.xy * drops.w, 0.0f)), h);
O = pack_gbuffer(
Ne,
float4( I.position.xyz + Ne.xyz*def_virtualh/2.h, ms ),
float4( D.rgb, gloss ));
return O;
}
@@ -0,0 +1,141 @@
#if ( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
#define EXTEND_F_DEFFER
#endif
#include "common.h"
#include "sload.h"
#include "check_screenspace.h"
static float DITHER_THRESHOLDS[16] =
{
1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
};
// SSS Settings
#ifdef SSFX_FLORAFIX
#include "settings_screenspace_FLORA.h"
#endif
#ifdef ATOC
float4 main ( p_bumped I ) : SV_Target
{
surface_bumped S = sload (I);
S.base.w = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
return S.base;
}
#else // ATOC
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I, float4 pos2d : SV_Position )
#else // MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I )
#endif // MSAA_ALPHATEST_DX10_1_ATOC
{
f_deffer O;
#if !defined(MSAA_ALPHATEST_DX10_1)
surface_bumped S = sload (I);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_0_ATOC) )
clip (S.base.w-def_aref);
#endif // !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1_ATOC) )
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
float alpha = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
uint mask = alpha_to_coverage ( alpha, pos2d );
#endif // MSAA_ALPHATEST_DX10_1_ATOC
#else // !defined(MSAA_ALPHATEST_DX10_1)
uint mask = 0x0;
surface_bumped S = sload (I,MSAAOffsets[0]*(1.0/16.0));
if( S.base.w-def_aref >= 0 ) mask |= 0x1;
[unroll] for( int i = 1; i < MSAA_SAMPLES; ++i )
{
surface_bumped SI = sload (I,MSAAOffsets[i]*(1.0/16.0));
if( SI.base.w-def_aref >= 0 ) mask |= ( uint(0x1) << i );
}
if( mask == 0x0 )
discard;
#endif // !defined(MSAA_ALPHATEST_DX10_1)
// FLORA FIXES & IMPROVEMENTS - SSS Update 18
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
//S.normal.xy += float2(0.1f, 0.1f);
S.normal.xy *= max(10.0f * rain_params.y, 3.0f);
// FLORA FIXES & IMPROVEMENTS - SSS Update 22
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Fake UP Normal
float3 fN = mul(m_WV, float3(S.normal.x, 1.0f, S.normal.y));
fN = normalize (fN);
// Terrain Normal ( Engine feed the terrain normals )
float3 Ne = float3(I.M1.z, I.M2.z, I.M3.z) + fN;
Ne = normalize (Ne);
float ms = xmaterial;
S.gloss = def_gloss;
// Dither
float4 Postc = mul(m_P, float4(I.position.xyz, 1));
float2 tc = (Postc.xy / Postc.w) * float2(0.5f, -0.5f) + 0.5f;
float2 dither_uv = tc * screen_res.xy; // Aspect ratio
uint dither_idx = (uint(dither_uv.x) % 4) * 4 + uint(dither_uv.y) % 4;
clip(I.M1.x - DITHER_THRESHOLDS[dither_idx]);
#ifdef SSFX_FLORAFIX
// Material value ( MAT_FLORA )
ms = 0.15f;
// Fake gloss
S.gloss = lerp(ssfx_florafixes_1.x, ssfx_florafixes_1.y, rain_params.y);
#endif
// -----------------------------------------------------------------------
#ifdef USE_LM_HEMI
// float4 lm = tex2D (s_hemi, I.lmh);
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
//float h = dot (lm.rgb,1.h/3.h);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
#ifndef EXTEND_F_DEFFER
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.rgb, S.gloss) );
#else
O = pack_gbuffer(
float4 (Ne, h),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms),
float4 (S.base.rgb, S.gloss),
mask );
#endif
return O ;
}
#endif // ATOC
@@ -0,0 +1,125 @@
#define SSFX_WIND_ISGRASS
#include "common.h"
#include "check_screenspace.h"
float4 benders_pos[32];
float4 benders_setup;
float4 exdata[61]; // Terrain Normal [xyz] & Grass alpha [w]
int grass_align;
float4 consts; // {1/quant,1/quant,diffusescale,ambient}
float4 wave; // cx,cy,cz,tm
float4 dir2D;
float4 array[61*4];
float4 wind;
#ifdef SSFX_WIND
#include "screenspace_wind.h"
#endif
v2p_bumped main (v_detail v)
{
v2p_bumped O;
// index
int i = v.misc.w;
float4 m0 = array[i+0];
float4 m1 = array[i+1];
float4 m2 = array[i+2];
float4 c0 = array[i+3];
float4 data = exdata[i / 4]; // Adjust size ( 61 instead of 61*4 )
// Transform pos to world coords
float4 P;
P.x = dot(m0, v.pos);
P.y = dot(m1, v.pos);
P.z = dot(m2, v.pos);
P.w = 1;
float H = P.y - m1.w; // height of vertex (scaled)
// Force grass to go up
P.xz = P.xz - 0.5f * data.xz * H * grass_align;
#ifndef SSFX_WIND
float dp = calc_cyclic(dot(P, wave));
float frac = v.misc.z * consts.x; // fractional
float inten = H * dp;
float2 result = calc_xz_wave(dir2D.xz * inten, frac);
float4 pos = float4(P.x + result.x, P.y, P.z + result.y, 1);
#else
float3 wind_result = ssfx_wind_grass(P.xyz, H, ssfx_wind_setup());
float4 pos = float4(P.xyz + wind_result.xyz, 1);
#endif
// INTERACTIVE GRASS - SSS Update 15.4
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
#ifdef SSFX_INTER_GRASS
#if SSFX_INT_GRASS > 0
for (int b = 0; b < SSFX_INT_GRASS + 1; b++)
{
// Direction, Radius & Bending Strength, Distance and Height Limit
float3 dir = benders_pos[b + 16].xyz;
float3 rstr = float3(benders_pos[b].w, benders_pos[b + 16].ww);
bool non_dynamic = rstr.x <= 0 ? true : false;
float dist = distance(pos.xz, benders_pos[b].xz);
float height_limit = 1.0f - saturate(abs(pos.y - benders_pos[b].y) / ( non_dynamic ? 2.0f : rstr.x ));
height_limit *= H;
// Adjustments ( Fix Radius or Dynamic Radius )
rstr.x = non_dynamic ? benders_setup.x : rstr.x;
rstr.yz *= non_dynamic ? benders_setup.yz : 1.0f;
// Strength through distance and bending direction.
float bend = 1.0f - saturate(dist / (rstr.x + 0.001f));
float3 bend_dir = normalize(pos.xyz - benders_pos[b].xyz) * bend;
float3 dir_limit = dir.y >= -1 ? saturate(dot(bend_dir.xyz, dir.xyz) * 5.0f) : 1.0f; // Limit if nedeed
// Apply direction limit
bend_dir.xz *= dir_limit.xz;
// Apply vertex displacement
pos.xz += bend_dir.xz * 2.0f * rstr.yy * height_limit; // Horizontal
pos.y -= bend * 0.6f * rstr.z * height_limit * dir_limit.y; // Vertical
}
#endif
#endif
// FLORA FIXES & IMPROVEMENTS - SSS Update 22
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Use terrain normal [ c0.xyz ]
float3 N = mul((float3x3)m_WV, data.xyz);
float3x3 xform = 0;
// Normal
xform[0].z = N.x;
xform[1].z = N.y;
xform[2].z = N.z;
// Alpha here
xform[0].x = data.w;
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
// Eye-space pos/normal
float hemi = clamp(c0.w, 0.05f, 1.0f); // Some spots are bugged ( Full black ), better if we limit the value till a better solution. // Option -> v_hemi(N);
float3 Pe = mul (m_V, pos );
O.tcdh = float4 ((v.misc * consts).xyyy);
O.hpos = mul (m_VP, pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
O.tcdh.w = hemi * c_sun.x + c_sun.y; // (,,,dir-occlusion)
#endif
return O;
}
FXVS;
@@ -0,0 +1,192 @@
#include "check_screenspace.h"
#include "settings_screenspace_PUDDLES.h"
#include "settings_screenspace_SSR.h"
#include "common.h"
#include "sload.h"
#include "screenspace_common_ripples.h"
Texture2D s_puddles_normal;
Texture2D s_puddles_perlin;
Texture2D s_puddles_mask;
Texture2D s_rainsplash;
#define USE_4_DETAIL
#if defined(USE_TDETAIL) && defined(USE_4_DETAIL)
# define USE_4_BUMP
#endif
#ifdef USE_4_BUMP
f_deffer main ( p_bumped I )
#else
f_deffer main ( p_flat I )
#endif
{
f_deffer O;
// diffuse
float4 D = tbase (I.tcdh); // IN: rgb.a
float4 L = s_lmap.Sample( smp_base, I.tcdh);
float G = 0.001;
#ifdef USE_TDETAIL
#ifdef USE_4_DETAIL
float4 mask= s_mask.Sample ( smp_base, I.tcdh);
float mag = dot (mask,1);
mask= mask/mag ;
#ifdef USE_4_BUMP
float4 n_Rt = s_dn_r.Sample ( smp_base, I.tcdbump).wzyx;
float4 n_Gt = s_dn_g.Sample ( smp_base, I.tcdbump).wzyx;
float4 n_Bt = s_dn_b.Sample ( smp_base, I.tcdbump).wzyx;
float4 n_At = s_dn_a.Sample ( smp_base, I.tcdbump).wzyx;
float3 n_R = (n_Rt-0.5)*mask.r;
float g_R=n_Rt.w*mask.r;
float3 n_G = (n_Gt-0.5)*mask.g;
float g_G=n_Gt.w*mask.g;
float3 n_B = (n_Bt-0.5)*mask.b;
float g_B=n_Bt.w*mask.b;
float3 n_A = (n_At-0.5)*mask.a;
float g_A=n_At.w*mask.a;
float3 mix = n_R+n_G+n_B+n_A;
mix *= float3(0.6f, 0.6f, 1); // Adjust bump strength
float3 N = mul (float3x3(I.M1, I.M2, I.M3), mix.xyz);
// Puddles Implementation - SSS Update 14.6
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Wetness factor
float wetness_f = rain_params.y;
// Always render puddles if G_PUDDLES_ALLWAYS is defined
#ifdef G_PUDDLES_ALLWAYS
wetness_f = 1.0f;
#endif
// Intensity factor.
float puddles_f = wetness_f;
// Size factor. Convert 0 ~ 1 to 1 ~ -0.1f
float size_f = (1.0f - G_PUDDLES_SIZE * 1.1f);
// Texture mask
float puddles_mask = 1.0f - s_puddles_mask.Sample(smp_base, I.tcdh).r;
// Puddles perlin
float puddles = saturate((s_puddles_perlin.Sample(smp_base, I.tcdh * 15.0f / G_PUDDLES_GLOBAL_SIZE).r - size_f) * puddles_f);
// Get normals and transform space to create a slope mask
float3 N1 = mul(float3x3(I.M1, I.M2, I.M3), float3(0,0,1));
float3 N2 = mul(m_inv_V, normalize(N1));
// Slope mask
float slope = max(N2.x, N2.y);
// Slope adjustements... Some magic numbers
slope = saturate((slope - 0.997f) * (102.0f + 0.997f));
// Slope & texture mask defines final puddles intensity
puddles *= slope * puddles_mask;
// Puddles border hardness
puddles = smoothstep(0, saturate(0.3f - G_PUDDLES_BORDER_HARDNESS * 0.3f), puddles);
#ifdef G_PUDDLES_RIPPLES
float rain_int = saturate(rain_params.x * 1.5f);
// Base ripples anim speed
float ripples_anim = timers.x * ((0.01f + (rain_int * 0.008f)) * G_PUDDLES_RIPPLES_SPEED );
// Base ripples scale
float ripples_scale = 140 / G_PUDDLES_RIPPLES_SCALE;
// Base ripples Normal
float3 WN0 = s_puddles_normal.Sample(smp_base, I.tcdh * ripples_scale + float2(0, ripples_anim));
float3 WN1 = s_puddles_normal.Sample(smp_base, I.tcdh * ripples_scale - float2(0.33f, ripples_anim));
float3 ripplesNormal = ((WN0 + WN1) * 0.5f) * 2.0f - 1.0f;
// Rain Ripples
float2 ripplesUV = I.tcdh * ripples_scale * 1.3f / G_PUDDLES_RAIN_RIPPLES_SCALE;
float2 rainRipples = ssfx_rain_ripples( s_rainsplash, ripplesUV, float3(0.85f, 1.0f, 10.0f), I.position.z);
// Rain ripples intensity... ( Rain intensity * Depth fadeout * Intensity )
rainRipples *= rain_params.x * 3.0f * G_PUDDLES_RAIN_RIPPLES_INTENSITY;
// Base ripples Intensity
ripplesNormal *= saturate(0.05f + rain_int * G_PUDDLES_RIPPLES_RAINING_INT * G_PUDDLES_RIPPLES_INTENSITY);
// Mix ripples
ripplesNormal = ripplesNormal * 0.666f + float3(rainRipples * 0.333f, 0);
#else
float3 ripplesNormal = 0;
#endif
// Normal Up and ripples for puddles
float3 MirrorUp = mul(m_V, float3(ripplesNormal.x, 1.0, ripplesNormal.y));
N = lerp(N, MirrorUp, puddles);
// Refraction Normal
float3 N_refra = ripplesNormal;
// Adjust refraction intensity based on wetness and puddle perlin
N_refra.xy *= 0.15f * smoothstep( 0.6f, 0.8f, wetness_f * puddles ) * G_PUDDLES_REFRACTION_INTENSITY;
// Detail textures + refraction when needed
float2 detail_tc = I.tcdbump + N_refra;
float3 d_R = s_dt_r.Sample ( smp_base, detail_tc) * mask.r;
float3 d_G = s_dt_g.Sample ( smp_base, detail_tc) * mask.g;
float3 d_B = s_dt_b.Sample ( smp_base, detail_tc) * mask.b;
float3 d_A = s_dt_a.Sample ( smp_base, detail_tc) * mask.a;
float3 dt = d_R + d_G + d_B + d_A;
D.rgb = 2 * D.rgb * dt;
// Apply tint
D.rgb = lerp( D.rgb, D.rgb * G_PUDDLES_TINT, puddles);
// Limit pudddle reflection.
puddles = clamp(puddles, 0, G_PUDDLES_REFLECTIVITY);
// Add at the end the extra wetness. Full intensity at 50% of wetness ( rain_params.y )
#ifndef SSFX_NEWGLOSS
puddles = puddles + saturate(rain_params.y * 2.0f) * G_PUDDLES_TERRAIN_EXTRA_WETNESS;
#endif
// Add gloss and puddles to the final gloss result
G = max(g_R + g_G + g_B + g_A, puddles);
#else
float3 N = I.N.xyz ;
#endif
#else
D.rgb = 2*D.rgb*s_detail.Sample( smp_base, I.tcdbump).rgb;
#endif
#else
float3 N = I.N.xyz ;
#endif
// hemi, sun, material
float ms = xmaterial ;
#ifdef USE_R2_STATIC_SUN
ms = L.w ;
#endif
// 2. Standart output
float4 Ne = float4 (normalize(N), D.w );
O = pack_gbuffer(
Ne, // hemi
float4 (I.position.xyz + Ne.xyz*def_virtualh/2.h, 0.95f ), //
float4 (D.x, D.y, D.z, G ) ); // OUT: rgb.gloss
return O;
}
@@ -0,0 +1 @@
#include "deffer_model_hud_bump.vs"
@@ -0,0 +1,99 @@
#include "common.h"
#include "skin.h"
#if defined(USE_PARALLAX) || defined(USE_STEEPPARALLAX)
uniform float3x4 m_invW;
#endif // defined(USE_PARALLAX) || defined(USE_STEEPPARALLAX)
v2p_bumped _main( v_model I, float3 psp )
{
float4 w_pos = I.P;
// Eye-space pos/normal
v2p_bumped O;
O.hpos = mul( m_WVP, w_pos );
float2 tc = I.tc;
float3 Pe = mul( m_WV, w_pos );
O.tcdh = float4( tc.xyyy );
// Hemi cube lighting
float3 Nw = mul ((float3x3)m_W, (float3)I.N);
float3 hc_pos = (float3)hemi_cube_pos_faces;
float3 hc_neg = (float3)hemi_cube_neg_faces;
float3 hc_mixed= (Nw < 0) ? hc_neg : hc_pos;
float hemi_val= dot( hc_mixed, abs(Nw) );
hemi_val = saturate(hemi_val);
O.position = float4(Pe, hemi_val); //Use L_material.x for old behaviour;
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
O.tcdh.w = L_material.y; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
float3 N = I.N; // just scale (assume normal in the -.5f, .5f)
float3 T = I.T; //
float3 B = I.B; //
float3x3 xform = mul ((float3x3)m_WV, float3x3(
2*T.x,2*B.x,2*N.x,
2*T.y,2*B.y,2*N.y,
2*T.z,2*B.z,2*N.z
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform [0];
O.M2 = xform [1];
O.M3 = xform [2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
if (!all(psp))
O.RDrops.xyz = I.P.xyz;
else
O.RDrops.xyz = psp;
O.RDrops.w = Nw.y; // Normal-Y [ World Space ]
return O;
}
/////////////////////////////////////////////////////////////////////////
#ifdef SKIN_NONE
v2p_bumped main(v_model v) { return _main(v, 0); }
#endif
#ifdef SKIN_0
v2p_bumped main(v_model_skinned_0 v) { return _main(skinning_0(v), v.P); }
#endif
#ifdef SKIN_1
v2p_bumped main(v_model_skinned_1 v) { return _main(skinning_1(v), v.P); }
#endif
#ifdef SKIN_2
v2p_bumped main(v_model_skinned_2 v) { return _main(skinning_2(v), v.P); }
#endif
#ifdef SKIN_3
v2p_bumped main(v_model_skinned_3 v) { return _main(skinning_3(v), v.P); }
#endif
#ifdef SKIN_4
v2p_bumped main(v_model_skinned_4 v) { return _main(skinning_4(v), v.P); }
#endif
FXVS;
@@ -0,0 +1,2 @@
#define USE_PARALLAX
#include "deffer_model_hud_bump_d.vs"
@@ -0,0 +1,2 @@
#define USE_TDETAIL
#include "deffer_model_hud_bump.vs"
@@ -0,0 +1,72 @@
#include "common.h"
#include "skin.h"
v2p_flat _main( v_model I, float3 psp )
{
// world-space N
float3 N_w = mul( m_W, I.N );
// Eye-space pos/normal
v2p_flat O;
float3 Pe = mul( m_WV, I.P );
O.hpos = mul( m_WVP, I.P );
O.N = mul( (float3x3)m_WV, (float3)I.N );
O.tcdh = float4( I.tc.xyyy );
// Hemi cube lighting
float3 Nw = mul ((float3x3)m_W, (float3)I.N);
float3 hc_pos = (float3)hemi_cube_pos_faces;
float3 hc_neg = (float3)hemi_cube_neg_faces;
float3 hc_mixed= (Nw < 0) ? hc_neg : hc_pos;
float hemi_val= dot( hc_mixed, abs(Nw) );
hemi_val = saturate(hemi_val);
O.position = float4(Pe, hemi_val); //Use L_material.x for old behaviour;
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
O.tcdh.w = L_material.y; // (,,,dir-occlusion)
#endif
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh*dt_params; // dt tc
#endif
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
if (!all(psp))
O.RDrops.xyz = I.P.xyz;
else
O.RDrops.xyz = psp;
O.RDrops.w = Nw.y; // Normal-Y [ World Space ]
return O;
}
/////////////////////////////////////////////////////////////////////////
#ifdef SKIN_NONE
v2p_flat main(v_model v) { return _main(v, 0); }
#endif
#ifdef SKIN_0
v2p_flat main(v_model_skinned_0 v) { return _main(skinning_0(v), v.P); }
#endif
#ifdef SKIN_1
v2p_flat main(v_model_skinned_1 v) { return _main(skinning_1(v), v.P); }
#endif
#ifdef SKIN_2
v2p_flat main(v_model_skinned_2 v) { return _main(skinning_2(v), v.P); }
#endif
#ifdef SKIN_3
v2p_flat main(v_model_skinned_3 v) { return _main(skinning_3(v), v.P); }
#endif
#ifdef SKIN_4
v2p_flat main(v_model_skinned_4 v) { return _main(skinning_4(v), v.P); }
#endif
FXVS;
@@ -0,0 +1,67 @@
#define USE_TDETAIL
#include "common.h"
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
#define v_in v_static_color
#else
#define v_in v_static
#endif
v2p_bumped main( v_in I )
{
float4 w_pos = I.P ;
float2 tc = unpack_tc_base (I.tc,I.T.w,I.B.w); // copy tc
float hemi = I.Nh.w ;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_WV, w_pos );
O.hpos = mul (m_WVP, w_pos );
O.tcdh = float4 (tc.xyyy );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
O.tcdh.w = I.color.w; // (r,g,b,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
float3 N = unpack_bx4(I.Nh); // just scale (assume normal in the -.5f, .5f)
float3 T = unpack_bx4(I.T); //
float3 B = unpack_bx4(I.B); //
float3x3 xform = mul ((float3x3)m_WV, float3x3(
T.x,B.x,N.x,
T.y,B.y,N.y,
T.z,B.z,N.z
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
#ifdef USE_LM_HEMI
O.lmh = unpack_tc_lmap (I.lmh);
#endif
return O;
}
FXVS;
@@ -0,0 +1,405 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 20
* @ Description: Terrain Shader - HIGH ( Texture Splatting, POM & Puddles )
* @ Modified time: 2024-11-12 11:02
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#define USE_TDETAIL // Keep this here, used by "common_iostructs"
#include "common.h"
#include "check_screenspace.h"
#ifdef SSFX_PUDDLES
#include "settings_screenspace_PUDDLES.h"
#endif
#include "screenspace_common_ripples.h"
// Setup
#include "settings_screenspace_TERRAIN.h"
// Puddles textures
#ifdef SSFX_PUDDLES
Texture2D s_puddles_normal;
Texture2D s_puddles_mask;
Texture2D s_rainsplash;
#endif
// Height Textures
Texture2D s_height_r;
Texture2D s_height_g;
Texture2D s_height_b;
Texture2D s_height_a;
uniform float4 ssfx_terrain_pom; // Samples, Range, Height, Water Limit
uniform float4 ssfx_terrain_offset;
struct surface
{
float4 base;
float4 normal;
float gloss;
float mask;
float height;
float AO;
float2 tc;
};
surface Terrain_InitSurfaces(Texture2D height_tex, float2 tc, float mask, int idx)
{
surface S;
S.base = 0;
S.gloss = 0;
S.normal = 0;
#ifdef TERRAIN_GTR_COMPATIBILITY
S.height = saturate(height_tex.Sample(smp_base, tc).a + ssfx_terrain_offset[idx]);
#else
S.height = saturate(height_tex.Sample(smp_base, tc).r + ssfx_terrain_offset[idx]);
#endif
S.AO = TERRAIN_POM_AO - S.height * S.height * TERRAIN_POM_AO; // Use the height as AO
S.mask = mask;
S.tc = tc;
return S;
}
// For future improvements...
void HeightBlending(float4 heights, inout float4 weights)
{
// Texture height + splatting weight
float4 H = heights + weights;
float H_weights = max(max(H.x, H.y), max(H.z, H.w)) - 1.01f;
// Cut
heights = max(heights - H_weights, 0.0f) * weights;
// Normalize
weights.rgba = heights / dot(heights, 1.0f);
}
void ApplyWeights(inout surface Sr, inout surface Sg, inout surface Sb, inout surface Sa, float4 weights)
{
// Just apply the texture splatting
Sr.base.rgb *= weights.x;
Sr.normal *= weights.x;
Sr.gloss *= weights.x;
Sg.base.rgb *= weights.y;
Sg.normal *= weights.y;
Sg.gloss *= weights.y;
Sb.base.rgb *= weights.z;
Sb.normal *= weights.z;
Sb.gloss *= weights.z;
Sa.base.rgb *= weights.a;
Sa.normal *= weights.a;
Sa.gloss *= weights.a;
}
void TerrainParallax(float2 tc_step, float _step, inout surface S, inout p_bumped p, Texture2D height_tex, int idx)
{
if (S.mask <= 0)
return;
if (p.position.z >= ssfx_terrain_pom.y)
return;
// Init vars to store steps
float curr_step = 0;
float2 parallax_tc = p.tcdbump;
// Store the previous & current sample to do the POM calc and Contact Refinement if needed.
float prev_Height = 0;
float curr_Height = TERRAIN_POM_PLANE - S.height * S.mask; // Apply the splatting weight and limit
float prev_Sam = 0;
float curr_Sam = S.height;
do // Basic Step Parallax
{
// Save previous data
prev_Height = curr_Height;
prev_Sam = curr_Sam;
// Step TexCoor
parallax_tc -= tc_step;
curr_step += _step;
// Sample
#ifdef TERRAIN_GTR_COMPATIBILITY
curr_Sam = saturate(height_tex.SampleLevel(smp_base, parallax_tc, 0).a + ssfx_terrain_offset[idx]);
#else
curr_Sam = saturate(height_tex.SampleLevel(smp_base, parallax_tc, 0).r + ssfx_terrain_offset[idx]);
#endif
curr_Height = TERRAIN_POM_PLANE - curr_Sam * S.mask; // Apply the splatting weight and limit
} while(curr_Height > curr_step);
#ifdef SSFX_TERRA_POM_REFINE
// Step back
parallax_tc += tc_step;
curr_step -= _step;
// Previous height ( Step back )
curr_Height = prev_Height;
// Increase precision ( 3 times seems like a good balance )
_step /= 3;
tc_step /= 3;
do // Step
{
// Save previous data ( Used for interpolation )
prev_Height = curr_Height;
prev_Sam = curr_Sam;
// Step TexCoor
parallax_tc -= tc_step;
curr_step += _step;
// Sample
#ifdef TERRAIN_GTR_COMPATIBILITY
curr_Sam = saturate(height_tex.SampleLevel(smp_base, parallax_tc, 0).a + ssfx_terrain_offset[idx]);
#else
curr_Sam = saturate(height_tex.SampleLevel(smp_base, parallax_tc, 0).r + ssfx_terrain_offset[idx]);
#endif
curr_Height = TERRAIN_POM_PLANE - curr_Sam * S.mask; // Apply the splatting weight and limit
} while(curr_Height >= curr_step);
#endif
// [ POM ] Interpolation between the previous offset and the current offset
float currentDiff = curr_Height - curr_step;
float ratio = currentDiff / (currentDiff - saturate(prev_Height - curr_step + _step));
// Final TexCoor
S.tc = lerp(parallax_tc, parallax_tc + tc_step, ratio);
// Get height
S.height = lerp(curr_Sam, prev_Sam, ratio);
}
void TerrainTextures(inout surface S, Texture2D s_base_det, Texture2D s_bump_det, float2 offset)
{
if (S.mask <= 0)
return;
S.base = s_base_det.Sample(smp_base, S.tc + offset);
S.normal = s_bump_det.Sample(smp_base, S.tc + offset);
S.gloss = S.normal.x;
S.normal.rgb = S.normal.wzy * 2.0f - 1.0f;//- 0.5;
// Apply ambient occlusion
S.base.rgb *= (1.0 - S.AO);
}
f_deffer main(p_bumped I)
{
// General --------------------------------------------------------
// Normal & Eye Vector
float3 Nw = normalize(float3(I.M1.z, I.M2.z, I.M3.z));
float3 eyeVec = normalize(I.position.xyz);
// Refraction UV
float2 N_refra = 0;
// Color
float4 C = s_base.Sample(smp_base, I.tcdh.xy);
// Splatting Mask
float4 mask = s_mask.Sample(smp_base, I.tcdh.xy);
mask /= dot(mask, 1.0);
// Init Surfaces --------------------------------------------------
#ifdef TERRAIN_GTR_COMPATIBILITY
surface Sr = Terrain_InitSurfaces(s_dt_r, I.tcdbump.xy, mask.x, 0);
surface Sg = Terrain_InitSurfaces(s_dt_g, I.tcdbump.xy, mask.y, 1);
surface Sb = Terrain_InitSurfaces(s_dt_b, I.tcdbump.xy, mask.z, 2);
surface Sa = Terrain_InitSurfaces(s_dt_a, I.tcdbump.xy, mask.w, 3);
#else
surface Sr = Terrain_InitSurfaces(s_height_r, I.tcdbump.xy, mask.x, 0);
surface Sg = Terrain_InitSurfaces(s_height_g, I.tcdbump.xy, mask.y, 1);
surface Sb = Terrain_InitSurfaces(s_height_b, I.tcdbump.xy, mask.z, 2);
surface Sa = Terrain_InitSurfaces(s_height_a, I.tcdbump.xy, mask.w, 3);
#endif
// Texture splatting ( TODO: Improve Texture Splatting )
//HeightBlending(float4(Sr.height, Sg.height, Sb.height, Sa.height), mask);
// Parallax -------------------------------------------------------
// Distance attenuation
float dist_att = 1.0 - smoothstep(TERRAIN_POM_RANGE * 0.8f, TERRAIN_POM_RANGE, I.position.z);
float3 eye = normalize(mul(float3x3(I.M1.x, I.M2.x, I.M3.x,
I.M1.y, I.M2.y, I.M3.y,
I.M1.z, I.M2.z, I.M3.z), -I.position));
float view_angle = abs(dot(float3(0.0, 0.0, 1.0), eye));
// Dynamic steps
float _step = rcp(lerp(ssfx_terrain_pom.x, TERRAIN_POM_STEPS_MIN, view_angle)); // 1.0 / Step Qty
_step *= TERRAIN_POM_PLANE; // We are working with 0.0 ~ 0.5
// View direction + bias to try to minimize issues with some slopes.
float2 viewdir = eye.xy / (abs(eye.z) + 0.41f);
// Offset direction
float2 tc_step = _step * viewdir * ssfx_terrain_pom.z * dist_att;
// Do Parallax
#ifdef TERRAIN_GTR_COMPATIBILITY
TerrainParallax(tc_step, _step, Sr, I, s_dt_r, 0);
TerrainParallax(tc_step, _step, Sg, I, s_dt_g, 1);
TerrainParallax(tc_step, _step, Sb, I, s_dt_b, 2);
TerrainParallax(tc_step, _step, Sa, I, s_dt_a, 3);
#else
TerrainParallax(tc_step, _step, Sr, I, s_height_r, 0);
TerrainParallax(tc_step, _step, Sg, I, s_height_g, 1);
TerrainParallax(tc_step, _step, Sb, I, s_height_b, 2);
TerrainParallax(tc_step, _step, Sa, I, s_height_a, 3);
#endif
// Calculate height using splatting mask
float PixelHeight = dot(float4(Sr.height, Sg.height, Sb.height, Sa.height), mask);
// Puddles slope mask and height ----------------------------------
#ifdef SSFX_PUDDLES
// Wetness factor
float wetness_f = saturate(rain_params.y) * ssfx_terrain_pom.w;
// Always render puddles if G_PUDDLES_ALLWAYS is defined
#ifdef G_PUDDLES_ALLWAYS
wetness_f = 1.0f;
#endif
float height_str = saturate(wetness_f * TERRAIN_POM_PLANE - PixelHeight);
float puddles = saturate(height_str * 4.0f);
// Texture mask
float PuddlesMask = 1.0f - s_puddles_mask.Sample(smp_base, I.tcdh).r;
// Transform space to create a slope mask
float3 N = mul(m_inv_V, Nw);
// Slope mask
float SlopeMask = 1.0f - max(abs(N.x), abs(N.z));
// Slope adjustements... Some magic numbers
SlopeMask = saturate(SlopeMask - 0.9f) * 13.0f;
// Slope & texture mask defines final puddles intensity
puddles *= SlopeMask * PuddlesMask;
// Puddles Ripples ------------------------------------------------
#ifdef G_PUDDLES_RIPPLES
float rain_int = saturate(rain_params.x * 1.5f);
// Base ripples anim speed
float ripples_anim = timers.x * ((0.01f + (rain_int * 0.008f)) * G_PUDDLES_RIPPLES_SPEED );
// Base ripples scale
float ripples_scale = 140 / G_PUDDLES_RIPPLES_SCALE;
// Base ripples Normal
float3 WN0 = s_puddles_normal.Sample(smp_base, I.tcdh * ripples_scale + float2(0, ripples_anim));
float3 WN1 = s_puddles_normal.Sample(smp_base, I.tcdh * ripples_scale - float2(0.33f, ripples_anim));
float3 ripplesNormal = normalize(float3(WN0.xy + WN1.xy, WN0.z * WN1.z)) * 2.0f - 1.0f;//((WN0 + WN1) * 0.5f) * 2.0f - 1.0f;
// Rain Ripples
float2 ripplesUV = I.tcdh * ripples_scale * 1.3f / G_PUDDLES_RAIN_RIPPLES_SCALE;
float2 rainRipples = ssfx_rain_ripples( s_rainsplash, ripplesUV, float3(0.85f, 1.0f, 10.0f), I.position.z);
// Rain ripples intensity... ( Rain intensity * Depth fadeout * Intensity )
rainRipples *= rain_params.x * G_PUDDLES_RAIN_RIPPLES_INTENSITY;
// Base ripples Intensity
ripplesNormal *= saturate(0.05f + rain_int * G_PUDDLES_RIPPLES_RAINING_INT * G_PUDDLES_RIPPLES_INTENSITY);
// Mix ripples
ripplesNormal = ripplesNormal * 0.666f + float3(rainRipples * 0.333f, 0);
#else
float3 ripplesNormal = 0;
#endif
// Refraction Normal
N_refra = ripplesNormal.xy;
// Adjust refraction intensity based on wetness and puddle height
N_refra *= 0.15f * smoothstep( 0.6f, 0.8f, puddles ) * G_PUDDLES_REFRACTION_INTENSITY;
#endif
// Textures -------------------------------------------------------
// Sample color and bump textures with new parallax TexCoors and refraction displacement
TerrainTextures(Sr, s_dt_r, s_dn_r, N_refra);
TerrainTextures(Sg, s_dt_g, s_dn_g, N_refra);
TerrainTextures(Sb, s_dt_b, s_dn_b, N_refra);
TerrainTextures(Sa, s_dt_a, s_dn_a, N_refra);
// Apply splatting mask to everything ( Color, Normal and Gloss )
ApplyWeights(Sr, Sg, Sb, Sa, mask);
// Mix everything ------------------------------------------------
// Normal
float3 Ne = normalize(mul(float3x3(I.M1, I.M2, I.M3), Sr.normal.rgb + Sg.normal.rgb + Sb.normal.rgb + Sa.normal.rgb ));
// Color
C.rgb = (Sr.base.rgb + Sg.base.rgb + Sb.base.rgb + Sa.base.rgb ) * C.rgb * 2.0;
// Gloss
float G = Sr.gloss + Sg.gloss + Sb.gloss + Sa.gloss;
#ifdef SSFX_PUDDLES // Puddles Mix
// Normal Up and ripples for puddles
float3 PuddlesNormal = mul(m_V, float3(ripplesNormal.x, 1, ripplesNormal.y));
// Puddles Normal
Ne = lerp(Ne, PuddlesNormal, saturate(puddles * puddles * 2) );
// Puddles Color
C.rgb = lerp( C.rgb, C.rgb * G_PUDDLES_TINT, puddles);
// Puddles Gloss
G = max(G, puddles * 0.4f);
#endif
// Depth Offset ---------------------------------------------------
float d1 = dot(Nw, Nw * (1.0 - PixelHeight * 1.5) * -0.11f); // Exaggerate shadows? ( 1.5f )
float d2 = dot(eyeVec, Nw);
float3 offset_pos = I.position.xyz + eyeVec * (d1 / min(d2, -0.3f)); // Limit `d2` to -0.3 to avoid problems with some slopes
// Send Pack ------------------------------------------------------
return pack_gbuffer( float4( Ne, C.w ), // normal.hemi
float4( offset_pos, 0.95f ),
float4( C.rgb, G )
);
}
@@ -0,0 +1,28 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 20
* @ Description: Terrain Shader - LOW
* @ Modified time: 2024-02-27 23:30
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
f_deffer main ( p_flat I )
{
f_deffer O;
// diffuse
float4 D = s_base.Sample( smp_base, I.tcdh);
float G = 0.001f;
float3 N = I.N.xyz;
// 2. Standart output
float4 Ne = float4 (normalize(N), D.w);
O = pack_gbuffer(
Ne, // hemi
float4 (I.position.xyz + Ne.xyz*def_virtualh / 2.h, 0.95f),
float4 (D.rgb, G)); // OUT: rgb.gloss
return O;
}
@@ -0,0 +1,61 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 20
* @ Description: Terrain Shader - MID
* @ Modified time: 2024-02-27 23:31
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
Texture2D s_lod_texture;
static float2 terrain_lod_offset[4] = {
float2(0.15f, 0.15f),
float2(0.65f, 0.15f),
float2(0.15f, 0.65f),
float2(0.65f, 0.65f)
};
f_deffer main( p_flat I )
{
f_deffer O;
// diffuse
float4 D = s_base.Sample( smp_base, I.tcdh);
float3 N = I.N.xyz;
float4 mask= s_mask.Sample( smp_base, I.tcdh );
float mag = dot( mask, 1 );
mask= mask / mag;
float2 lod_uv = 0, p_lod_uv = 0;
float factor = 0.0f;
float2 tc = (frac( I.tcdh * 100 ) * 0.35f);
for (int a = 0; a <= 3; a++)
{
if (mask[a] > factor)
{
p_lod_uv = lod_uv;
lod_uv = terrain_lod_offset[a] + tc;
factor = mask[a];
}
}
// Texture - TODO: Use partial derivative?
float3 lod_texture = s_lod_texture.Sample(smp_base, lod_uv).rgb * factor;
lod_texture += s_lod_texture.Sample(smp_linear, p_lod_uv).rgb * (1.0 - factor);
D.rgb = lerp( 2 * D.rgb * lod_texture, D.rgb, saturate(-2.4f + length(I.position) * 0.013f));
float4 Ne = float4(normalize(N), D.w);
// Standart output
O = pack_gbuffer( Ne,
float4( I.position.xyz + Ne.xyz * def_virtualh / 2.h, 0.95f ), // Pos & MatID
float4( D.rgb, 0.001f)); // RGB & Gloss
return O;
}
@@ -0,0 +1,139 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 19
* @ Description: Trees - Branches/Bushes
* @ Modified time: 2023-12-16 13:53
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
#include "check_screenspace.h"
float4 benders_pos[32];
float4 benders_setup;
uniform float3x4 m_xform ;
uniform float3x4 m_xform_v ;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
#ifdef SSFX_WIND
#include "screenspace_wind.h"
#endif
v2p_bumped main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
// Transform to world coords
float3 pos = mul(m_xform, I.P);
float H = pos.y - m_xform._24; // height of vertex
float2 tc = (I.tc * consts).xy;
#ifndef SSFX_WIND
float base = m_xform._24 ; // take base height from matrix
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 result = calc_xz_wave (wind.xz*inten*2.0f, frac);
float3 wind_result = float3(result.x, 0, result.y);
#else
float3 wind_result = ssfx_wind_tree_branches(pos, H, tc.y, ssfx_wind_setup());
#endif
#ifdef USE_TREEWAVE
wind_result = 0;
#endif
float4 w_pos = float4(pos.xyz + wind_result.xyz, 1);
// INTERACTIVE GRASS ( Bushes ) - SSS Update 15.4
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
#if SSFX_INT_GRASS > 0
for (int b = 0; b < SSFX_INT_GRASS + 1; b++)
{
// Direction, Radius & Bending Strength, Distance and Height Limit
float3 dir = benders_pos[b + 16].xyz;
float3 rstr = float3(benders_pos[b].w, benders_pos[b + 16].ww); // .x = Radius | .yz = Str
bool non_dynamic = rstr.x <= 0 ? true : false;
float dist = distance(w_pos.xz, benders_pos[b].xz);
float height_limit = 1.0f - saturate(abs(pos.y - benders_pos[b].y) / ( non_dynamic ? 2.0f : rstr.x ));
height_limit *= (1.0f - tc.y); // Bushes uses UV Coor instead of H to limit displacement
// Adjustments ( Fix Radius or Dynamic Radius )
rstr.x = non_dynamic ? benders_setup.x : rstr.x;
rstr.yz *= non_dynamic ? benders_setup.yz : 1.0f;
// Strength through distance and bending direction.
float bend = 1.0f - saturate(dist / (rstr.x + 0.001f));
float3 bend_dir = normalize(w_pos.xyz - benders_pos[b].xyz) * bend;
float3 dir_limit = dir.y >= -1 ? saturate(dot(bend_dir.xyz, dir.xyz) * 5.0f) : 1.0f; // Limit if nedeed
// Apply direction limit
bend_dir.xz *= dir_limit.xz;
// Apply vertex displacement
w_pos.xz += bend_dir.xz * 2.25f * rstr.yy * height_limit; // Horizontal
w_pos.y -= bend * 0.67f * rstr.z * height_limit * dir_limit.y; // Vertical
}
#endif
float hemi = clamp(I.Nh.w * c_scale.w + c_bias.w, 0.3f, 1.0f); // Limit hemi - SSS Update 14.5
// float hemi = I.Nh.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_V, w_pos );
O.tcdh = float4 (tc.xyyy );
O.hpos = mul (m_VP, w_pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
O.tcdh.w = suno; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
//Normal mapping
// FLORA FIXES & IMPROVEMENTS - SSS Update 14
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Use real tree Normal, Tangent and Binormal.
float3 N = unpack_bx4(I.Nh);
float3 T = unpack_bx4(I.T);
float3 B = unpack_bx4(I.B);
float3x3 xform = mul ((float3x3)m_xform_v, float3x3(
T.x,B.x,N.x,
T.y,B.y,N.y,
T.z,B.z,N.z
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
return O;
}
FXVS;
@@ -0,0 +1,3 @@
#define USE_TDETAIL
#define USE_PARALLAX
#include "deffer_tree_bump.vs"
@@ -0,0 +1,88 @@
#include "common.h"
float4 benders_pos[32];
float4 benders_setup;
uniform float3x4 m_xform;
uniform float3x4 m_xform_v;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
v2p_flat main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
v2p_flat o;
// Transform to world coords
float3 pos = mul (m_xform, I.P);
//
float base = m_xform._24; // take base height from matrix
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float H = pos.y - base; // height of vertex (scaled, rotated, etc.)
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 result = calc_xz_wave (wind.xz*inten, frac);
#ifdef USE_TREEWAVE
result = 0;
#endif
float4 f_pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
float2 tc = (I.tc * consts).xy;
// INTERACTIVE GRASS ( Bushes ) - SSS Update 17.1
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
#if SSFX_INT_GRASS > 0
for (int b = 0; b < SSFX_INT_GRASS + 1; b++)
{
// Direction, Radius & Bending Strength, Distance and Height Limit
float3 dir = benders_pos[b + 16].xyz;
float3 rstr = float3(benders_pos[b].w, benders_pos[b + 16].ww); // .x = Radius | .yz = Str
bool non_dynamic = rstr.x <= 0 ? true : false;
float dist = distance(f_pos.xz, benders_pos[b].xz);
float height_limit = 1.0f - saturate(abs(pos.y - benders_pos[b].y) / ( non_dynamic ? 2.0f : rstr.x ));
height_limit *= (1.0f - tc.y); // Bushes uses UV Coor instead of H to limit displacement
// Adjustments ( Fix Radius or Dynamic Radius )
rstr.x = non_dynamic ? benders_setup.x : rstr.x;
rstr.yz *= non_dynamic ? benders_setup.yz : 1.0f;
// Strength through distance and bending direction.
float bend = 1.0f - saturate(dist / (rstr.x + 0.001f));
float3 bend_dir = normalize(f_pos.xyz - benders_pos[b].xyz) * bend;
float3 dir_limit = dir.y >= -1 ? saturate(dot(bend_dir.xyz, dir.xyz) * 5.0f) : 1.0f; // Limit if nedeed
// Apply direction limit
bend_dir.xz *= dir_limit.xz;
// Apply vertex displacement
f_pos.xz += bend_dir.xz * 2.25f * rstr.yy * height_limit; // Horizontal
f_pos.y -= bend * 0.67f * rstr.z * height_limit * dir_limit.y; // Vertical
}
#endif
// Final xform(s)
// Final xform
float3 Pe = mul (m_V, f_pos );
float hemi = I.Nh.w*c_scale.w + c_bias.w;
//float hemi = I.Nh.w;
o.hpos = mul (m_VP, f_pos );
o.N = normalize(mul((float3x3)m_xform_v, I.P.xyz));
o.tcdh = float4 (tc.xyyy );
o.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
o.tcdh.w = suno; // (,,,dir-occlusion)
#endif
#ifdef USE_TDETAIL
o.tcdbump = o.tcdh*dt_params; // dt tc
#endif
return o;
}
FXVS;
@@ -0,0 +1,98 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 19
* @ Description: Trees - Trunk
* @ Modified time: 2023-12-16 13:58
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
#include "check_screenspace.h"
uniform float3x4 m_xform ;
uniform float3x4 m_xform_v ;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
#ifdef SSFX_WIND
#include "screenspace_wind.h"
#endif
v2p_bumped main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
// Transform to world coords
float3 pos = mul(m_xform, I.P);
float H = pos.y - m_xform._24; // height of vertex
#ifndef SSFX_WIND
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 wind_result = calc_xz_wave (wind.xz*inten, frac);
#else
float2 wind_result = ssfx_wind_tree_trunk(pos, H, ssfx_wind_setup()).xy;
#endif
#ifdef USE_TREEWAVE
wind_result = 0;
#endif
float4 w_pos = float4(pos.x + wind_result.x, pos.y, pos.z + wind_result.y, 1);
float2 tc = (I.tc * consts).xy;
float hemi = clamp(I.Nh.w * c_scale.w + c_bias.w, 0.3f, 1.0f); // Limit hemi - SSS Update 14.5
// float hemi = I.Nh.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_V, w_pos );
O.tcdh = float4 (tc.xyyy );
O.hpos = mul (m_VP, w_pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
O.tcdh.w = suno; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
//Normal mapping
// FLORA FIXES & IMPROVEMENTS - SSS Update 14
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Use real tree Normal, Tangent and Binormal.
float3 N = unpack_bx4(I.Nh);
float3 T = unpack_bx4(I.T);
float3 B = unpack_bx4(I.B);
float3x3 xform = mul ((float3x3)m_xform_v, float3x3(
T.x,B.x,N.x,
T.y,B.y,N.y,
T.z,B.z,N.z
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
return O;
}
FXVS;
@@ -0,0 +1,94 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 19
* @ Description: Trees - Trunk ( Burn Sections )
* @ Modified time: 2023-12-16 13:42
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
#include "check_screenspace.h"
uniform float3x4 m_xform ;
uniform float3x4 m_xform_v ;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
#ifdef SSFX_WIND
#include "screenspace_wind.h"
#endif
v2p_bumped main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
// Transform to world coords
float3 pos = mul(m_xform, I.P);
float H = pos.y - m_xform._24; // height of vertex
#ifndef SSFX_WIND
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 wind_result = calc_xz_wave (wind.xz*inten, frac);
#else
float2 wind_result = ssfx_wind_tree_trunk(pos, H, ssfx_wind_setup()).xy;
#endif
#ifdef USE_TREEWAVE
wind_result = 0;
#endif
float4 w_pos = float4(pos.x + wind_result.x, pos.y, pos.z + wind_result.y, 1);
float2 tc = (I.tc * consts).xy;
float hemi = I.Nh.w * c_scale.w + c_bias.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_V, w_pos );
O.tcdh = float4 (tc.xyyy );
O.hpos = mul (m_VP, w_pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
O.tcdh.w = suno; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
//Normal mapping
float3 N = unpack_bx4(I.Nh);
float3 T = unpack_bx4(I.T);
float3 B = unpack_bx4(I.B);
float3x3 xform = mul ((float3x3)m_xform_v, float3x3(
T.x,B.x,N.x,
T.y,B.y,N.y,
T.z,B.z,N.z
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
return O;
}
FXVS;
@@ -0,0 +1,11 @@
#include "common.h"
#include "screenspace_common.h"
#include "screenspace_dof.h"
float4 main(p_screen I) : SV_TARGET
{
float3 P = SSFX_get_position(I.tc0, 0);
float3 img = s_image.Sample(smp_nofilter, I.tc0).rgb;
return float4(SSFX_DOF( I.tc0, P, img ), 1.0);
}
@@ -0,0 +1,22 @@
--Normal pass, with bumpmapping
function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_grass","deffer_grass")
: fog (false)
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
shader:dx10cullmode (1)
local opt = shader:dx10Options()
shader:dx10texture("s_base", t_base)
shader:dx10texture("s_bump", "levels\\" .. opt:getLevel() .. "\\" .. t_base.."_bump")
shader:dx10texture("s_bumpX", t_base.."_bump#")
shader:dx10texture("s_waves", "fx\\wind_wave")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_linear")
shader:dx10sampler("smp_linear2")
end
@@ -0,0 +1,74 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17.1
* @ Description: Rain Shader - PS
* @ Modified time: 2024-11-23 21:21
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "screenspace_common.h"
#ifdef SSFX_BEEFS_NVG
uniform float4 shader_param_8;
uniform float4 ssfx_issvp;
#endif
Texture2D ssfx_color_buffer;
// Pixel Struct
struct p_Rain
{
float2 Tex0 : TEXCOORD0;
float4 tc : TEXCOORD1;
};
float4 ssfx_rain_setup; // Alpha, Brigthness, Refraction, Reflection
float4 main ( p_Rain I ) : SV_Target
{
// Factor to adjust the effect depending on light conditions
float HemiFactor = saturate(dot(L_hemi_color.rgb, float3(1.0f, 1.0f, 1.0f)));
// Screen Space
float2 PosTc = I.tc.xy / I.tc.w;
// Normal Setup
float4 N0 = s_base.Sample( smp_rtlinear, I.Tex0);
N0.xy = N0.xy * 2.0f - 1.0f; // Convert to -1.0f ~ 1.0f
// Adjust "refraction" offset
float4 UV_Offset = float4(N0.xy * 0.0125f, N0.xy);
UV_Offset.xy = normalize(float3(UV_Offset.xy * ssfx_rain_setup.z, 1.0f));
UV_Offset.zw = normalize(float3(UV_Offset.zw * (0.2f + HemiFactor * 0.5f), 1.0f));
#if SSFX_RAIN_QUALITY > 0
// Remove incorrect refraction
float Depth = SSFX_get_depth(saturate(PosTc + UV_Offset.xy), 0);
UV_Offset.xy *= (I.tc.w < Depth || Depth <= SKY_EPS);
#endif
// Screen Buffer ( Blur )
float3 Screen = ssfx_color_buffer.Sample(smp_rtlinear, saturate(PosTc + UV_Offset.xy)).rgb;
#if SSFX_RAIN_QUALITY > 1
// Fake reflection using light accumulator with a high UV offset
#ifndef USE_MSAA
float3 rL = s_accumulator.Sample(smp_nofilter, saturate(PosTc + UV_Offset.zw)).rgb;
#else
float3 rL = s_accumulator.Load(int3(saturate(PosTc + UV_Offset.zw) * screen_res.xy, 0), 0).rgb;
#endif
// Add fake reflection
Screen = blend_soft( Screen, rL * ssfx_rain_setup.w);
#endif
// Add Brightness
Screen += L_hemi_color.rgb * ssfx_rain_setup.y;
#ifdef SSFX_BEEFS_NVG
N0.w *= shader_param_8.x > 0 ? 0.5f : 1.0f;
#endif
// Result
return float4( saturate(Screen), N0.w * ssfx_rain_setup.x );
}
@@ -0,0 +1,19 @@
-- @ Version: SCREEN SPACE SHADERS - UPDATE 17
-- @ Description: Rain - Shader Config
-- @ Author: https://www.moddb.com/members/ascii1457
-- @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
function normal(shader, t_base, t_second, t_detail)
shader : begin ("effects_rain","effects_rain")
: zb (true,false)
: blend (true,blend.srcalpha,blend.invsrcalpha)
: aref (true,0)
shader : dx10texture("s_base", "fx\\rain_drop")
shader : dx10texture("s_position", "$user$position")
shader : dx10texture("s_accumulator", "$user$accum")
shader : dx10texture("ssfx_color_buffer", "$user$ssfx_rain")
shader : dx10sampler ("smp_rtlinear")
shader : dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,34 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17
* @ Description: Rain Shader - VS
* @ Modified time: 2023-06-22 20:16
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
// Vertex Struct
struct v2p_Rain
{
float2 Tex0 : TEXCOORD0;
float4 tc : TEXCOORD1;
float4 HPos : SV_Position;
};
uniform float4x4 mVPTexgen;
v2p_Rain main ( v_TL I)
{
v2p_Rain O;
// Basic Stuff
O.HPos = mul( m_WVP, I.P);
O.Tex0 = I.Tex0;
// Screen Space Data
O.tc = mul( mVPTexgen, I.P);
O.tc.z = O.HPos.z;
return O;
}
@@ -0,0 +1,38 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17
* @ Description: Rain Shader - VS
* @ Modified time: 2024-11-19 00:07
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "screenspace_common.h"
Texture2D ssfx_color_buffer;
// Pixel Struct
struct p_Rain
{
float2 Tex0 : TEXCOORD0;
float4 tc : TEXCOORD1;
};
float4 ssfx_rain_setup;
float4 main ( p_Rain I ) : SV_Target
{
// Screen Space
float2 PosTc = I.tc.xy / I.tc.w;
// Normal Setup
float4 N0 = s_base.Sample( smp_base, I.Tex0 );
N0.xy = N0.xy * 2.0f - 1.0f; // Convert to -1.0f ~ 1.0f
// Adjust "refraction" Intensity
N0.xy = normalize(float3(N0.xy * 0.05f * ssfx_rain_setup.y, 1.0f));
// Screen Buffer
float3 Screen = ssfx_color_buffer.Sample(smp_rtlinear, saturate(PosTc + N0.xy)).rgb;
return float4( Screen, N0.w * ssfx_rain_setup.x );
}
@@ -0,0 +1,19 @@
-- @ Version: SCREEN SPACE SHADERS - UPDATE 17
-- @ Description: Rain - Shader Config
-- @ Author: https://www.moddb.com/members/ascii1457
-- @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
function normal(shader, t_base, t_second, t_detail)
shader : begin ("effects_rain","effects_rain_splash")
: zb (true,false)
: blend (true,blend.srcalpha,blend.invsrcalpha)
: aref (true,0)
shader : dx10texture("s_base", "fx\\rain_splash")
shader : dx10texture("ssfx_color_buffer", "$user$ssfx_rain")
shader : dx10sampler ("smp_base")
shader : dx10sampler ("smp_rtlinear")
shader : dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,27 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17
* @ Description: Blood Decal - Pixel Shader
* @ Modified time: 2023-07-06 12:28
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
uniform float4 ssfx_blood_decals;
float4 main ( p_TL I ) : SV_Target
{
float4 res = s_base.Sample( smp_base, I.Tex0 );
// Color intensity
res.rgb *= ssfx_blood_decals.x;
// Alpha adjustments
res.a = saturate(res.a * 1.7f - 0.7f) * ssfx_blood_decals.y;
// Lifespan fade-out
res.a *= 1.0 - I.Color.a;
return float4(res.rgb, res.a);
}
@@ -0,0 +1,20 @@
-- @ Version: SCREEN SPACE SHADERS - UPDATE 17
-- @ Description: Blood Decal - Shader Config
-- @ Author: https://www.moddb.com/members/ascii1457
-- @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
function normal(shader, t_base, t_second, t_detail)
shader : begin("effects_wallmark_blood", "effects_wallmark_blood")
: sorting(3, false)
: blend(true, blend.srcalpha, blend.invsrcalpha)
: zb(true, false)
: fog(false)
: wmark(true)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_rtlinear")
end
@@ -0,0 +1,20 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17
* @ Description: Decals - VS
* @ Modified time: 2023-07-05 05:58
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
v2p_TL main(v_TL I)
{
v2p_TL O;
O.HPos = mul(m_VP, I.P);
O.Tex0 = I.Tex0;
O.Color = I.Color.bgra;
return O;
}
@@ -0,0 +1,55 @@
local tex_base = "water\\water_water"
local tex_nmap = "fx\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_sky0 = "$user$sky0" -- "sky\\sky_8_cube"
local tex_sky1 = "$user$sky1" -- "sky\\sky_8_cube"
local tex_bluenoise = "fx\\blue_noise"
local tex_rainsplash = "fx\\water_sbumpvolume"
local tex_caustics = "fx\\water_caustics"
function normal (shader, t_base, t_second, t_detail)
shader :begin ("water_regular","water_regular")
:sorting (2, false)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:distort (true)
:fog (true)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_nmap", tex_nmap)
shader:dx10texture ("sky_s0", tex_sky0)
shader:dx10texture ("sky_s1", tex_sky1)
shader:dx10texture ("s_position", "$user$position")
shader:dx10texture ("s_rimage", "$user$generic_temp")
shader:dx10texture ("s_diffuse", "$user$albedo")
shader:dx10texture ("s_accumulator", "$user$accum")
shader:dx10texture ("s_bluenoise", tex_bluenoise)
shader:dx10texture ("s_rainsplash", tex_rainsplash)
shader:dx10texture ("s_watercaustics", tex_caustics)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_linear")
shader:dx10sampler ("smp_nofilter")
shader:dx10sampler ("smp_rtlinear")
end
function l_special (shader, t_base, t_second, t_detail)
shader :begin ("waterd","waterd")
:sorting (2, true)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:fog (false)
:distort (true)
shader: dx10color_write_enable( true, true, true, false)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_distort", tex_dist)
shader:dx10texture ("s_position", "$user$position")
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,54 @@
local tex_base = "water\\water_ryaska1"
local tex_nmap = "fx\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_sky0 = "$user$sky0" -- "sky\\sky_8_cube"
local tex_sky1 = "$user$sky1" -- "sky\\sky_8_cube"
local tex_bluenoise = "fx\\blue_noise"
local tex_rainsplash = "fx\\water_sbumpvolume"
local tex_caustics = "fx\\water_caustics"
function normal (shader, t_base, t_second, t_detail)
shader :begin ("water_ryaska","water_ryaska")
:sorting (2, false)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:distort (true)
:fog (true)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_nmap", tex_nmap)
shader:dx10texture ("sky_s0", tex_sky0)
shader:dx10texture ("sky_s1", tex_sky1)
shader:dx10texture ("s_position", "$user$position")
shader:dx10texture ("s_rimage", "$user$generic_temp")
shader:dx10texture ("s_diffuse", "$user$albedo")
shader:dx10texture ("s_accumulator", "$user$accum")
shader:dx10texture ("s_bluenoise", tex_bluenoise)
shader:dx10texture ("s_rainsplash", tex_rainsplash)
shader:dx10texture ("s_watercaustics", tex_caustics)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_linear")
shader:dx10sampler ("smp_nofilter")
shader:dx10sampler ("smp_rtlinear")
end
function l_special (shader, t_base, t_second, t_detail)
shader :begin ("waterd","waterd")
:sorting (2, true)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:fog (false)
:distort (true)
shader: dx10color_write_enable( true, true, true, false)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_distort", tex_dist)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,54 @@
local tex_base = "water\\water_studen"
local tex_nmap = "fx\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_sky0 = "$user$sky0" -- "sky\\sky_8_cube"
local tex_sky1 = "$user$sky1" -- "sky\\sky_8_cube"
local tex_bluenoise = "fx\\blue_noise"
local tex_rainsplash = "fx\\water_sbumpvolume"
local tex_caustics = "fx\\water_caustics"
function normal (shader, t_base, t_second, t_detail)
shader :begin ("water_studen","water_studen")
:sorting (2, false)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:distort (true)
:fog (true)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_nmap", tex_nmap)
shader:dx10texture ("sky_s0", tex_sky0)
shader:dx10texture ("sky_s1", tex_sky1)
shader:dx10texture ("s_position", "$user$position")
shader:dx10texture ("s_rimage", "$user$generic_temp")
shader:dx10texture ("s_diffuse", "$user$albedo")
shader:dx10texture ("s_accumulator", "$user$accum")
shader:dx10texture ("s_bluenoise", tex_bluenoise)
shader:dx10texture ("s_rainsplash", tex_rainsplash)
shader:dx10texture ("s_watercaustics", tex_caustics)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_linear")
shader:dx10sampler ("smp_nofilter")
shader:dx10sampler ("smp_rtlinear")
end
function l_special (shader, t_base, t_second, t_detail)
shader :begin ("waterd","waterd")
:sorting (2, true)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:fog (false)
:distort (true)
shader: dx10color_write_enable( true, true, true, false)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_distort", tex_dist)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,54 @@
local tex_base = "water\\water_ryaska1"
local tex_nmap = "fx\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_sky0 = "$user$sky0" -- "sky\\sky_8_cube"
local tex_sky1 = "$user$sky1" -- "sky\\sky_8_cube"
local tex_bluenoise = "fx\\blue_noise"
local tex_rainsplash = "fx\\water_sbumpvolume"
local tex_caustics = "fx\\water_caustics"
function normal (shader, t_base, t_second, t_detail)
shader :begin ("water_underground","water_underground")
:sorting (2, false)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:distort (true)
:fog (true)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_nmap", tex_nmap)
shader:dx10texture ("sky_s0", tex_sky0)
shader:dx10texture ("sky_s1", tex_sky1)
shader:dx10texture ("s_position", "$user$position")
shader:dx10texture ("s_rimage", "$user$generic_temp")
shader:dx10texture ("s_diffuse", "$user$albedo")
shader:dx10texture ("s_accumulator", "$user$accum")
shader:dx10texture ("s_bluenoise", tex_bluenoise)
shader:dx10texture ("s_rainsplash", tex_rainsplash)
shader:dx10texture ("s_watercaustics", tex_caustics)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_linear")
shader:dx10sampler ("smp_nofilter")
shader:dx10sampler ("smp_rtlinear")
end
function l_special (shader, t_base, t_second, t_detail)
shader :begin ("waterd","waterd")
:sorting (2, true)
:blend (true,blend.srcalpha,blend.invsrcalpha)
:zb (true,false)
:fog (false)
:distort (true)
shader: dx10color_write_enable( true, true, true, false)
shader:dx10texture ("s_base", tex_base)
shader:dx10texture ("s_distort", tex_dist)
shader:dx10sampler ("smp_base")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,140 @@
/**
* @ Description: Enhanced Shaders and Color Grading 1.10
* @ Author: https://www.moddb.com/members/kennshade
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#ifndef HMODEL_H
#define HMODEL_H
#define CUBE_MIPS 6 //mipmaps for ambient shading and specular
#include "pbr_cubemap_check.h"
//gamma correction is set up to be semi gamma correct
TextureCube env_s0;
TextureCube env_s1;
uniform float4 env_color; // color.w = lerp factor
float4 hmodel_stuff; //x - hemi vibrance // y - hemi contrast // z - wet surface factor
void hmodel
(
out float3 hdiffuse, out float3 hspecular,
float m, float h, float4 alb_gloss, float3 Pnt, float3 normal
)
{
// [ SSS Test ]. Overwrite terrain material
bool m_terrain = abs(m - 0.95) <= 0.04f;
bool m_flora = abs(m - 0.15) <= 0.04f;
if (m_terrain)
m = 0;
//PBR style
float3 albedo = calc_albedo(alb_gloss, m);
float3 specular = calc_specular(alb_gloss, m);
float rough = calc_rough(alb_gloss, m);
//calc_rain(albedo, specular, rough, alb_gloss, m, h);
//calc_foliage(albedo, specular, rough, float4(0.05,0.05,0.05,0.05), m);
float roughCube = rough;
//float roughCube = sqrt(rough); //cubemap mipmaps (brdf too?)
//float RoughMip = roughCube * CUBE_MIPS;
float RoughMip = CUBE_MIPS - ((1 - roughCube) * CUBE_MIPS);
//normal vector
normal = normalize(normal);
float3 nw = mul(m_inv_V, normal);
//nw = normalize(nw);
//view vector
Pnt = normalize(Pnt);
float3 v2Pnt = mul(m_inv_V, Pnt);
//v2Pnt = normalize(v2Pnt);
//normal remap
float3 nwRemap = nw;
float3 vnormabs = abs(nwRemap);
float vnormmax = max(vnormabs.x, max(vnormabs.y, vnormabs.z));
nwRemap /= vnormmax;
if (nwRemap.y < 0.999) nwRemap.y = nwRemap.y*2-1; // fake remapping
//reflection vector
float3 vreflect= reflect(v2Pnt, nw );
//reflect remap
float3 vreflectRemap = vreflect;
float3 vreflectabs = abs(vreflectRemap);
float vreflectmax = max(vreflectabs.x, max(vreflectabs.y, vreflectabs.z));
vreflectRemap /= vreflectmax;
if (vreflectRemap.y < 0.999) vreflectRemap.y = vreflectRemap.y*2-1; //fake remapping
//normalize
nwRemap = normalize(nwRemap);
vreflectRemap = normalize(vreflectRemap);
//DICE reflection vector roughness
vreflectRemap = getSpecularDominantDir(nwRemap, vreflectRemap, rough);
//Valve style ambient cube to prevent seams
const float Epsilon = 0.001;
float3 nSquared = nw * nw;
float3 e0d = 0;
e0d += nSquared.x * (env_s0.SampleLevel(smp_base, float3(nwRemap.x, Epsilon, Epsilon), CUBE_MIPS).rgb);
e0d += nSquared.y * (env_s0.SampleLevel(smp_base, float3(Epsilon, nwRemap.y, Epsilon), CUBE_MIPS).rgb);
e0d += nSquared.z * (env_s0.SampleLevel(smp_base, float3(Epsilon, Epsilon, nwRemap.z), CUBE_MIPS).rgb);
//e0d = LinearTosRGB(e0d);
//e0d = env_s0.SampleLevel(smp_base, nwRemap, CUBE_MIPS);
float3 e1d = 0;
e1d += nSquared.x * (env_s1.SampleLevel(smp_base, float3(nwRemap.x, Epsilon, Epsilon), CUBE_MIPS).rgb);
e1d += nSquared.y * (env_s1.SampleLevel(smp_base, float3(Epsilon, nwRemap.y, Epsilon), CUBE_MIPS).rgb);
e1d += nSquared.z * (env_s1.SampleLevel(smp_base, float3(Epsilon, Epsilon, nwRemap.z), CUBE_MIPS).rgb);
//e1d = LinearTosRGB(e1d);
//e1d = env_s1.SampleLevel(smp_base, nwRemap, CUBE_MIPS);
//specular color
float3 e0s = env_s0.SampleLevel( smp_base, vreflectRemap, RoughMip );
float3 e1s = env_s1.SampleLevel( smp_base, vreflectRemap, RoughMip );
//lerp
float3 env_d = lerp(e0d, e1d, env_color.w);
float3 env_s = lerp(e0s, e1s, env_color.w);
// hscale - something like diffuse reflection
float hscale = h; //. * (.5h + .5h*nw.y);
float hspec = .5h + .5h * dot( vreflect, v2Pnt);
//TODO - make hscale normal mapped
float4 light = float4(hscale, hscale, hscale, hscale);
//float4 light = s_material.SampleLevel( smp_material, float3( hscale, hspec, m ), 0 ).xxxy;
//tint color
//float3 env_col = 1.0;
float3 env_col = env_color.rgb;
//float3 env_col = fog_color.rgb * 2.0;
env_d *= env_col;
env_s *= env_col;
//lightmap ambient
env_d *= light.xxx;
env_s *= light.www;
//ambient color
float3 amb_col = L_ambient.rgb;
env_d += amb_col;
env_s += amb_col; //*(env_s/env_d);
env_d = SRGBToLinear(env_d);
env_s = SRGBToLinear(env_s); //gamma correct
env_s *= 1.0f - m_flora * 0.75f;
hdiffuse = Amb_BRDF(rough, albedo, specular, env_d, env_s, -v2Pnt, nw ).rgb;
hspecular = 0; //do not use hspec at all
}
#endif
@@ -0,0 +1,30 @@
#ifndef IMG_CORRECTIONS_H
#define IMG_CORRECTIONS_H
#include "common.h"
#include "anomaly_shaders.h"
float3 img_corrections(float3 img)
{
//exposure
img.xyz *= pp_img_corrections.x;
//color grading (thanks KD and Crytek and Cjayho)
float fLum = dot(img.xyz, LUMINANCE_VECTOR);
float3 cColor = lerp(0.0, pp_img_cg.xyz, saturate( fLum * 2.0 ) );
cColor = lerp( cColor, 1.0, saturate( fLum - 0.5) * 2.0 );
if (pp_img_cg.x > 0.0 || pp_img_cg.y > 0.0 || pp_img_cg.z > 0.0)
{
img.xyz = saturate(lerp( img.xyz, cColor.xyz , saturate( fLum * 0.15 ) ));
}
//saturation
img.xyz = saturate(lerp(img.xyz, dot(img.xyz, LUMINANCE_VECTOR), (1.0 - pp_img_corrections.z)));
//gamma correction
img.xyz = pow(img,(1.0/pp_img_corrections.y));
//that's all :)
return img.xyz;
}
#endif
@@ -0,0 +1,107 @@
/**
* @ Description: Enhanced Shaders and Color Grading 1.10
* @ Author: https://www.moddb.com/members/kennshade
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/enhanced-shaders-and-color-grading-for-151
*/
#ifndef LMODEL_H
#define LMODEL_H
#include "common.h"
#include "common_brdf.h"
#include "pbr_brdf.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Lighting formulas
float4 compute_lighting(float3 N, float3 V, float3 L, float4 alb_gloss, float mat_id)
{
// [ SSS Test ]. Overwrite terrain material
bool m_terrain = abs(mat_id - 0.95) <= 0.04f;
if (m_terrain)
mat_id = 0;
float3 albedo = calc_albedo(alb_gloss, mat_id);
float3 specular = calc_specular(alb_gloss, mat_id);
float rough = calc_rough(alb_gloss, mat_id);
//calc_rain(albedo, specular, rough, alb_gloss, mat_id, 1);
calc_foliage(albedo, specular, rough, alb_gloss, mat_id);
float3 light = Lit_BRDF(rough, albedo, specular, V, N, L );
//if(mat_id == MAT_FLORA) //Be aware of precision loss/errors
if(abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) //Be aware of precision loss/errors
{
//Simple subsurface scattering
float3 subsurface = SSS(N,V,L);
light.rgb += subsurface*albedo;
}
return float4(light, 0);
}
float4 plight_infinity(float m, float3 pnt, float3 normal, float4 c_tex, float3 light_direction )
{
//gsc vanilla stuff
float3 N = normalize(normal); // normal
float3 V = normalize(-pnt); // vector2eye
float3 L = normalize(-light_direction); // vector2light
float4 light = compute_lighting(N,V,L,c_tex,m);
return light; // output (albedo.gloss)
}
float4 plight_local(float m, float3 pnt, float3 normal, float4 c_tex, float3 light_position, float light_range_rsq, out float rsqr )
{
float atteps = 0.1;
float3 L2P = pnt - light_position; // light2point
rsqr = dot(L2P,L2P); // distance 2 light (squared)
rsqr = max(rsqr, atteps);
//rsqr = rsqr + 1.0;
//vanilla atten - linear
float att = saturate(1.0 - rsqr*light_range_rsq); // q-linear attenuate
att = SRGBToLinear(att);
/*
//unity atten - quadtratic
//catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/
att = rsqr * light_range_rsq;
att *= att;
att = saturate(1.0 - att);
att *= att;
att = att / rsqr;
*/
float3 N = normalize(normal); // normal
float3 V = normalize(-pnt); // vector2eye
float3 L = normalize(-L2P); // vector2light
float4 light = compute_lighting(N,V,L,c_tex,m);
return att*light; // output (albedo.gloss)
}
float3 specular_phong(float3 pnt, float3 normal, float3 light_direction)
{
float3 H = normalize(pnt + light_direction );
float nDotL = saturate(dot(normal, light_direction));
float nDotH = saturate(dot(normal, H));
float nDotV = saturate(dot(normal, pnt));
float lDotH = saturate(dot(light_direction, H));
//float vDotH = saturate(dot(pnt, H));
return L_sun_color.rgb * Lit_Specular(nDotL, nDotH, nDotV, lDotH, 0.02, 0.1);
}
// TODO: DX10: Remove path without blending
half4 blendp(half4 value, float4 tcp)
{
return value;
}
half4 blend(half4 value, float2 tc)
{
return value;
}
#endif
@@ -0,0 +1,25 @@
#include "common.h"
struct v2p
{
float2 tc0: TEXCOORD0; // base
float3 c0: COLOR0; // sun
float fog: FOG;
};
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
float4 main( v2p I ) : SV_Target
{
// float4 t_base = tex2D (s_base,I.tc0);
float4 t_base = s_base.Sample( smp_base, I.tc0 );
float3 light = I.c0;
float3 final = light * t_base * 2;
// Fogging
final = lerp(fog_color, final, I.fog);
// out
return float4 (final.rgb, I.fog * I.fog * t_base.a);
}
@@ -0,0 +1,63 @@
#include "common.h"
#include "skin.h"
#include "screenspace_fog.h"
/*
struct vf
{
float2 tc0 : TEXCOORD0; // base
float3 c0 : COLOR0; // color
float fog : FOG;
float4 hpos : POSITION;
};
*/
struct v2p
{
float2 tc0 : TEXCOORD0; // base
float3 c0 : COLOR0; // color
float fog : FOG;
float4 hpos : SV_Position;
};
v2p _main(v_model v)
{
v2p o;
float4 pos = v.P;
float3 pos_w = mul( m_W, pos );
float3 norm_w = normalize( mul( m_W, v.N ) );
o.hpos = mul( m_WVP, pos ); // xform, input in world coords
o.tc0 = v.tc.xy; // copy tc
o.c0 = calc_model_lq_lighting( norm_w );
o.fog = saturate(calc_fogging( float4( pos_w, 1 ) )); // fog, input in world coords
o.fog = SSFX_FOGGING(1.0 - o.fog, pos.y); // Add SSFX Fog
return o;
}
/////////////////////////////////////////////////////////////////////////
#ifdef SKIN_NONE
v2p main(v_model v) { return _main(v); }
#endif
#ifdef SKIN_0
v2p main(v_model_skinned_0 v) { return _main(skinning_0(v)); }
#endif
#ifdef SKIN_1
v2p main(v_model_skinned_1 v) { return _main(skinning_1(v)); }
#endif
#ifdef SKIN_2
v2p main(v_model_skinned_2 v) { return _main(skinning_2(v)); }
#endif
#ifdef SKIN_3
v2p main(v_model_skinned_3 v) { return _main(skinning_3(v)); }
#endif
#ifdef SKIN_4
v2p main(v_model_skinned_4 v) { return _main(skinning_4(v)); }
#endif
@@ -0,0 +1,56 @@
#include "common.h"
#include "skin.h"
#include "screenspace_fog.h"
struct vf
{
float2 tc0 : TEXCOORD0; // base
float3 tc1 : TEXCOORD1; // environment
float3 c0 : COLOR0; // color
float fog : FOG;
float4 hpos : SV_Position;
};
vf _main (v_model v)
{
vf o;
float4 pos = v.P;
float3 pos_w = mul(m_W, pos);
float3 norm_w = normalize(mul(m_W,v.N));
o.hpos = mul(m_WVP, pos); // xform, input in world coords
o.tc0 = v.tc.xy; // copy tc
o.tc1 = calc_reflection(pos_w, norm_w);
o.c0 = calc_model_lq_lighting(float3(0,1,0)); // SSS 14.5 - Improve the illumination a little using a fake normal
o.fog = saturate(calc_fogging(float4(pos_w,1)) ); // fog, input in world coords
o.fog = SSFX_FOGGING(1.0 - o.fog, pos.y); // Add SSFX Fog
return o;
}
/////////////////////////////////////////////////////////////////////////
#ifdef SKIN_NONE
vf main(v_model v) { return _main(v); }
#endif
#ifdef SKIN_0
vf main(v_model_skinned_0 v) { return _main(skinning_0(v)); }
#endif
#ifdef SKIN_1
vf main(v_model_skinned_1 v) { return _main(skinning_1(v)); }
#endif
#ifdef SKIN_2
vf main(v_model_skinned_2 v) { return _main(skinning_2(v)); }
#endif
#ifdef SKIN_3
vf main(v_model_skinned_3 v) { return _main(skinning_3(v)); }
#endif
#ifdef SKIN_4
vf main(v_model_skinned_4 v) { return _main(skinning_4(v)); }
#endif
@@ -0,0 +1,306 @@
/**
* @ Description: Enhanced Shaders and Color Grading 1.10
* @ Author: https://www.moddb.com/members/kennshade
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
//=================================================================================================
//Pseudo PBR shading for STALKER Anomaly
//Roughness is controlled with r2_gloss_min
//=================================================================================================
#include "pbr_settings.h" //load settings files
#define PI 3.14159265359
//=================================================================================================
uniform float4 ssfx_lightsetup_1; // Spec intensity
//Metalness
float calc_metalness(float4 alb_gloss, float material_ID)
{
//material ID experiment
float metallerp = max(0.0, (material_ID*4)-0.5)/4; //approx material + weight? //nowhere near
//metallerp = saturate((metallerp - 0.5) * 2); //metal threshold
//metallerp = saturate(((metallerp * 4) - 2) * 0.5); //metal threshold
//binary metalness
float metalness = saturate(material_ID - 0.75 - 0.001) > 0 ? 1 : 0;
//float metal_thres = METALNESS_THRESHOLD;
//float metal_soft = METALNESS_SOFTNESS;
//float metal_thres = METALNESS_THRESHOLD * (1 - metallerp) * 2;
float metal_thres = pow(METALNESS_THRESHOLD, exp2(metallerp));
float metal_soft = metal_thres * 0.9;
//lerp on gloss
//metalness *= saturate(smoothstep(METALNESS_THRESHOLD-METALNESS_SOFTNESS, METALNESS_THRESHOLD+METALNESS_SOFTNESS, alb_gloss.a));
metalness *= saturate((alb_gloss.a - (metal_thres-metal_soft)) / ((metal_thres+metal_soft) - (metal_thres-metal_soft)));
return metalness;
}
float3 Soft_Light (float3 base, float3 blend)
{
return (blend <= 0.5) ? base - (1-2*blend)*base*(1-base) : base + (2*blend-1)*(sqrt(base)-base);
}
//=================================================================================================
//Material
//
float3 calc_albedo_boost(float3 albedo)
{
float3 blend = lerp(0.5, 1-dot(albedo, LUMINANCE_VECTOR), ALBEDO_BOOST); //boost albedo by inv
return Soft_Light(albedo, blend);
}
float3 calc_albedo(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
float3 albedo = alb_gloss.rgb;
//albedo = SRGBToLinear(albedo);
albedo = calc_albedo_boost(albedo);
//albedo = SRGBToLinear(albedo);
float3 screen_contrib = albedo;
screen_contrib = (1-(1-screen_contrib)*(1-screen_contrib))-lerp(dot(screen_contrib, LUMINANCE_VECTOR), screen_contrib, 0.5);
albedo = SRGBToLinear(albedo);
screen_contrib = SRGBToLinear(screen_contrib);
float3 albedo_metal = screen_contrib; //metal albedo is screen blend contrib, it gets rid of all highlights.
return saturate(lerp(albedo, albedo_metal, metalness)*ALBEDO_AMOUNT);
}
float3 calc_specular(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
float3 specular = float3(SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE); //base fresnel to tweak
float3 specular_metal = alb_gloss.rgb; //metal uses diffuse for specular
specular_metal = calc_albedo_boost(specular_metal); //boost albedo
specular_metal = SRGBToLinear(specular_metal);
//tweaks for specular boost
//material_ID = sqrt(material_ID/0.75);
material_ID = saturate(material_ID * 1.425);
alb_gloss.a = sqrt(alb_gloss.a);
/*
//old spec boost
float specular_boost = ((0.5+material_ID) * (0.5+alb_gloss.a))-0.25; //0.0 - 2.0 range
specular_boost = specular_boost - 1; //scale in -1 to +1 range
specular_boost = SPECULAR_RANGE * specular_boost;
specular_boost = max(0, specular_boost + 1); //0 - 2
*/
float specular_boost = (material_ID*2-1) + (alb_gloss.a*2-1); //-2.0 - +2.0 range
specular_boost = exp2(SPECULAR_RANGE * specular_boost);
specular_boost = pow(specular_boost, SPECULAR_POW);
specular *= specular_boost;
return saturate(lerp(specular, specular_metal, metalness));
}
float calc_rough(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
alb_gloss.a = pow(alb_gloss.a, ROUGHNESS_POW - (metalness * METAL_BOOST)); //metal boost
float roughpow = 0.5 / max(0.001, 1 - Ldynamic_color.w);
float rough = pow(lerp(ROUGHNESS_HIGH, ROUGHNESS_LOW, alb_gloss.a), roughpow);
//rough = pow(rough, 1 + (metalness * METAL_BOOST)); //metal boost
return saturate(rough*rough);
}
//=================================================================================================
//Rain and Foliage
//
void calc_rain(inout float3 albedo, inout float3 specular, inout float rough, in float4 alb_gloss, in float material_ID, in float rainmask)
{
//rain based on Remember Me's implementation
//float wetness = saturate(rain_params.x*rainmask);
float wetness = saturate(smoothstep(0.1,0.9,rain_params.x*rainmask));
float porosity = 1-saturate(material_ID*1.425); //metal material at 0, concrete at 1
//porosity = saturate((porosity-0.5)/0.4); //Remember Me rain porosity
float factor = lerp(1,0.2, porosity); //albedo darkening factor
albedo *= lerp(1, factor, wetness);
rough = lerp(0.001, rough, lerp(1, factor, wetness));
specular = lerp(specular, 0.02, wetness);
}
void calc_foliage(inout float3 albedo, inout float3 specular, inout float rough, in float4 alb_gloss, in float mat_id)
{
//specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? calc_specular(alb_gloss, 0.0) : specular;
// specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? alb_gloss.g * 0.02 : specular;
//specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? pow(alb_gloss.g * 0.1414, 2) : specular;
if (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON)
{
//float light = 1.0f - saturate(dot(L_hemi_color.rgb, float3(1,1,1)));
specular = alb_gloss.g * 0.05f;//max( light * 0.025f, 0.008f);
}
}
//=================================================================================================
//Functions
//
float F_Shlick(float f0, float f90, float vDotH)
{
return lerp(f0, f90, pow(1-vDotH, 5));
}
float3 F_Shlick(float3 f0, float3 f90, float vDotH)
{
return lerp(f0, f90, pow(1-vDotH, 5));
}
// We have a better approximation of the off specular peak
// but due to the other approximations we found this one performs better .
// N is the normal direction
// R is the mirror vector
// This approximation works fine for G smith correlated and uncorrelated
float3 getSpecularDominantDir(float3 N, float3 R, float roughness)
{
float smoothness = saturate(1 - roughness);
float lerpFactor = smoothness * (sqrt(smoothness) + roughness);
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
//=================================================================================================
//Shading
//
//include BRDFs
#include "pbr_brdf_blinn.h" //brdf
#include "pbr_brdf_ggx.h" //brdf
float Lit_Burley(float nDotL, float nDotV, float vDotH, float rough)
{
float fd90 = 0.5 + 2 * vDotH * vDotH * rough;
float lightScatter = F_Shlick(1, fd90, nDotL);
float viewScatter = F_Shlick(1, fd90, nDotV);
return (lightScatter * viewScatter) / PI;
}
float Lambert_Source(float nDotL,float rough)
{
float exponent = lerp(1.4, 0.6, rough);
return (pow(nDotL, exponent) * ((exponent + 1.0) * 0.5)) / max(1e-5, PI * nDotL);
}
float Lit_Diffuse(float nDotL, float nDotV, float vDotH, float rough)
{
#ifdef USE_BURLEY_DIFFUSE
return Lit_Burley(nDotL, nDotV, vDotH, rough);
#else
return Lambert_Source(nDotL, rough);
#endif
}
float3 Lit_Specular(float nDotL, float nDotH, float nDotV, float vDotH, float3 f0, float rough)
{
#ifdef USE_GGX_SPECULAR
return Lit_GGX(nDotL, nDotH, nDotV, vDotH, f0, rough); //GGX is much more expensive but looks nicer
#else
return Lit_Blinn(nDotL, nDotH, nDotV, vDotH, f0, rough); //much cheaper pbr blinn
#endif
}
float3 Lit_BRDF(float rough, float3 albedo, float3 f0, float3 V, float3 N, float3 L )
{
// SPECULAR ADJUSTMENTS - SSS Update 18
// Color, intensity and some minor adjustments.
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
float3 H = normalize(V + L);
float DotNV = dot(N, V);
float nDotL = saturate(dot(N, L));
float nDotH = saturate(dot(N, H));
float nDotV = max(1e-5, DotNV);
float vDotH = saturate(dot(V, H));
float3 diffuse_term = Lit_Diffuse(nDotL, nDotV, vDotH, rough).rrr;
diffuse_term *= albedo;
// Specular
float3 specular_term = Lit_Specular(nDotL, nDotH, nDotV, vDotH, f0, rough);
// Horizon falloff
float horizon = saturate(DotNV * 2.0f);
specular_term *= horizon * horizon;
// Specular color
float3 light = saturate(Ldynamic_color.rgb);
specular_term *= 1.0f - ((light.r + light.g + light.b) / 3.0) * (1.0f - ssfx_lightsetup_1.x);
specular_term *= lerp(1.0f, Ldynamic_color.rgb, ssfx_lightsetup_1.y);
// SSS Update 19 - Smooth Shading ( squared nDotL )
return (diffuse_term + specular_term) * nDotL * nDotL * PI;
}
//=================================================================================================
//Ambient
//
float EnvBurley(float roughness, float NV)
{
//Burley (Hill's curve)
float d0 = 0.97619 - 0.488095 * pow(1.0 - NV, 5.0);
float d1 = 1.55754 + (-2.02221 + (2.56283 - 1.06244 * NV) * NV) * NV;
return lerp(d0, d1, roughness);
}
float Amb_Diffuse(float3 f0, float rough, float nDotV)
{
#ifdef USE_BURLEY_DIFFUSE
return EnvBurley(rough, nDotV);
#else
return 1.0;
#endif
}
float3 Amb_Specular(float3 f0, float rough, float nDotV)
{
#ifdef USE_GGX_SPECULAR
return EnvGGX(f0, rough, nDotV);
#else
return EnvBlops2(f0, rough, nDotV);
#endif
}
float3 Amb_BRDF(float rough, float3 albedo, float3 f0, float3 env_d, float3 env_s, float3 V, float3 N)
{
float DotNV = dot(N, V);
//float nDotV = 1e-5 + abs(dot(N, V)); //DICE
float nDotV = max(1e-5, DotNV);
float3 diffuse_term = Amb_Diffuse(f0, rough, nDotV);
diffuse_term *= env_d * albedo;
float3 specular_term = Amb_Specular(f0, rough, nDotV);
specular_term *= env_s;
// horizon occlusion with falloff, should be computed for direct specular too
//float R = reflect(V, N);
//float horizon = saturate(1.0 + dot(R, N)); //needs vertex normals
float horizon = saturate(DotNV * 2.0f); // 0.95
horizon *= horizon;
specular_term *= horizon; //horizon atten
return diffuse_term + specular_term;
}
@@ -0,0 +1,124 @@
float D_GGX(float NdotH, float a2)
{
float denominator = (NdotH * a2 - NdotH) * NdotH + 1.0;
return a2 / (PI * denominator * denominator);
}
float Lambda_Smith(float NdotX, float a)
{
float a2 = a * a;
float NdotX_2 = NdotX * NdotX;
return (-1.0 + sqrt(a2 * (1.0 - NdotX_2) / NdotX_2 + 1.0)) * 0.5;
}
//Height Correlated Masking-shadowing function
float G2_Smith_Correlated(float NdotL, float NdotV, float a)
{
float lambdaV = Lambda_Smith(NdotV, a);
float lambdaL = Lambda_Smith(NdotL, a);
return 1.0 / (1.0 + lambdaV + lambdaL);
}
float G2_SmithJointApprox(float NdotL, float NdotV, float a)
{
float Vis_V = NdotL * ( NdotV * ( 1 - a ) + a );
float Vis_L = NdotV * ( NdotL * ( 1 - a ) + a );
return 0.5 * rcp( Vis_V + Vis_L );
}
float3 Lit_GGX(float NdotL, float NdotH, float NdotV, float VdotH, float3 F0, float rough)
{
//Alpha
float a = rough * rough;
float a2 = a * a;
//Normal distribution function
float D = D_GGX(NdotH, a2);
//Masking-shadowing
//float V = G2_Smith_Correlated(NdotL, NdotV, a);
float V = G2_SmithJointApprox(NdotL, NdotV, a); //denom included?
//Fresnel
float3 f90Atten = saturate(50*F0); //UE4 specular shadowing
float3 F = F_Shlick(F0, f90Atten, VdotH);
//Numerator
float3 numerator = (D * V) * F;
//Denominator
//float denominator = 4.0 * NdotV;
return numerator; //UE4 has no denom
//return numerator / denominator;
}
//UE4 mobile approx
float2 EnvBRDFApprox(float Roughness, float NoV )
{
const float4 c0 = { -1, -0.0275, -0.572, 0.022 };
const float4 c1 = { 1, 0.0425, 1.04, -0.04 };
float4 r = Roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NoV ) ) * r.x + r.y;
float2 AB = float2(-1.04, 1.04 ) * a004 + r.zw;
return AB;
}
//-------------------------------------------------------------------------------------------------
// Returns scale and bias values for environment specular reflections that represents the
// integral of the geometry/visibility + fresnel terms for a GGX BRDF given a particular
// viewing angle and roughness value. The final value is computed using polynomials that were
// fitted to tabulated data generated via monte carlo integration.
//-------------------------------------------------------------------------------------------------
float2 GGXEnvironmentBRDFScaleBias(float roughness, float nDotV)
{
const float sqrtRoughness = sqrt(roughness);
const float nDotV2 = nDotV * nDotV;
const float sqrtRoughness2 = sqrtRoughness * sqrtRoughness;
const float sqrtRoughness3 = sqrtRoughness2 * sqrtRoughness;
const float delta = 0.991086418474895f + (0.412367709802119f * sqrtRoughness * nDotV2) -
(0.363848256078895f * sqrtRoughness2) -
(0.758634385642633f * nDotV * sqrtRoughness2);
const float bias = saturate((0.0306613448029984f * sqrtRoughness) + 0.0238299731830387f /
(0.0272458171384516f + sqrtRoughness3 + nDotV2) -
0.0454747751719356f);
const float scale = saturate(delta - bias);
return float2(scale, bias);
}
//LVutner ambient BRDF
float2 integrate_brdf(float roughness, float NV)
{
//Schlick's approximation
float F_partial = pow(1.0 - NV, 5.0);
//GGX
const float4 c0 = float4(-1.0, -0.0275, -0.26, 0.0109);
const float4 c1 = float4(1.0, 0.0455, 1.0417, -0.0417);
float4 r = roughness * c0 + c1;
float a004 = min(0.9 - 0.75 * roughness, F_partial) * r.x + r.y;
float2 AB = float2(-1.0417, 1.0417) * a004 + r.zw;
//Output (Scale, Bias, Burley)
return float2(AB.x, AB.y);
}
float3 EnvGGX(float3 f0, float rough, float nDotV )
{
//UE4 GGX
float3 f90Atten = saturate(50*f0); //UE4 specular shadowing
float2 AB = EnvBRDFApprox(rough, nDotV);
//Matt Pettineo GGX
//float2 AB = GGXEnvironmentBRDFScaleBias(rough, nDotV);
//LVutner GGX
//float2 AB = integrate_brdf(rough, nDotV);
return (f0 * AB.x + AB.y * f90Atten);
}
@@ -0,0 +1,26 @@
/**
* @ Description: Enhanced Shaders and Color Grading 1.10
* @ Author: https://www.moddb.com/members/kennshade
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/enhanced-shaders-and-color-grading-for-151
*/
//=================================================================================================
//Settings for PBR conversion
//=================================================================================================
#define USE_BURLEY_DIFFUSE //use expensive Disney/Burley diffuse
#define USE_GGX_SPECULAR //use more expensive GGX specular
//=================================================================================================
#define ALBEDO_BOOST 0.0
#define ALBEDO_AMOUNT 1.00
#define ROUGHNESS_LOW 0.5
#define ROUGHNESS_HIGH 1.0
#define ROUGHNESS_POW 1.0
#define SPECULAR_BASE 0.01
#define SPECULAR_RANGE 1.0
#define SPECULAR_POW 1.0
#define METAL_BOOST 0.25
#define METALNESS_THRESHOLD 0.125
#define METALNESS_SOFTNESS 0.125
@@ -0,0 +1,84 @@
#include "common.h"
#include "screenspace_hud_raindrops.h"
struct v2p
{
float2 tc0 : TEXCOORD0; //main tc for screen
float3 RDrops : TEXCOORD1; //Raindrops
float4 c0 : COLOR0; //unused shit mb vertex shader idk
};
//intensity and frequency of flickering
#define SCREEN_FLICKERING float2(0.0255,42.0)
//clamping for scale of glitchness
#define SCREEN_GLITCH_LIMIT float2(0.1, 0.40)
//thats a "offset" of channels etc
#define SCREEN_RGB_TCX float3(0.1,0.2,0.3)
#define SCREEN_RGB_TCY float3(0.4,0.3,0.2)
//multipliers for intensity etc
#define SCREEN_RGB_RAND float3(0.33,0.66,0.99)
//just multiplier for rand intensity
#define SCREEN_RAND_TIME float(1.0)
Texture2D s_pdascreen;
float4 pda_params;
float3 glitch(float3 screen, float2 tc)
{
if ((tc.x - rand(timers.x*SCREEN_RAND_TIME) * noise(tc) ) < clamp(SCREEN_GLITCH_LIMIT.x,sin(4.*noise(tc)),SCREEN_GLITCH_LIMIT.y))
{
float randori_first = rand(sin(timers.x*SCREEN_RGB_RAND.x));
screen.x *= s_pdascreen.Sample(smp_base, float2(tc.x-SCREEN_RGB_TCX.x, tc.y+SCREEN_RGB_TCY.x)).z*randori_first;
float randori_second = rand(sin(timers.x*SCREEN_RGB_RAND.y));
screen.y *= s_pdascreen.Sample(smp_base, float2(tc.x-SCREEN_RGB_TCX.y, tc.y+SCREEN_RGB_TCY.y)).y*randori_second;
float randori_third = rand(sin(timers.x*SCREEN_RGB_RAND.z));
screen.z *= s_pdascreen.Sample(smp_base, float2(tc.x-SCREEN_RGB_TCX.z, tc.y+SCREEN_RGB_TCY.z)).x*randori_third;
screen += SCREEN_FLICKERING.x * sin(timers.x*SCREEN_FLICKERING.y);
}
return screen;
}
float4 main( v2p I ): SV_Target
{
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
float4 drops = 0; // xy = Normal | z = Overall str | w = reflection str
float extra_col = 0;
if (ssfx_hud_drops_1.y > 0)
{
// Calc droplets
float4 Layer0 = s_hud_rain.Sample(smp_base, (I.tc0 + float2(0, -ssfx_hud_drops_1.x * 0.01f)) * float2(1.5f, 0.75f)); // Big drops
float4 Layer1 = s_hud_rain.Sample(smp_base, I.tc0 * float2(5.0f, 3.0f)); // Small drops [ Static ]
// Process animation
float3 result = ssfx_process_drops(Layer0, 0.1f, 0.2f) + ssfx_process_drops(Layer1, 0.2f, 1.0f);
result.xy = clamp(result.xy, -1.0f, 1.0f);
// Only apply to facing up surfaces [ World Y+ ]
result.xyz *= saturate(I.RDrops.y);
// Intensity from script ( Cover + Rain intensity )
result.xyz *= ssfx_hud_drops_1.y;
// Refraction
I.tc0.xy = I.tc0.xy - result.xy * 0.4f;
// Add a small amount of white.
extra_col = saturate(Layer0.x + Layer1.x) * result.z * 0.25f;
}
float4 col = s_pdascreen.Sample(smp_base, I.tc0) + extra_col;
col.rgb = lerp(col.rgb, glitch(col.rgb, I.tc0), pda_params.y);
return float4(col.rgb, pda_params.x) * pda_params.z;
}
@@ -0,0 +1,13 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("pda_overlay","pda_overlay")
: fog (true)
: zb (true,false)
: blend (true,blend.srcalpha,blend.invsrcalpha)
: aref (true,0)
: sorting (2,true)
: distort (true)
shader:dx10texture ("s_base", t_base)
shader:dx10texture ("s_pdascreen", "$user$ui")
shader:dx10texture ("s_hud_rain", "fx\\hud_rain")
shader:dx10sampler ("smp_base")
end
@@ -0,0 +1,56 @@
#include "common.h"
#include "skin.h"
struct vf
{
float2 tc0 : TEXCOORD0; // base
float3 RDrops : TEXCOORD1;
float4 c0 : COLOR0; // color
float4 hpos : SV_Position;
};
vf _main (v_model v)
{
vf o;
o.hpos = mul(m_WVP, v.P); // xform, input in world coords
o.tc0 = v.tc.xy; // copy tc
// calculate fade
float3 dir_v = normalize (mul(m_WV,v.P));
float3 norm_v = normalize (mul(m_WV,v.N));
float fade = abs (dot(dir_v,norm_v));
o.c0 = fade;
// HUD Rain drops - SSS Update 17
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
o.RDrops.xyz = mul(m_W,v.N); // Normal [ World Space ]
return o;
}
/////////////////////////////////////////////////////////////////////////
#ifdef SKIN_NONE
vf main(v_model v) { return _main(v); }
#endif
#ifdef SKIN_0
vf main(v_model_skinned_0 v) { return _main(skinning_0(v)); }
#endif
#ifdef SKIN_1
vf main(v_model_skinned_1 v) { return _main(skinning_1(v)); }
#endif
#ifdef SKIN_2
vf main(v_model_skinned_2 v) { return _main(skinning_2(v)); }
#endif
#ifdef SKIN_3
vf main(v_model_skinned_3 v) { return _main(skinning_3(v)); }
#endif
#ifdef SKIN_4
vf main(v_model_skinned_4 v) { return _main(skinning_4(v)); }
#endif
@@ -0,0 +1,31 @@
#include "common.h"
#include "screenspace_fog.h"
struct v_vert
{
float4 pos : POSITION; // (float,float,float,1)
float4 color : COLOR0; // (r,g,b,dir-occlusion)
};
struct v2p
{
float4 c : COLOR0;
float fog : FOG;
float4 hpos : SV_Position;
};
v2p main (v_vert v)
{
v2p o;
o.hpos = mul(m_VP, v.pos); // xform, input in world coords
float fog = saturate(calc_fogging(v.pos)); // fog, input in world coords
o.fog = SSFX_FOGGING(1.0 - fog, v.pos.y); // Add SSFX Fog
o.c.rgb = lerp(fog_color, v.color, o.fog * o.fog); // fog blending
o.c.a = o.fog; // Alpha
return o;
}
FXVS;
@@ -0,0 +1,125 @@
#include "screenspace_common.h"
// Check Addons
#include "check_screenspace.h"
#ifdef SSFX_BEEFS_NVG
#include "night_vision.h"
#endif
float4 blur_params;
#ifndef SSFX_BEEFS_NVG
float4 main(p_screen I) : SV_Target
{
return SSFX_Blur(I.tc0, 0.25f);
}
#else
float4 main(p_screen I) : SV_Target
{
// Defines
float3 image;
const float GAUSS_SIGMA = 2.5;
const int support = int(GAUSS_SIGMA * 1.5);
float lua_param_nvg_generation = floor(shader_param_8.x); // 1, 2, or 3
float lua_param_nvg_num_tubes = frac(shader_param_8.x) * 10.0f;
float lua_param_nvg_washout_thresh = frac(shader_param_8.y);
float lua_param_vignette_current = floor(shader_param_8.z) / 100.0f;
if (lua_param_nvg_generation > 0.0f && compute_lens_mask(aspect_ratio_correction(I.tc0), lua_param_nvg_num_tubes) == 1.0f) // if NVGs are enabled ...
{
// HALF RES BLUR - PASS 1 - R = LUMA, G = LIGHTMAP, B = NORMALIZED DEPTH OUT TO FARTHEST_DEPTH (defined in night_vision.h)
if (blur_params.x == 1 && blur_params.z == (screen_res.x / 2.0f))
{
image = float3(s_image.Sample(smp_rtlinear, I.tc0).rg,saturate(s_position.Load( int3( (I.tc0)*screen_res.xy, 0 ), 0 ).z / farthest_depth));
if (image.b == 0.0f) { image.b = 1.0f; } float scale = 0.05f; scale *= (IGN_calc(I.tc0/2.0*screen_res.xy)); float3 total = 0.0f; float divisor = 0.0f;
float total_depth = image.b; float divisor_depth = 1.0f; float r = 1.0f; float2x2 G = rot(2.399996); float2 offset = float2(scale,scale);
for (int i = 0; i < 16; ++i) {
r += 1.0f / r; offset = mul(offset, G); float3 color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (offset * (r - 1.0f) * 1.0f/screen_res.xy),0).rgb;
color.b = saturate(s_position.Load( int3( (I.tc0*screen_res.xy) + (offset * (r - 1.0f)), 0 ), 0 ).z / (farthest_depth));
if (color.b == 0.0f) { color.b = 1.0f; } float weight = 1.0f; total.rg += color.rg * weight; divisor += weight; if (color.b <= image.b - 0.04)
{ total_depth += color.b; divisor_depth += weight; }
}
image = float3(max((total.rg / divisor),0),max((total_depth / divisor_depth),0));
float vignette = calc_vignette(lua_param_nvg_num_tubes, I.tc0, lua_param_vignette_current); image = clamp(image,0.0,1.0); image *= vignette;
return float4(image, 1.0f);
}
// HALF RES BLUR - PASS 2 - R = LUMA, G = LIGHTMAP, B = BLURRED DEPTH
else if (blur_params.x == 0 && blur_params.z == (screen_res.x / 2.0f)) // half-res fixed DOF blur pass 2
{
image = s_image.Sample(smp_rtlinear, I.tc0).rgb; float scale = 0.3f; float center_depth = image.b; scale *= (IGN_calc(I.tc0/2.0*screen_res.xy));
float3 total = 0.0f; float divisor = 0.0f; float r = 1.0f; float2x2 G = rot(2.399996); float2 offset = float2(scale,scale);
for (int i = 0; i < 24; ++i) { r += 1.0f / r; offset = mul(offset, G);
float falloff = saturate( ( 1.2f * center_depth ) - log(center_depth * 6.4f) - ( 0.4f * pow(center_depth, 2.3f) ) );
float3 color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (offset * (falloff) * (r - 1.02f) * 1.0f/screen_res.xy),0).rgb;
float weight = 1.0f; total += color * weight; divisor += weight;
}
image = max((total.rgb / divisor),0);
float vignette = calc_vignette(lua_param_nvg_num_tubes, I.tc0, lua_param_vignette_current); image = clamp(image,0.0,1.0); image *= vignette;
return float4(image, 1.0f);
}
// QUARTER RES BLUR - PASS 1 - R = LUMA, G = LIGHTMAP, B = ALBEDO
else if (blur_params.x == 1 && blur_params.z == (screen_res.x / 4))
{
float general_threshold = 0.05f; float light_thresh = lua_param_nvg_washout_thresh; float Pi = 6.28318530718; float blur_directions = 12.0; float blur_quality = 6.0;
float blur_radius = 1.5; float3 color = 0.0f; float3 color_average = s_image.Sample(smp_rtlinear, I.tc0).rgb; float weight = 0.0f;
float light_avgs = 0.0f;
for(float i=1.0; i<= blur_quality; i++) { for( float d=0.0; d<Pi; d+=Pi/blur_directions) {
color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (float2(cos(d),sin(d))*blur_radius*i/screen_res.xy),0).rgb; color.rb *= color.rb;
color.rb = saturate((color.rb - general_threshold) / (1.0f - general_threshold)); color.g = saturate((color.g - light_thresh) / (1.0f - light_thresh));
if (color.g > 0.0f) { color.g *= 8.0f; light_avgs += 1.0f;} else {light_avgs += 0.1 * i;}
color.rb = sqrt(color.rb); color_average += color; } }
image.rb = color_average.rb / (blur_directions*blur_quality); image.g = color_average.g / light_avgs;
return float4(image, 1.0f);
}
// QUARTER RES BLUR - PASS 2 - R = LUMA, G = LIGHTMAP, B = ALBEDO
else if (blur_params.x == 0 && blur_params.z == (screen_res.x / 4)) // quarter and eighth res circular bokeh pass 2
{
float Pi = 6.28318530718; float blur_directions = 16.0; float blur_quality = 4.0; float blur_radius = 4; float3 color = 0.0f;
float3 color_average = s_image.Sample(smp_rtlinear, I.tc0).rgb; float light_avgs = 0.0f; float weight = 0.0f; float total_weight = 0.0f;
for(float i=1.0; i<= blur_quality; i++) { for( float d=0.0; d<Pi; d+=Pi/blur_directions) {
color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (float2(cos(d),sin(d))*blur_radius*i/screen_res.xy),0).rgb;
if (color.g > 0.0f) { color.g *= 4.0f; light_avgs += 1.0f;} else {light_avgs += 0.1 * i;} color_average += color; } }
image.rb = color_average.rb / (blur_directions*blur_quality); image.g = color_average.g / light_avgs;
return float4(image, 1.0f);
}
// EIGHTH RES BLUR - PASS 1 - R = LUMA, G = LIGHTMAP, B = ALBEDO
else if (blur_params.x == 1 && blur_params.z == (screen_res.x / 8)) // quarter and eighth res circular bokeh pass 1
{
float general_threshold = 0.05f; float light_thresh = lua_param_nvg_washout_thresh; float Pi = 6.28318530718; float blur_directions = 12.0; float blur_quality = 4.0;
float blur_radius = 1; float3 color = 0.0f; float3 color_average = s_image.Sample(smp_rtlinear, I.tc0).rgb; float weight = 0.0f; float total_weight = 0.0f;
float light_avgs = 0.0f;
for(float i=1.0; i<= blur_quality; i++) { for( float d=0.0; d<Pi; d+=Pi/blur_directions) {
color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (float2(cos(d),sin(d))*blur_radius*i/screen_res.xy),0).rgb; color.rb *= color.rb;
color.rb = saturate((color.rb - general_threshold) / (1.0f - general_threshold)); color.g = saturate((color.g - light_thresh) / (1.0f - light_thresh));
if (color.g > 0.0f) { color.g *= 8.0f; light_avgs += 1.0f;} else {light_avgs += 0.1 * i;} color.rb = sqrt(color.rb); color_average += color; } }
image.rb = color_average.rb / (blur_directions*blur_quality); image.g = color_average.g / light_avgs;
return float4(image, 1.0f);
}
// EIGHTH RES BLUR - PASS 2 - R = LUMA, G = LIGHTMAP, B = ALBEDO
else if (blur_params.x == 0 && blur_params.z == (screen_res.x / 8)) // quarter and eighth res circular bokeh pass 2
{
float Pi = 6.28318530718; float blur_directions = 16.0; float blur_quality = 4.0; float blur_radius = 4; float3 color = 0.0f;
float3 color_average = s_image.Sample(smp_rtlinear, I.tc0).rgb; float light_avgs = 0.0f; float weight = 0.0f; float total_weight = 0.0f;
for(float i=1.0; i<= blur_quality; i++) { for( float d=0.0; d<Pi; d+=Pi/blur_directions) {
color = s_image.SampleLevel(smp_rtlinear, I.tc0 + (float2(cos(d),sin(d))*blur_radius*i/screen_res.xy),0).rgb;
if (color.g > 0.0f) { color.g *= 4.0f; light_avgs += 1.0f;} else {light_avgs += 0.1 * i;} color_average += color; } }
image.rb = color_average.rb / (blur_directions*blur_quality); image.g = color_average.g / light_avgs;
return float4(image, 1.0f);
}
}
// OTHERWISE, DO NORMAL BLUR
return SSFX_Blur(I.tc0, 0.25f);
}
#endif
@@ -0,0 +1,158 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 18
* @ Description: Rain patch normal
* @ Modified time: 2023-10-09 07:25
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "common.h"
#include "lmodel.h"
#include "shadow.h"
#include "screenspace_common_ripples.h"
uniform float4 ssfx_wetsurfaces_1; // Ripples [ Size, Speed, Min Speed, Int ]
uniform float4 ssfx_wetsurfaces_2; // FallWater [ Size, Speed, Min Speed, Int ]
Texture2D s_water;
Texture2D s_waterFall;
float4 RainFallof;
float3 GetWaterFall( Texture2D s_texture, float2 tc)
{
// 0.75 1.5 0.2 0.5
// Num of columns
float col_num = 50;
float col_scale = 1.0 / col_num;
// Original UV Coors
float2 tc_ori = tc * ssfx_wetsurfaces_2.x;
// UV Columns
float2 col_tc = float2(frac(tc_ori.x * col_num), tc_ori.y);
// Column ID to add a random offset and adjust horizontal offset
half col_id = ceil(tc_ori.x * col_num);
// Random Y-Offset for each column
float col_offset = hash22(float2(col_id, 1.0));
// Limit min speed
col_offset = (col_offset < ssfx_wetsurfaces_2.z ? col_offset * 3.0f : col_offset);
// Animate
col_offset += timers.x * col_offset * rain_params.x * ssfx_wetsurfaces_2.y;
// Add wabbly
//col_tc.x += sin((tc_ori.y + col_offset) * 20) * 0.5f + 0.5f;
// Base Bump. Columns UVs, scale and apply offset.
float3 water = s_texture.Sample(smp_base, (col_tc * float2(col_scale, 1.0f) + float2(col_scale * col_id, col_offset)));
// Bump to -1.0 ~ 1.0
water.xyz = water.xzy * 2.0f - 1.0f;
// Intensity
water.xyz *= ssfx_wetsurfaces_2.w;
return water.xyz;
}
#ifndef ISAMPLE
#define ISAMPLE 0
#endif
#ifdef MSAA_OPTIMIZATION
float4 main ( float2 tc : TEXCOORD0, float2 tcJ : TEXCOORD1, float4 Color : COLOR, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( float2 tc : TEXCOORD0, float2 tcJ : TEXCOORD1, float4 Color : COLOR, float4 pos2d : SV_Position ) : SV_Target
#endif
{
#ifdef MSAA_OPTIMIZATION
gbuffer_data gbd = gbuffer_load_data( tc, pos2d, iSample );
#else
gbuffer_data gbd = gbuffer_load_data( tc, pos2d, ISAMPLE );
#endif
// Buffers
float4 _P = float4( gbd.P, 1.0 );
float3 _N = normalize(gbd.N.xyz);
float3 _D = gbd.C;
float _M = gbd.mtl;
float4 PS = mul( m_shadow, _P );
float3 WorldP = mul( m_sunmask, _P );
float3 WorldN = mul( m_sunmask, _N.xyz );
// Read rain projection with some jetter. Also adding pixel normal
// factor to jitter to make rain strips more realistic.
float Cover = shadow_rain( PS, WorldP.xz - WorldN.xz ); // Wet Surfaces fix by Diana.Petran
// Distance
float p_len = length( _P.xyz );
bool is_flora = abs(_M - 0.15) < 0.04f;
bool is_terrain = abs(_M - 0.95) < 0.04f;
// Rain parameters ( Wetness > 0.5 = 100% | Rain Intensity > 0.66 = 100% )
float Wetness = saturate(rain_params.y * 2.0f);
float RainInt = clamp(rain_params.x * ssfx_wetsurfaces_1.y, ssfx_wetsurfaces_1.z * (rain_params.x > 0), 2.0f); // 1.5
// [ BUMP ] -------------------------------------------
float3 waterSplash = 0;
waterSplash.xy = ssfx_rain_ripples( s_water, WorldP.xz * ssfx_wetsurfaces_1.x, float3(RainInt, ssfx_wetsurfaces_1.w, 6), _P.z); // 0.9
// Blending weights ( We don't want splashes or fall water on FLORA )
float3 weights = WorldN.xyz * !is_flora;
// Water Fall
float3 waterFallX = GetWaterFall( s_waterFall, WorldP.zy );
float3 waterFallZ = GetWaterFall( s_waterFall, WorldP.xy );
// Base bump - Splahes
float3 water = waterSplash * smoothstep(0.75f, 0.8f, weights.y);
// Adjust Water fall and add to the Normal
weights.xz = saturate(abs(weights.xz) - 0.15f);
weights.xz *= float2(weights.x > weights.z, weights.x < weights.z);
water += waterFallX.yxz * weights.x;
water += waterFallZ.zxy * weights.z;
// HUD attenuations ( Remove Terrain & Flora )
float HUD_Attenuation = smoothstep( 1.0f, 1.3f, p_len + (is_terrain * 1.3f) ) * !is_flora;
// Apply attenuations
water *= HUD_Attenuation * saturate(RainInt) * Cover;
// Convert normal to view space
water = mul( m_V, water );
// Add water normal
_N = normalize(_N + water.xyz);
// [ GLOSS ] ------------------------------------------
float Gloss = (0.15f + saturate(RainInt) * 0.05) * Wetness; // Wetness
// Fade to full cover. ( RainFallof.y = far shadow rain rendering )
Cover += smoothstep( RainFallof.y - 20, RainFallof.y, _P.z );
// If gloss is high, remove cover factor
Gloss *= HUD_Attenuation * saturate(Cover + (gbd.gloss > 0.3f));
// Limit gloss on terrain ( Puddles )
Gloss = (is_terrain && gbd.gloss > 0.3f) ? 0.15f : Gloss;
// Remove rain gloss from bottom surfaces
Gloss *= saturate(weights.y * 1.5f);
// Apply distance falloff
Gloss *= smoothstep( 250, 200, p_len );
return float4( _N.xyz, Gloss );
}
@@ -0,0 +1,330 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 14
* @ Description: Main file
* @ Modified time: 2024-11-24 00:49
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#define SSFX_READY
#include "common.h"
#include "lmodel.h"
#include "hmodel.h"
#include "screenspace_common_noise.h"
#include "screenspace_common_ripples.h"
#include "check_screenspace.h"
static const float3 ssfx_hemisphere[64] =
{
float3(-0.134, 0.044, -0.825), float3(0.045, -0.431, -0.529), float3(-0.537, 0.195, -0.371),
float3(0.525, -0.397, 0.713), float3(0.895, 0.302, 0.139), float3(-0.613, -0.408, -0.141),
float3(0.307, 0.822, 0.169), float3(-0.819, 0.037, -0.388), float3(0.376, 0.009, 0.193),
float3(-0.006, -0.103, -0.035), float3(0.098, 0.393, 0.019), float3(0.542, -0.218, -0.593),
float3(0.526, -0.183, 0.424), float3(-0.529, -0.178, 0.684), float3(0.066, -0.657, -0.570),
float3(-0.214, 0.288, 0.188), float3(-0.689, -0.222, -0.192), float3(-0.008, -0.212, -0.721),
float3(0.053, -0.863, 0.054), float3(0.639, -0.558, 0.289), float3(-0.255, 0.958, 0.099),
float3(-0.488, 0.473, -0.381), float3(-0.592, -0.332, 0.137), float3(0.080, 0.756, -0.494),
float3(-0.638, 0.319, 0.686), float3(-0.663, 0.230, -0.634), float3(0.235, -0.547, 0.664),
float3(0.164, -0.710, 0.086), float3(-0.009, 0.493, -0.038), float3(-0.322, 0.147, -0.105),
float3(-0.554, -0.725, 0.289), float3(0.534, 0.157, -0.250),
float3(-0.234, 0.084, -0.425), float3(0.085, -0.831, -0.229), float3(-0.837, 0.295, -0.671),
float3(0.225, -0.697, 0.113), float3(0.295, 0.602, 0.239), float3(-0.413, -0.808, -0.241),
float3(0.607, 0.222, 0.269), float3(-0.219, 0.067, -0.688), float3(0.676, 0.0, 0.293),
float3(-0.00, -0.203, -0.135), float3(0.198, 0.693, 0.019), float3(0.842, -0.418, -0.193),
float3(0.526, -0.283, 0.824), float3(-0.529, -0.278, 0.484), float3(0.166, -0.707, -0.170),
float3(-0.414, 0.488, 0.288), float3(-0.489, -0.422, -0.292), float3(-0.008, -0.412, -0.321),
float3(0.153, -0.263, 0.054), float3(0.439, -0.558, 0.489), float3(-0.455, 0.158, 0.099),
float3(-0.888, 0.873, -0.681), float3(-0.192, -0.632, 0.237), float3(0.080, 0.356, -0.894),
float3(-0.438, 0.619, 0.486), float3(-0.463, 0.430, -0.434), float3(0.435, -0.547, 0.464),
float3(0.264, -0.310, 0.186), float3(-0.109, 0.893, -0.038), float3(-0.622, 0.247, -0.205),
float3(-0.500, -0.325, 0.489), float3(0.534, 0.247, -0.450)
};
#ifdef USE_MSAA
Texture2DMS<float4,MSAA_SAMPLES> s_rimage;
#else
Texture2D s_rimage;
#endif
uniform float4 sky_color;
TextureCube sky_s0;
TextureCube sky_s1;
static const float2 ssfx_pixel_size = 1.0f / screen_res.xy;
static const float ssfx_PI = 3.14159265f;
struct RayTrace
{
float2 r_pos;
float2 r_step;
float2 r_start;
float r_length;
float z_start;
float z_end;
};
bool SSFX_is_saturated(float2 value) { return (value.x == saturate(value.x) && value.y == saturate(value.y)); }
bool SSFX_is_valid_uv(float2 value) { return (value.x >= 0.0f && value.x <= 1.0f) && (value.y >= 0.0f && value.y <= 1.0f); }
float2 SSFX_view_to_uv(float3 Pos)
{
float4 tc = mul(m_P, float4(Pos, 1));
return (tc.xy / tc.w) * float2(0.5f, -0.5f) + 0.5f;
}
float SSFX_calc_SSR_fade(float2 tc, float start, float end)
{
// Vectical fade
float ray_fade = saturate(tc.y * 5.0f);
// Horizontal fade
float2 calc_edges = smoothstep(start, end, float2(tc.x, 1.0f - tc.x));
ray_fade *= calc_edges.x * calc_edges.y;
return ray_fade;
}
float3 SSFX_yaw_vector(float3 Vec, float Rot)
{
float s, c;
sincos(Rot, s, c);
// y-axis rotation matrix
float3x3 rot_mat =
{
c, 0, s,
0, 1, 0,
-s, 0, c
};
return mul(rot_mat, Vec);
}
float SSFX_get_depth(float2 tc, uint iSample : SV_SAMPLEINDEX)
{
#ifndef USE_MSAA
return s_position.SampleLevel(smp_nofilter, tc, 0).z;
#else
return s_position.Load(int3(tc * screen_res.xy, 0), iSample).z;
#endif
}
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
}
float3 SSFX_get_image(float2 tc, uint iSample : SV_SAMPLEINDEX)
{
#ifndef USE_MSAA
return s_rimage.SampleLevel(smp_nofilter, tc, 0).rgb;
#else
return s_rimage.Load(int3(tc * screen_res.xy, 0), 0).rgb;
#endif
}
RayTrace SSFX_ray_init(float3 ray_start_vs, float3 ray_dir_vs, float ray_max_dist, int ray_steps, float noise)
{
RayTrace rt;
float3 ray_end_vs = ray_start_vs + ray_dir_vs * ray_max_dist;
// Ray depth ( from start and end point )
rt.z_start = ray_start_vs.z;
rt.z_end = ray_end_vs.z;
// Compute ray start and end (in UV space)
rt.r_start = SSFX_view_to_uv(ray_start_vs);
float2 ray_end = SSFX_view_to_uv(ray_end_vs);
// Compute ray step
float2 ray_diff = ray_end - rt.r_start;
rt.r_step = ray_diff / (float)ray_steps;
rt.r_length = length(ray_diff);
rt.r_pos = rt.r_start + rt.r_step * noise;
return rt;
}
float3 SSFX_ray_intersect(RayTrace Ray, uint iSample)
{
float len = length(Ray.r_pos - Ray.r_start);
float alpha = len / Ray.r_length;
float depth_ray = (Ray.z_start * Ray.z_end) / lerp(Ray.z_end, Ray.z_start, alpha);
float depth_scene = SSFX_get_depth(Ray.r_pos, iSample);
return float3(depth_ray.x - depth_scene, depth_scene, len);
}
// Half-way scene lighting
float4 SSFX_get_fast_scenelighting(float2 tc, uint iSample : SV_SAMPLEINDEX)
{
#ifndef USE_MSAA
float4 rL = s_accumulator.Sample(smp_nofilter, tc);
float4 C = s_diffuse.Sample( smp_nofilter, tc );
#else
float4 rL = s_accumulator.Load(int3(tc * screen_res.xy, 0), iSample);
float4 C = s_diffuse.Load(int3( tc * screen_res.xy, 0 ), iSample);
#endif
#ifdef SSFX_ENHANCED_SHADERS // We have Enhanced Shaders installed
/*float3 hdiffuse = C.rgb + L_ambient.rgb;
rL.rgb += rL.a * SRGBToLinear(C.rgb);
return float4(LinearTosRGB((rL.rgb + hdiffuse) * saturate(rL.rrr * 100)), C.w);*/
float3 result = rL.rgb + rL.a * C.rgb;
result *= env_color.rgb;
return float4(result, C.w);
#else
float3 hdiffuse = C.rgb + L_ambient.rgb;
return float4((rL.rgb + hdiffuse) * saturate(rL.rrr * 100), C.w);
#endif
}
// Full scene lighting
float3 SSFX_get_scene(float2 tc, uint iSample : SV_SAMPLEINDEX)
{
#ifndef USE_MSAA
float4 rP = s_position.Sample( smp_nofilter, tc );
#else
float4 rP = s_position.Load(int3(tc * screen_res.xy, 0), iSample);
#endif
if (rP.z <= 0.05f)
return 0;
#ifndef USE_MSAA
float4 rD = s_diffuse.Sample( smp_nofilter, tc );
float4 rL = s_accumulator.Sample(smp_nofilter, tc);
#else
float4 rD = s_diffuse.Load(int3(tc * screen_res.xy, 0), iSample);
float4 rL = s_accumulator.Load(int3(tc * screen_res.xy, 0), iSample);
#endif
// Remove emissive materials for now...
if (length(rL) > 10.0f)
rL = 0;
float3 rN = gbuf_unpack_normal( rP.xy );
float rMtl = gbuf_unpack_mtl( rP.w );
float rHemi = gbuf_unpack_hemi( rP.w );
float3 nw = mul( m_inv_V, rN );
#ifdef SSFX_ENHANCED_SHADERS
rL.rgb += rL.a * SRGBToLinear(rD.rgb);
// hemisphere
float3 hdiffuse, hspecular;
hmodel(hdiffuse, hspecular, rMtl, rHemi, rD, rP, rN);
// Final color
float3 rcolor = rL.rgb + hdiffuse.rgb;
return LinearTosRGB(rcolor);
#else
// hemisphere
float3 hdiffuse, hspecular;
hmodel(hdiffuse, hspecular, rMtl, rHemi, rD.w, rP, rN);
// Final color
float4 light = float4(rL.rgb + hdiffuse, rL.w);
float4 C = rD * light;
float3 spec = C.www * rL.rgb;
return C.rgb + spec;
#endif
}
float3 SSFX_calc_sky(float3 dir)
{
dir = SSFX_yaw_vector(dir, -sky_color.w); // Sky rotation
dir.y = (dir.y - max(cos(dir.x) * 0.65f, cos(dir.z) * 0.65f)) * 2.1f; // Fix perspective
dir.y -= -0.35; // Altitude
float3 sky0 = sky_s0.SampleLevel(smp_base, dir, 0).xyz;
float3 sky1 = sky_s1.SampleLevel(smp_base, dir, 0).xyz;
// Use hemi color or real sky color if the modded executable is installed.
#ifndef SSFX_MODEXE
return saturate(L_hemi_color.rgb) * lerp(sky0, sky1, L_ambient.w);
#else
return saturate(sky_color.bgr) * lerp(sky0, sky1, L_ambient.w);
#endif
}
float3 SSFX_calc_env(float3 dir)
{
float3 env0 = env_s0.SampleLevel(smp_base, dir, 0).xyz;
float3 env1 = env_s1.SampleLevel(smp_base, dir, 0).xyz;
return env_color.xyz * lerp( env0, env1, env_color.w );
}
// https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel
// 1.3f water ~ 1.5f glass ~ 1.8f diamond
float SSFX_calc_fresnel(float3 V, float3 N, float ior)
{
float cosi = clamp(-1, 1, dot(V, N));
float etai = 1, etat = ior;
if (cosi > 0)
{
etai = ior;
etat = 1;
}
// Compute sini using Snell's law
float sint = etai / etat * sqrt(max(0.f, 1 - cosi * cosi));
// Total internal reflection
if (sint >= 1)
return 1.0f;
float cost = sqrt(max(0.f, 1 - sint * sint));
cosi = abs(cosi);
float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost));
float Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost));
return (Rs * Rs + Rp * Rp) / 2;
}
static const float2x2 pp_rotation_matrix = { -0.666276f, 0.745705f, -0.745705f, -0.666276f };
float4 SSFX_Blur(float2 uv, float radius)
{
float3 blur = 0;
radius *= SSFX_gradient_noise_IGN(uv / 2.0 * screen_res.xy) * 6.28f;
float2 offset = float2(radius, radius);
float r = 0.9f;
for (int i = 0; i < 16; i++)
{
r += 1.0f / r;
offset = mul(offset, pp_rotation_matrix);
blur += s_image.SampleLevel(smp_rtlinear, uv + (offset * (r - 1.0f) * ssfx_pixel_size), 0).rgb;
}
float3 image = blur / 16;
return float4(image, 1.0f);
}
@@ -0,0 +1,59 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 12.5
* @ Description: Main file - Noise
* @ Modified time: 2024-04-25 01:58
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
float3 hash33(float3 p3)
{
p3 = frac(p3 * float3(0.1031f, 0.1030f, 0.0973f));
p3 += dot(p3, p3.yxz + 33.33f);
return frac((p3.xxy + p3.yxx) * p3.zyx);
}
float4 SSFX_mod289(float4 x)
{
return x - floor(x / 289.0f) * 289.0f;
}
float4 SSFX_permute(float4 x)
{
return SSFX_mod289((x * 34.0f + 1.0f) * x);
}
float SSFX_noise(float2 tc)
{
float2 noise = frac(tc.xy * 0.5f);
return noise.x + noise.y * 0.5f;
}
float2 SSFX_noise2(float2 p)
{
p = p % 289;
float x = (34 * p.x + 1) * p.x % 289 + p.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
float SSFX_gradient_noise_IGN(float2 uv)
{
// IGN
uv = frac(uv);
float f = 0.06711056 * uv.x + 0.00583715 * uv.y;
return frac(52.9829189 * frac(f));
}
float SSFX_gradientNoise(float2 p)
{
float2 ip = floor(p);
float2 fp = frac(p);
float d00 = dot(SSFX_noise2(ip), fp);
float d01 = dot(SSFX_noise2(ip + float2(0, 1)), fp - float2(0, 1));
float d10 = dot(SSFX_noise2(ip + float2(1, 0)), fp - float2(1, 0));
float d11 = dot(SSFX_noise2(ip + float2(1, 1)), fp - float2(1, 1));
fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);
return lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x);
}
@@ -0,0 +1,62 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 18
* @ Description: Ripples code
* @ Modified time: 2023-09-21 01:31
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*
* Based on the work of Sébastien Lagarde for the game "Remember Me"
* https://seblagarde.wordpress.com/2013/01/03/water-drop-2b-dynamic-rain-and-its-effects/
*
* Setup : [ x: speed | y: intensity | z: ripple frequency ]
* Sample : [ x: Fade | y: Normal-Y | z: Normal-X | w: Time Offset ]
*/
static const float3 SSFX_ripples_speed = float3( 1.05f, 1.31f, 1.58f );
static const float4 SSFX_ripples_offset = float4( 0.5f, 0.25f, 0.31f, 0.5f );
static const float SSFX_ripples_PI = 3.141592f;
float2 ssfx_process_ripples(float4 ripples, float3 setup)
{
// Get bump from texture and transform to -1.0 ~ 1.0
float2 ripples_N = ripples.yz * 2.0 - 1.0;
// Apply time
float RFrac = frac(ripples.w + timers.x * setup.x); // Apply time shift
float TimeFrac = RFrac - 1.0f + ripples.x; // Fade
float RFreq = clamp(TimeFrac * setup.z, 0.0f, 4.0); // Frequency and limit ( 2 = 1 full ripple )
float FinalFactor = saturate(0.7f - RFrac) * ripples.x * sin( RFreq * SSFX_ripples_PI); // Create ripples
// Fade
FinalFactor *= smoothstep(4.0f, 0, RFreq);
// Apply intensity
ripples_N *= FinalFactor * setup.y;
return ripples_N;
}
float2 ssfx_rain_ripples( Texture2D ripples_tex, float2 uvs, float3 setup, float depth)
{
// Falloff
float Dist = 15.0f - depth;
// Discard when depth > 15
if (Dist < 0)
return 0;
// Sample layers
float4 Layer0 = ripples_tex.Sample( smp_linear, uvs );
float4 Layer1 = ripples_tex.Sample( smp_linear, uvs * 0.61f + SSFX_ripples_offset.xy);
float4 Layer2 = ripples_tex.Sample( smp_linear, uvs * 0.87f + SSFX_ripples_offset.zw);
// Process 3 layers of ripples
float2 result = ssfx_process_ripples(Layer0, float3(SSFX_ripples_speed.x * setup.x, setup.yz)) +
ssfx_process_ripples(Layer1, float3(SSFX_ripples_speed.y * setup.x, setup.yz)) +
ssfx_process_ripples(Layer2, float3(SSFX_ripples_speed.z * setup.x, setup.yz));
result *= Dist * 0.0666f; // 0.0 ~ 15.0 To 0.0 ~ 1.0
return clamp(result, -1.0f, 1.0f);
}
@@ -0,0 +1,85 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 12.5
* @ Description: Debanding implementation
* @ Modified time: 2022-11-23 15:47
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "screenspace_common.h"
#include "settings_screenspace_DEBAND.h"
// Internal vars
static const float dband_threshold = 0.039215f;
static const float2 dband_dir_Offsets[4] =
{
float2( 1, 1), // XOX
float2(-1,-1), // O0O
float2(-1, 1), // XOX
float2( 1,-1)
};
void dband_process(inout float3 color, float2 tc, float noise, float2 dir, float loop_step)
{
// Some vars
float3 sampled_pixel;
float3 diff;
float3 avg = 0, max_diff = 0;
float pixel_factor = loop_step / G_DEBANDING_QUALITY;
// Radius for the sample
float radius = noise * (G_DEBANDING_RADIUS * pixel_factor * pixel_factor) * ssfx_pixel_size;
// Sample 4 points arround the original pixel
[unroll (4)]
for (int taps = 0; taps <= 4; taps++)
{
// Sample pixel
sampled_pixel = s_image.Sample(smp_linear, tc + radius * (dir * dband_dir_Offsets[taps])).rgb;
// Add to the average
avg += sampled_pixel;
// Difference between original pixel and sampled pixel
diff = abs(color - sampled_pixel);
// From the 4 samples save the biggest difference
max_diff = max(max_diff, diff);
}
// Normalize average
avg /= 4.0f;
// Difference between original pixel and average
diff = abs(color - avg);
// Calc how much the pixel difference is close to our threshold.
float3 threshold = saturate((1.0 - diff / dband_threshold) * 3.0f) * saturate((1.0 - max_diff / dband_threshold) * 3.0f);
// We use the original pixel or average?
color = lerp(color, avg, threshold);
}
float3 ssfx_debanding(float3 color, float2 tc)
{
// Noise
float db_noise = SSFX_permute(SSFX_permute(SSFX_permute(tc.x) + tc.y) + noise(tc));
// Get random direction [ -1 ~ 1 ]
float2 dir = float2(cos(db_noise), sin(db_noise));
[unroll (G_DEBANDING_QUALITY)]
for (int loop_cnt = 1; loop_cnt <= G_DEBANDING_QUALITY; loop_cnt++)
{
// More variaton for each iteration
db_noise = SSFX_permute(db_noise);
// Process image
dband_process(color, tc, db_noise * 0.0033f, dir, loop_cnt);
}
// Return result
return color;
}
@@ -0,0 +1,84 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 12
* @ Description: DOF Implementation
* @ Modified time: 2022-11-09 01:54
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "check_screenspace.h"
uniform float4 ssfx_wpn_dof_1;
uniform float ssfx_wpn_dof_2;
float3 SSFX_DOF(float2 tc, float3 depth, float3 img)
{
// Full Blur Scene + CA
float CA = float2(4.0f / screen_res.x, 4.0f / screen_res.y);
float3 blur_far = 0;
blur_far.r = s_blur_2.SampleLevel(smp_rtlinear, tc + CA, 0).r;
blur_far.g = s_blur_2.SampleLevel(smp_rtlinear, tc, 0).g;
blur_far.b = s_blur_2.SampleLevel(smp_rtlinear, tc - CA, 0).b;
// Use Depth to adjust blur intensity
float blur_w = lerp(ssfx_wpn_dof_1.w, 0, smoothstep(ssfx_wpn_dof_1.x, ssfx_wpn_dof_1.y, depth.z ) );
blur_w *= depth.z > SKY_EPS; // Don't apply to the sky ( Sky depth = float(0.001) )
float edgeBlur = 0;
// Peripheral vision blur
if (ssfx_wpn_dof_2 > 0)
{
// Vignette to calc blur
float2 mid_uv = tc - float2(0.5f, 0.5f);
edgeBlur = pow(smoothstep(0.0f, saturate(1.0f - ssfx_wpn_dof_2), length(mid_uv)), 1.5f) * 1.33f;
blur_w = saturate(blur_w + edgeBlur) * ssfx_wpn_dof_1.w;
}
// Close blur ( Weapon blur )
if (blur_w > 0)
{
float offset_f = 0.001f;
float ratio = screen_res.y / screen_res.x;
float2 blur_res = float2(blur_w, blur_w) * float2(offset_f * ratio, offset_f);
// Offset pattern
float2 blur_Offsets[8] =
{
float2( -blur_res.x,-blur_res.y), // XOX
float2( blur_res.x,blur_res.y), // OOO
float2( blur_res.x,-blur_res.y), // XOX
float2(-blur_res.x,blur_res.y),
float2( 0,-blur_res.y), // OXO
float2( blur_res.x,0), // XOX
float2( -blur_res.x,0), // OXO
float2(0,blur_res.y)
};
float3 Wpn_Blur = 0;
// Create blur
for (int b = 0; b < 8; b++)
{
Wpn_Blur += s_image.SampleLevel(smp_rtlinear, tc + blur_Offsets[b], 0).rgb;
Wpn_Blur += s_image.SampleLevel(smp_rtlinear, tc + blur_Offsets[b] * 2, 0).rgb;
}
// Normalize blur
img = Wpn_Blur / 16;
// Peripheral vision blur with extra help from s_blur_2
img = lerp(img, blur_far, saturate(0.4f - (1.0f - edgeBlur)));
}
// Far blur ( Reload, Inventory and PDA )
if (ssfx_wpn_dof_1.z > 0)
{
// Let's use s_blur_2 for far blur
img = lerp(img, blur_far, saturate(smoothstep(1.0f, 2.4f, length(depth) ) + int(depth.z <= SKY_EPS)) * ssfx_wpn_dof_1.z);
}
return img;
}
@@ -0,0 +1,60 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 14.4
* @ Description: 2 Layers fog ( Distance + Height )
* @ Modified time: 2024-01-22 05:45
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "settings_screenspace_FOG.h"
float SSFX_HEIGHT_FOG(float3 P, float World_Py, inout float3 color)
{
// Get Sun dir
float3 Sun = saturate(dot(normalize(Ldynamic_dir), -normalize(P)));
// Apply sun color
Sun = lerp(fog_color, Ldynamic_color.rgb, Sun);
// Distance Fog ( Default Anomaly Fog )
float fog = saturate(length(P) * fog_params.w + fog_params.x);
// Height Fog
float fogheight = smoothstep(G_FOG_HEIGHT, -G_FOG_HEIGHT, World_Py) * G_FOG_HEIGHT_INTENSITY;
// Add the height fog to the distance fog
float fogresult = saturate(fog + fogheight * (fog * G_FOG_HEIGHT_DENSITY));
// Blend factor to mix sun color and fog color. Adjust intensity to.
float FogBlend = fogheight * G_FOG_SUNCOLOR_INTENSITY;
// Final fog color
float3 FOG_COLOR = lerp(fog_color, Sun, FogBlend);
// Apply fog to color
color = lerp(color, FOG_COLOR, fogresult);
// Return distance fog.
return fog;
}
float SSFX_FOGGING(float Fog, float World_Py)
{
// Height fog
float fog_height = smoothstep(G_FOG_HEIGHT, -G_FOG_HEIGHT, World_Py) * G_FOG_HEIGHT_INTENSITY;
// Add height fog to default distance fog.
float fog_extra = saturate(Fog + fog_height * (Fog * G_FOG_HEIGHT_DENSITY));
return 1.0f - fog_extra;
}
float SSFX_CALC_FOG(float3 P)
{
float3 WorldP = mul(m_inv_V, float4(P.xyz, 1));
float distance = length(P.xyz);
float fog = saturate(distance * fog_params.w + fog_params.x); // Vanilla fog
float fogheight = smoothstep(G_FOG_HEIGHT, -G_FOG_HEIGHT, WorldP.y) * G_FOG_HEIGHT_INTENSITY; // Height fog
return saturate(fog + fogheight * (fog * G_FOG_HEIGHT_DENSITY));
}
@@ -0,0 +1,64 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 17
* @ Description: HUD Raindrops - Base
* @ Modified time: 2023-08-04 07:23
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
Texture2D s_hud_rain; // Raindrops texture [ x: Fade | y: Normal-Y | z: Normal-X | w: Time Offset ]
#define SSFX_HUD_LIGHTVECTOR float3(0.30f, 0.59f, 0.11f) // Vector to adjust the intensity of the raindrops at night
uniform float4 ssfx_hud_drops_1; // Time, Int, refle, refra
uniform float4 ssfx_hud_drops_2; // Density, Size, Extra Gloss, Gloss
float3 ssfx_process_drops(float4 droplets, float speed, float intensity )
{
// Unpack normal [ -1.0 ~ 1.0 ]
float2 droplets_N = droplets.yz * 2 - 1;
// Apply time
float DropsTime = ssfx_hud_drops_1.x * speed; // Fade * speed factor
float DropsFrac = 1.0f - frac(droplets.w + DropsTime); // Time offset
float DropsInt = saturate((DropsFrac * droplets.x) - ssfx_hud_drops_2.x); // (Time * Fade) - Density
// Apply intensity
DropsInt *= intensity;
droplets_N *= DropsInt;
return float3(droplets_N, DropsInt);
}
// Mapping based on https://iquilezles.org/articles/biplanar/
// Thanks to the chaotic nature of the drops, we can do a very basic planar mapping with 1 sample ( I'm using 2 to add variety to the drops )
float3 ssfx_hud_raindrops( Texture2D drops_tex, float3 p, float uv_scale )
{
// Partial derivatives to reconstruct normal & mapping
float3 d1 = ddx(p);
float3 d2 = ddy(p);
// Recontruct normal
float3 n = abs(normalize(cross(d1, d2)));
// Major axis (in x; yz are following axis)
int3 ma = (n.x > n.y && n.x > n.z) ? int3(0, 1, 2) : // [ yz ] Side
(n.y > n.z) ? int3(1, 2, 0) : // [ zx ] Top
int3(2, 0, 1) ; // [ xy ] Front
// Uvs & partial derivatives
float2 uvs = float2(p[ma.y], p[ma.z]) * ssfx_hud_drops_2.y;
float4 d1_d2 = float4(d1[ma.y], d1[ma.z], d2[ma.y], d2[ma.z]);
// Project + Fetch [ x: Fade | y: Normal-Y | z: Normal-X | w: Time Offset ]
float4 Layer0 = drops_tex.SampleGrad(smp_base, uvs * 15.0f, d1_d2.xy, d1_d2.zw);
float4 Layer1 = drops_tex.SampleGrad(smp_base, (uvs + float2(.23,.46)) * 8.0f, d1_d2.xy, d1_d2.zw);
float w = pow( n[ma.x], 5 );
// Process animation
float3 result = ssfx_process_drops(Layer0, 0.2f, w) + ssfx_process_drops(Layer1, 0.1f, w);
result.xy = clamp(result.xy, -1.0f, 1.0f);
return result;
}
@@ -0,0 +1,54 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 20
* @ Description: LUT shader
* @ Modified time: 2024-01-22 04:12
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
// Settings
#include "settings_screenspace_LUT.h"
// Internal --
#define LUT_GROUPS max(1, G_CELLS_GROUPS)
#define TEXEL_SIZE float2(1.0f / G_LUT_SIZE_W, 1.0f / (G_CELLS_SIZE * LUT_GROUPS))
#define TEXEL_HALF float2(TEXEL_SIZE.xy / 2.0f)
#define TEXEL_FIX TEXEL_SIZE.y * LUT_GROUPS
uniform float4 ssfx_lut;
float3 ssfx_lut_pp(float3 base_col)
{
// Prepare LUT UVs
float3 cells = base_col * G_CELLS_SIZE - base_col;
float lut_frac = frac(cells.b);
cells.rg = TEXEL_HALF + cells.rg * TEXEL_SIZE;
cells.r += (cells.b - lut_frac) * TEXEL_FIX;
// Final LUT UVs
float4 uvs = float4(cells.rg, cells.r + TEXEL_FIX, cells.g);
// Group offset
float2 grp_offset = float2(0.0, ssfx_lut.y / LUT_GROUPS);
// Sample LUTs
float3 lut_col = lerp( s_lut_atlas.Sample(smp_linear, uvs.xy + grp_offset).rgb,
s_lut_atlas.Sample(smp_linear, uvs.zw + grp_offset).rgb,
lut_frac);
#ifdef G_ADVANCE_TRANSITION
// Group2 offset
grp_offset = float2(0.0, ssfx_lut.z / LUT_GROUPS);
// Sample transition LUTs
float3 SecondLUT = lerp(s_lut_atlas.Sample(smp_linear, uvs.xy + grp_offset).rgb,
s_lut_atlas.Sample(smp_linear, uvs.zw + grp_offset).rgb,
lut_frac);
lut_col = lerp(lut_col, SecondLUT, ssfx_lut.w);
#endif
return lerp(base_col.rgb, lut_col.rgb, ssfx_lut.x);
}
@@ -0,0 +1,174 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 21
* @ Description: SSR Ray-march
* @ Modified time: 2024-06-03 09:42
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#ifndef SSFX_SSR_QUALITY
#define SSFX_SSR_QUALITY 0
#endif
#include "screenspace_common.h"
#include "settings_screenspace_SSR.h"
uniform float4 ssr_setup; // x: SSR Resolution | y: Blur Intensity | z: Temporal Intensity
uniform float4 ssfx_ssr_2; // x: Intensity | y: Sky Intensity | z: Weapon Intensity | w: Max Weapon Intensity
uniform float4 ssfx_is_underground;
Texture2D blue_noise;
static const int2 q_ssr_steps[6] =
{
int2(8,72),
int2(16,36),
int2(24,18),
int2(32,5),
int2(48,1),
int2(64,1),
};
float4 SSFX_ssr_fast_ray(float3 ray_start_vs, float3 ray_dir_vs, float2 tc, float HudMask, inout float2 noise, uint iSample : SV_SAMPLEINDEX)
{
float2 sky_tc = 0;
float2 behind_hit = 0;
// Noise to "improve" consistency between steps
float2 uv_noise = tc + timers.x * (ssr_setup.w > 0);
uv_noise.x *= screen_res.x / screen_res.y;
noise = blue_noise.Sample(smp_linear, uv_noise).x * ssr_setup.w * 0.5f * HudMask;
noise = noise * 2 - 1;
// Initialize Ray
RayTrace ssr_ray = SSFX_ray_init(ray_start_vs, ray_dir_vs, 150, q_ssr_steps[SSFX_SSR_QUALITY].x, 1.0f - noise);
// Save the original step.x
float ori_x = ssr_ray.r_step.x;
// Depth from the start of the ray
float ray_depthstart = SSFX_get_depth(ssr_ray.r_start, iSample);
float2 ray_check = 0;
// Ray-march
[unroll (q_ssr_steps[SSFX_SSR_QUALITY].x)]
for (int i = 0; i < q_ssr_steps[SSFX_SSR_QUALITY].x; i++)
{
// Ray out of screen...
if (ssr_ray.r_pos.y < 0.0f || ssr_ray.r_pos.y > 1.0f)
return 0;
// Trick for the horizontal out of bounds. Mirror border of the screen.
if (ssr_ray.r_pos.x < 0.0f || ssr_ray.r_pos.x > 1.0f)
{
ssr_ray.r_pos -= ssr_ray.r_step; // Step back
ssr_ray.r_step.x = -ssr_ray.r_step.x; // Invert Horizontal
ssr_ray.r_pos += ssr_ray.r_step; // Step
}
// Ray intersect check
ray_check = SSFX_ray_intersect(ssr_ray, iSample);
// Sampled depth is not weapon or sky ( SKY_EPS float(0.001) )
bool NoWpnSky = ray_check.y > 1.3f;
// Disable weapon and sky
ray_check.x *= NoWpnSky;
// Return if ray is not reflecting backward
if (ray_check.x > 0)
{
if (ray_check.x <= q_ssr_steps[SSFX_SSR_QUALITY].y)
return float4(ssr_ray.r_pos, ray_check.y, 0);
#if SSFX_SSR_QUALITY > 2 // 1 Binary Search step in higher quality settigns ( Quality 4 & 5 )
// Current ray pos & step to restore later...
float4 prev_step = 0;
prev_step.xy = ssr_ray.r_pos;
prev_step.zw = ssr_ray.r_step;
// Half and flip
ssr_ray.r_step *= -0.5f;
// Step ray
ssr_ray.r_pos += ssr_ray.r_step;
// Ray intersect check
ray_check = SSFX_ray_intersect(ssr_ray, iSample);
// Depth test... Conditions to use as reflections...
if (abs(ray_check.x) <= 1.25f)
return float4(ssr_ray.r_pos, ray_check.y, 0);
// Restore previous ray position & step
ssr_ray.r_pos = prev_step.xy;
ssr_ray.r_step = prev_step.zw;
#endif
}
else
{
// TexCoor for sky ( Used to fade "SSFX_calc_SSR_fade" )
if (ray_check.y <= SKY_EPS)
sky_tc = ssr_ray.r_pos;
behind_hit = ssr_ray.r_pos;
// Reset or keep depending on... ( > 1.3f = no interaction with weapons and sky )
behind_hit *= (ray_depthstart - 2.0f < ray_check.y) && NoWpnSky;
}
// Step the ray
ssr_ray.r_pos += ssr_ray.r_step;
}
return float4(behind_hit, ray_check.y, sky_tc.y);
}
void SSFX_ScreenSpaceReflections(float2 tc, float4 P, float3 N, float4 gloss, inout float4 color, float HudMask, inout float2 noise, uint iSample : SV_SAMPLEINDEX)
{
// Note: Distance falloff on "rain_patch_normal.ps"
// Material condition
bool m_terrain = abs(P.w - 0.95f) <= 0.02f;
// Calc reflection bounce
float3 inVec = normalize(P.xyz); // Incident
float3 reVec = reflect(inVec , N); // Reflected
float4 hit_uv = 0;
// Calc SSR ray. Discard low reflective pixels
if (gloss.w > 0.02f)
hit_uv = SSFX_ssr_fast_ray(P.xyz, reVec, tc, HudMask, noise, iSample);
float3 reflection = gloss.rgb;
// Valid UV coor? SSFX_trace_ssr_ray return 0.0f if uv is out of bounds or sky.
if (all(hit_uv.xy))
{
// Get scene reflection
float3 scene = SSFX_get_image(hit_uv.xy, iSample);
// Vertical screen fade
float HitFade = saturate(hit_uv.y * G_SSR_VERTICAL_SCREENFADE);
// Mix base reflection ( skybox if m_terrain ) with ray reflection
reflection.rgb = lerp(reflection * m_terrain, scene, HitFade);
}
else
{
// Keep skybox if m_terrain
float ray_fade = saturate(saturate(hit_uv.w * G_SSR_VERTICAL_SCREENFADE) + m_terrain);
reflection *= ray_fade;
}
color.rgb = reflection;
}
@@ -0,0 +1,142 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 22
* @ Description: SSS implementation
* @ Modified time: 2024-11-25 02:19
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
uniform float4 ssfx_sss; // Dir Len, Omni Len, Grass Shadows, -
#include "screenspace_common.h"
#include "settings_screenspace_SSS.h"
Texture2D s_hud_mask;
float SSFX_ScreenSpaceShadows(float4 P, float3 N, float2 tc, float HudMask, uint iSample)
{
// Weapon Mask
bool IsHUD = HudMask <= 0;
float pLen = length(P.xyz);
// Distance Factor
float DFactor = saturate((pLen - 80) * 0.01f);
// Adjust Settings for weapons and scene.
float ray_detail = lerp(G_SSS_DETAIL, 0.05f, pLen * 0.02f);
float ray_thick = lerp(0.2f, 10, DFactor);
float ray_len = lerp(1.0, 20, DFactor);
ray_len *= saturate(P.z); // Limit the ray_len to avoid issues when surfaces are extremely close
if (IsHUD)
{
ray_detail = 0;
ray_len = G_SSS_WEAPON_LENGTH;
ray_thick = 1.0f;
}
RayTrace sss_ray = SSFX_ray_init(P, -L_sun_dir_e, ray_len * ssfx_sss.x, SSFX_SSS_DIR_QUALITY, hash12(tc * 100 + timers.xx * 100));
[unroll (SSFX_SSS_DIR_QUALITY)]
for (int i = 0; i < SSFX_SSS_DIR_QUALITY; i++)
{
// Break the march if ray go out of screen...
if (!SSFX_is_valid_uv(sss_ray.r_pos))
return 1;
// Sample current ray pos ( x = difference | y = sample depth | z = current ray len )
float3 depth_ray = SSFX_ray_intersect(sss_ray, iSample);
// Check depth difference
float diff = depth_ray.x;
// No Sky
if (depth_ray.y <= SKY_EPS)
return 1;
// Disable weapons at some point to avoid wrong shadows on the ground
if (!IsHUD)
diff *= depth_ray.y >= 1.0f;
// Negative: Ray is closer to the camera ( not occluded )
// Positive: Ray is beyond the depth sample ( occluded )
if (diff > ray_detail && diff < ray_thick)
return saturate(1.0f - G_SSS_INTENSITY);
// Step the ray + Noise
sss_ray.r_pos += sss_ray.r_step * (1.0f + hash12((tc * 100) + timers.xx * 100));
}
// None
return 1;
}
float SSFX_ScreenSpaceShadows_Point(float4 P, float2 tc, float3 LightPos, float HudMask, uint iSample)
{
// Light vector
float3 L_dir = -normalize(P.xyz - LightPos);
// Material conditions...
bool mat_flora = abs(P.w - MAT_FLORA) <= 0.04f;
// Weapon Mask
bool IsHUD = HudMask <= 0;
// Adjust Settings for weapons and scene.
float ray_detail = G_SSS_DETAIL;
float ray_thick = 0.2f;
float ray_len = 0.5f;
// Grass overwrite.
if (IsHUD)
{
ray_thick = 1.0f;
ray_len = 0.06f;
}
else
{
if (mat_flora)
{
ray_thick = 10.0f;
ray_len = 0.5f;
}
}
RayTrace sss_ray = SSFX_ray_init(P, L_dir, ray_len * ssfx_sss.y, SSFX_SSS_OMNI_QUALITY, hash12(tc * 100 + timers.xx * 100));
[unroll (SSFX_SSS_OMNI_QUALITY)]
for (int i = 0; i < SSFX_SSS_OMNI_QUALITY; i++)
{
// Break the march if ray go out of screen...
if (!SSFX_is_valid_uv(sss_ray.r_pos))
return 1;
// Sample current ray pos ( x = difference | y = sample depth | z = current ray len )
float3 depth_ray = SSFX_ray_intersect(sss_ray, iSample);
// Check depth difference
float diff = depth_ray.x;
// No Sky
if (depth_ray.y <= SKY_EPS)
return 1;
// Disable weapons at some point to avoid wrong shadows on the ground
if (!IsHUD)
diff *= depth_ray.y >= 1.0f;
// Negative: Ray is closer to the camera ( not occluded )
// Positive: Ray is beyond the depth sample ( occluded )
if (diff > ray_detail && diff < ray_thick)
return 1.0f - saturate(G_SSS_INTENSITY - smoothstep( SSFX_SSS_OMNI_QUALITY * 0.5f, SSFX_SSS_OMNI_QUALITY + 1, i));
// Step the ray
sss_ray.r_pos += sss_ray.r_step * (1.0f + hash12((tc * 100) + timers.xx * 100));
}
return 1;
}
@@ -0,0 +1,123 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 22
* @ Description: Water implementation
* @ Modified time: 2024-11-16 07:21
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
#include "screenspace_common.h"
#include "settings_screenspace_WATER.h"
uniform float3 eye_direction;
static const int2 q_steps[5] =
{
int2(8,3),
int2(16,2),
int2(24,2),
int2(32,2),
int2(64,1)
};
float3 SSFX_ssr_water_ray(float3 ray_start_vs, float3 ray_dir_vs, float noise, out float HitDepth, float2 tc, uint iSample : SV_SAMPLEINDEX)
{
// Some vars to use later...
float4 prev_step;
int prev_sign;
float3 behind_hit = 0;
HitDepth = 0;
float RayThick = clamp( 48.0f / q_steps[SSFX_WATER_QUALITY].x, 1.0f, 3.0f);
// Initialize Ray
RayTrace ssr_ray = SSFX_ray_init(ray_start_vs, ray_dir_vs, 150, q_steps[SSFX_WATER_QUALITY].x, noise);
// Horizontal stretch to avoid borders
float2 stretch_uv = 1.0f - smoothstep(0.9f, 1.0f, float2(tc.x, 1.0 - tc.x));
// Apply stretch
ssr_ray.r_step.x *= saturate(stretch_uv.x * stretch_uv.y + saturate(eye_direction.y * 3.0f));
// Adjust the starting Point
ssr_ray.r_pos = ssr_ray.r_start + ssr_ray.r_step * noise;
// Depth from the start of the ray
float ray_depthstart = SSFX_get_depth(ssr_ray.r_start, iSample);
// Ray-march
[unroll (q_steps[SSFX_WATER_QUALITY].x)]
for (int st = 1; st <= q_steps[SSFX_WATER_QUALITY].x; st++)
{
// Ray out of screen...
if (!SSFX_is_valid_uv(ssr_ray.r_pos.xy))
return 0;
// Ray intersect check ( x = difference | y = depth sample )
float3 ray_check = SSFX_ray_intersect(ssr_ray, iSample);
HitDepth = ray_check.y;
// Sampled depth is not weapon or sky ( SKY_EPS float(0.001) )
bool NoWpnSky = ray_check.y > 1.3f;
// Don't want interaction with weapons or sky
ray_check.x *= NoWpnSky;
// Depth difference positive...
if (ray_check.x > 0)
{
// Conditions to use as reflection...
if (ray_check.x <= RayThick || (ray_depthstart + 40.0f < ray_check.y))
return float3(ssr_ray.r_pos, ray_check.y);
// Current ray pos & step to use later...
prev_step.xy = ssr_ray.r_pos;
prev_step.zw = ssr_ray.r_step;
prev_sign = -1;
// Binary Search
for (int x = 0; x < q_steps[SSFX_WATER_QUALITY].y; x++)
{
// Half and flip depending on depth difference sign
if (sign(ray_check.x) != prev_sign)
{
ssr_ray.r_step *= -0.5f;
prev_sign = sign(ray_check.x);
}
// Step ray
ssr_ray.r_pos += ssr_ray.r_step;
// Ray intersect check
ray_check = SSFX_ray_intersect(ssr_ray, iSample);
// Depth test... Conditions to use as reflections...
if (abs(ray_check.x) <= RayThick)
return float3(ssr_ray.r_pos, ray_check.y);
}
// Restore previous ray position & step
ssr_ray.r_pos = prev_step.xy;
ssr_ray.r_step = prev_step.zw;
}
else
{
// Sample behind... Let's use this coor to fill...
behind_hit = float3(ssr_ray.r_pos, ray_check.y);
// Reset or keep depending on... ( > 1.3f = no interaction with weapons and sky )
behind_hit *= (ray_depthstart - 2.0f < ray_check.y) && NoWpnSky;
}
// Pass through condition
bool PTh = (!NoWpnSky && ray_check.y > 0.01f && st > q_steps[SSFX_WATER_QUALITY].x * 0.4f);
// Step ray... Try to pass through closer objects ( Like weapons and sights )
ssr_ray.r_pos += ssr_ray.r_step * (1.0f + 2.5f * PTh);
}
return behind_hit;
}
@@ -0,0 +1,146 @@
/**
* @ Version: SCREEN SPACE SHADERS - UPDATE 19
* @ Description: Wind Main File
* @ Modified time: 2023-12-23 16:05
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
uniform float4 wind_params;
uniform float4 ssfx_wsetup_grass; // Anim Speed - Turbulence - Push - Wave
uniform float4 ssfx_wsetup_trees; // Branches Speed - Trunk Speed - Bending - Min Wind Speed
uniform float4 ssfx_wind_anim;
Texture2D s_waves;
sampler smp_linear2;
struct wind_setup
{
float2 direction;
float speed;
float sqrt_speed;
float trees_animspeed;
float trees_trunk_animspeed;
float trees_bend;
float grass_animspeed;
float grass_turbulence;
float grass_push;
float grass_wave;
};
wind_setup ssfx_wind_setup()
{
wind_setup wsetup;
// Direction. Radians to Vector
float r = -wind_params.x + 1.57079f;
wsetup.direction = float2(cos(r),sin(r));
// Wind Speed
wsetup.speed = max(ssfx_wsetup_trees.w, saturate(wind_params.y * 0.001));
wsetup.sqrt_speed = saturate(sqrt(wsetup.speed * 1.66f));
// Setup
wsetup.grass_animspeed = ssfx_wsetup_grass.x;
wsetup.grass_turbulence = ssfx_wsetup_grass.y;
wsetup.grass_push = ssfx_wsetup_grass.z;
wsetup.grass_wave = ssfx_wsetup_grass.w;
wsetup.trees_animspeed = ssfx_wsetup_trees.x;
wsetup.trees_trunk_animspeed = ssfx_wsetup_trees.y;
wsetup.trees_bend = ssfx_wsetup_trees.z;
return wsetup;
}
#ifdef SSFX_WIND_ISGRASS
// Flow Map - X: X-Anim | Y: Z-Anim | Z: Wind Wave | W : Detail
float3 ssfx_wind_grass(float3 pos, float H, wind_setup W)
{
// Height Limit. ( Add stiffness to tall grass )
float HLimit = saturate(H * H - 0.01f) * saturate(1.0f - H * 0.1f);
// Offset animation
float2 Offset = -ssfx_wind_anim.xy * W.grass_animspeed;
// Sample ( The scale defines the detail of the motion )
float3 Flow = s_waves.SampleLevel( smp_linear2, (pos.xz + Offset) * 0.018f, 0);
// Grass Motion ( -1.0 ~ 1.0 ). Turbulence.
float2 GrassMotion = (Flow.xy * 2.0f - 1.0f) * W.grass_turbulence;
// Apply wind direction and flow. Wind push.
float2 WindDir = Flow.z * W.direction * W.grass_push;
// Add everything and apply height limit
float3 Final = float3(GrassMotion.x + WindDir.x, Flow.z * W.grass_wave, GrassMotion.y + WindDir.y) * W.speed * HLimit;
return Final;
}
#else // Non Grass
float3 ssfx_wind_tree_trunk(float3 pos, float Tree_H, wind_setup W)
{
// Phase ( from matrix ) + Offset
float Phase = m_xform._24 + ssfx_wind_anim.z * W.trees_trunk_animspeed;
// Trunk wave
float TWave = (cos(Phase) * sin(Phase * 5.0f) + 0.5f) * W.trees_bend;
// Wind speed
float WSpeed = saturate(W.sqrt_speed * 1.5f);
// Base wind speed displacement
float Base_Bend = WSpeed * 0.006f * saturate(1.0f - Tree_H * 0.005f);
// Intensity ( Squared height )
Base_Bend *= Tree_H * Tree_H * TWave * WSpeed;
// Apply direction
float2 Final = Base_Bend.xx * W.direction;
return float3(Final, saturate((TWave + 1.0f) * 0.5));
}
float3 ssfx_wind_tree_branches(float3 pos, float Tree_H, float tc_y, wind_setup W)
{
// UV Offset
float2 Offset = -ssfx_wind_anim.xy * W.trees_animspeed;
// Sample flow map
float3 Flow = s_waves.SampleLevel( smp_linear2, (pos.xz + Offset) * 0.02f, 0);
// Sample 2, slower and detailed
float3 Flow2 = s_waves.SampleLevel( smp_linear2, (pos.xz + Offset * 0.2f) * 0.1f, 0);
// Branch motion [ -1.0 ~ 1.0 ]
float3 branchMotion = float3(Flow.x, Flow2.y, Flow.y) * 2.0f - 1.0f;
// Trunk position
float3 Trunk = ssfx_wind_tree_trunk(pos, Tree_H, W);
// Gust from trunk data.
branchMotion.xz *= Trunk.z * clamp(Tree_H * 0.1f, 1.0f, 2.5f);
// Add wind direction
branchMotion.xz += Flow2.z * W.direction;
// Add wind gust
branchMotion.y *= saturate(Tree_H * 0.1f);
// Everything is limited by the UV and wind speed
branchMotion *= (1.0f - tc_y) * W.speed;
// Add trunk animation
branchMotion.xz += Trunk.xy;
return branchMotion;
}
#endif

Some files were not shown because too many files have changed in this diff Show More