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

193 lines
5.5 KiB
PostScript

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