diff --git a/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml b/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
index 9c9978f622..560fe4ca8f 100644
--- a/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
+++ b/Game/Resources_SoC_1.0006/gamedata/config/ui/ui_mm_opt.xml
@@ -470,7 +470,7 @@
ui_mm_ao_mode
-
+
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES.H b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES.H
new file mode 100644
index 0000000000..f1d4a1d47b
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES.H
@@ -0,0 +1,400 @@
+//=================================================================================================
+// ACEScg color space and ACEScc log space transformations and Reference Rendering Transform for sRGB monitors
+// Based on code by Stephen Hill (@self_shadow), Unity Technologies and others
+//=================================================================================================
+#define USE_ACES // Use ACES style color management
+//=================================================================================================
+static const float PI = 3.14159265;
+static const float HALF_MIN = 6.10352e-5f;
+static const float HALF_MAX = 65504;
+static const float ACEScc_MAX = 1.4679964;
+static const float ACEScc_MIDGRAY = 0.4135884;
+// static const float3 LUMINANCE_VECTOR = float3(0.213, 0.715, 0.072);
+
+static const float RRT_GLOW_GAIN = 0.05;
+static const float RRT_GLOW_MID = 0.08;
+
+static const float RRT_RED_SCALE = 0.82;
+static const float RRT_RED_PIVOT = 0.03;
+static const float RRT_RED_HUE = 0.0;
+static const float RRT_RED_WIDTH = 135.0;
+
+static const float RRT_SAT_FACTOR = 0.96;
+
+// static const float CINEMA_WHITE = 48.0;
+// static const float CINEMA_BLACK = CINEMA_WHITE / 2400.0;
+static const float ODT_SAT_FACTOR = 0.93;
+
+static const float DIM_SURROUND_GAMMA = 0.9811;
+
+//=================================================================================================
+// Color transformation matrices
+//
+
+static const float3x3 sRGB_2_AP0 = {0.4397010, 0.3829780, 0.1773350, 0.0897923, 0.8134230, 0.0967616, 0.0175440, 0.1115440, 0.8707040};
+
+static const float3x3 AP0_2_sRGB = {
+ 2.52169, -1.13413, -0.38756, -0.27648, 1.37272, -0.09624, -0.01538, -0.15298, 1.16835,
+};
+
+static const float3x3 sRGB_2_AP1 = {0.61319, 0.33951, 0.04737, 0.07021, 0.91634, 0.01345, 0.02062, 0.10957, 0.86961};
+
+static const float3x3 AP1_2_sRGB = {
+ 1.70505, -0.62179, -0.08326, -0.13026, 1.14080, -0.01055, -0.02400, -0.12897, 1.15297,
+};
+
+static const float3x3 AP0_2_AP1 = {1.4514393161, -0.2365107469, -0.2149285693, -0.0765537734, 1.1762296998, -0.0996759264, 0.0083161484, -0.0060324498, 0.9977163014};
+
+static const float3x3 AP1_2_AP0 = {0.6954522414, 0.1406786965, 0.1638690622, 0.0447945634, 0.8596711185, 0.0955343182, -0.0055258826, 0.0040252103, 1.0015006723};
+
+static const float3 AP1_RGB2Y = float3(0.272229, 0.674082, 0.0536895);
+/*
+static const float3x3 RRT_SAT_MAT =
+{
+ 0.9708890, 0.0269633, 0.00214758,
+ 0.0108892, 0.9869630, 0.00214758,
+ 0.0108892, 0.0269633, 0.96214800
+};
+
+static const float3x3 ODT_SAT_MAT =
+{
+ 0.949056, 0.0471857, 0.00375827,
+ 0.019056, 0.9771860, 0.00375827,
+ 0.019056, 0.0471857, 0.93375800
+};
+*/
+static const float3x3 AP1_2_XYZ_MAT = {0.6624541811, 0.1340042065, 0.1561876870, 0.2722287168, 0.6740817658, 0.0536895174, -0.0055746495, 0.0040607335, 1.0103391003};
+
+static const float3x3 XYZ_2_AP1_MAT = {1.6410233797, -0.3248032942, -0.2364246952, -0.6636628587, 1.6153315917, 0.0167563477, 0.0117218943, -0.0082844420, 0.9883948585};
+
+//=================================================================================================
+// Color space transformations
+//
+
+float3 sRGB_to_ACES(float3 x) { return mul(sRGB_2_AP0, x); }
+
+float3 ACES_to_sRGB(float3 x) { return mul(AP0_2_sRGB, x); }
+
+float3 sRGB_to_ACEScg(float3 x) { return mul(sRGB_2_AP1, x); }
+
+float3 ACEScg_to_sRGB(float3 x) { return mul(AP1_2_sRGB, x); }
+
+float3 ACEScg_to_ACES(float3 x) { return mul(AP1_2_AP0, x); }
+
+float3 ACES_to_ACEScg(float3 x) { return mul(AP0_2_AP1, x); }
+
+float lin_to_ACEScc(float x)
+{
+ return (x < 0.00003051757) ? (log2(0.00001525878 + x * 0.5) + 9.72) / 17.52 : (log2(x) + 9.72) / 17.52;
+ /*
+ if (x <= 0)
+ return -0.3584474886;
+ else if (x < pow(2, -15))
+ return (log2( pow(2, -16) + x * 0.5) + 9.72) / 17.52;
+ else
+ return (log2(x) + 9.72) / 17.52;
+ */
+}
+
+float ACEScc_to_lin(float x)
+{
+ return (x < -0.3013698630) ? (exp2(x * 17.52 - 9.72) - 0.00001525878) * 2 : exp2(x * 17.52 - 9.72);
+ /*
+ if (x < -0.3013698630)
+ return (pow( 2, x * 17.52 - 9.72) - pow( 2, -16)) * 2;
+ else
+ return pow( 2, x * 17.52 - 9.72);
+ */
+}
+
+float3 lin_to_ACEScc(float3 x)
+{
+ x = clamp(x, 0, HALF_MAX);
+ x = float3(lin_to_ACEScc(x.r), lin_to_ACEScc(x.g), lin_to_ACEScc(x.b));
+ return x;
+}
+
+float3 ACEScc_to_lin(float3 x)
+{
+ x = float3(ACEScc_to_lin(x.r), ACEScc_to_lin(x.g), ACEScc_to_lin(x.b));
+ x = clamp(x, 0, HALF_MAX);
+ return x;
+}
+
+float3 ACES_to_ACEScc(float3 x)
+{
+ x = ACES_to_ACEScg(x);
+ x = lin_to_ACEScc(x);
+ return x;
+}
+
+float3 ACEScc_to_ACES(float3 x)
+{
+ x = ACEScc_to_lin(x);
+ x = ACEScg_to_ACES(x);
+ return x;
+}
+
+float3 ACEScg_to_ACEScc(float3 x)
+{
+ x = lin_to_ACEScc(x);
+ return x;
+}
+
+float3 ACEScc_to_ACEScg(float3 x)
+{
+ x = ACEScc_to_lin(x);
+ return x;
+}
+
+//=================================================================================================
+// Various RRT approximations
+//
+float3 RRTAndODTFit(float3 x)
+{
+ x *= 1.8;
+ float3 a = x * (x + 0.0245786) - 0.000090537;
+ float3 b = x * (0.983729 * x + 0.4329510) + 0.238081;
+ return (a / b);
+}
+
+float3 ACESFilm(float3 x)
+{
+ x *= 0.7;
+ float a = 2.51f;
+ float b = 0.03f;
+ float c = 2.43f;
+ float d = 0.59f;
+ float e = 0.14f;
+ return ((x * (a * x + b)) / (x * (c * x + d) + e));
+}
+
+float3 ACESUnity(float3 x)
+{
+ x *= 1.4;
+ // Luminance fitting of *RRT.a1.0.3 + ODT.Academy.RGBmonitor_100nits_dim.a1.0.3*.
+ // https://github.com/colour-science/colour-unity/blob/master/Assets/Colour/Notebooks/CIECAM02_Unity.ipynb
+ // RMSE: 0.0012846272106
+ const float a = 278.5085;
+ const float b = 10.7772;
+ const float c = 293.6045;
+ const float d = 88.7122;
+ const float e = 80.6889;
+ return (x * (a * x + b)) / (x * (c * x + d) + e);
+}
+
+//=================================================================================================
+// Display tranformations
+//
+float3 ACES_IDT(float3 color)
+{
+ float3 aces = SRGBToLinear(color);
+ aces = sRGB_to_ACES(aces);
+ return aces;
+}
+
+float3 XYZ_2_xyY(float3 XYZ)
+{
+ float divisor = max(dot(XYZ, (1.0).xxx), 1e-4);
+ return float3(XYZ.xy / divisor, XYZ.y);
+}
+
+float3 xyY_2_XYZ(float3 xyY)
+{
+ float m = xyY.z / max(xyY.y, 1e-4);
+ float3 XYZ = float3(xyY.xz, (1.0 - xyY.x - xyY.y));
+ XYZ.xz *= m;
+ return XYZ;
+}
+
+float3 darkSurround_to_dimSurround(float3 linearCV)
+{
+ float3 XYZ = mul(AP1_2_XYZ_MAT, linearCV);
+
+ float3 xyY = XYZ_2_xyY(XYZ);
+ xyY.z = clamp(xyY.z, 0.0, HALF_MAX);
+ xyY.z = pow(xyY.z, DIM_SURROUND_GAMMA);
+ XYZ = xyY_2_XYZ(xyY);
+
+ return mul(XYZ_2_AP1_MAT, XYZ);
+}
+
+float3 ACES_ODT(float3 oces)
+{
+ // Apply gamma adjustment to compensate for dim surround
+ oces = darkSurround_to_dimSurround(oces);
+
+ // martix for ODT
+ // oces = mul(ODT_SAT_MAT, oces);
+ oces = lerp(dot(oces, AP1_RGB2Y).xxx, oces, ODT_SAT_FACTOR.xxx);
+
+ oces = ACEScg_to_sRGB(oces);
+
+ oces = LinearTosRGB(oces);
+ return saturate(oces);
+}
+
+//=================================================================================================
+// Reference Render Transform and Output Display Transform
+// features glow module
+
+float rgb_2_saturation(float3 x)
+{
+ const float TINY = 1e-4;
+ float mi = min(min(x.r, x.g), x.b);
+ float ma = max(max(x.r, x.g), x.b);
+ return (max(ma, TINY) - max(mi, TINY)) / max(ma, 1e-2);
+}
+
+float rgb_2_yc(float3 x)
+{
+ const float ycRadiusWeight = 1.75;
+
+ // Converts RGB to a luminance proxy, here called YC
+ // YC is ~ Y + K * Chroma
+ // Constant YC is a cone-shaped surface in RGB space, with the tip on the
+ // neutral axis, towards white.
+ // YC is normalized: RGB 1 1 1 maps to YC = 1
+ //
+ // ycRadiusWeight defaults to 1.75, although can be overridden in function
+ // call to rgb_2_yc
+ // ycRadiusWeight = 1 -> YC for pure cyan, magenta, yellow == YC for neutral
+ // of same value
+ // ycRadiusWeight = 2 -> YC for pure red, green, blue == YC for neutral of
+ // same value.
+
+ float r = x.x;
+ float g = x.y;
+ float b = x.z;
+ float chroma = sqrt(b * (b - g) + g * (g - r) + r * (r - b));
+ return (b + g + r + ycRadiusWeight * chroma) / 3.0;
+}
+
+float sigmoid_shaper(float x)
+{
+ // Sigmoid function in the range 0 to 1 spanning -2 to +2.
+
+ float t = max(1.0 - abs(x / 2.0), 0.0);
+ float y = 1.0 + sign(x) * (1.0 - t * t);
+
+ return y / 2.0;
+}
+
+float glow_fwd(float ycIn, float glowGainIn, float glowMid)
+{
+ float glowGainOut;
+
+ if (ycIn <= 2.0 / 3.0 * glowMid)
+ glowGainOut = glowGainIn;
+ else if (ycIn >= 2.0 * glowMid)
+ glowGainOut = 0.0;
+ else
+ glowGainOut = glowGainIn * (glowMid / ycIn - 1.0 / 2.0);
+
+ return glowGainOut;
+}
+
+float rgb_2_hue(float3 x)
+{
+ // Returns a geometric hue angle in degrees (0-360) based on RGB values.
+ // For neutral colors, hue is undefined and the function will return a quiet NaN value.
+ float hue;
+ if (x.x == x.y && x.y == x.z)
+ hue = 0.0; // RGB triplets where RGB are equal have an undefined hue
+ else
+ hue = (180.0 / PI) * atan2(sqrt(3.0) * (x.y - x.z), 2.0 * x.x - x.y - x.z);
+
+ if (hue < 0.0)
+ hue = hue + 360.0;
+
+ return hue;
+}
+
+float center_hue(float hue, float centerH)
+{
+ float hueCentered = hue - centerH;
+ if (hueCentered < -180.0)
+ hueCentered = hueCentered + 360.0;
+ else if (hueCentered > 180.0)
+ hueCentered = hueCentered - 360.0;
+ return hueCentered;
+}
+
+float3 ACES_RRT(float3 aces)
+{
+ // --- Glow module --- //
+ float saturation = rgb_2_saturation(aces);
+ float ycIn = rgb_2_yc(aces);
+ float s = sigmoid_shaper((saturation - 0.4) / 0.2);
+ float addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);
+ // addedGlow = (addedGlow > 1) ? 100 : 1; //check glow region
+ aces *= addedGlow;
+
+ // --- Red modifier --- //
+ float hue = rgb_2_hue(aces);
+ float centeredHue = center_hue(hue, RRT_RED_HUE);
+ float hueWeight;
+ {
+ // hueWeight = cubic_basis_shaper(centeredHue, RRT_RED_WIDTH);
+ hueWeight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH));
+ hueWeight *= hueWeight;
+ }
+ aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE);
+
+ // --- ACES to RGB rendering space --- //
+ aces = clamp(aces, 0.0, HALF_MAX);
+ aces = ACES_to_ACEScg(aces);
+
+ // clamp to float range and within gamut
+ float3 rgbPre = clamp(aces, 0.0, HALF_MAX);
+
+ // --- Global desaturation --- //
+ // rgbPre = mul(RRT_SAT_MAT, rgbPre);
+ rgbPre = lerp(dot(rgbPre, AP1_RGB2Y).xxx, rgbPre, RRT_SAT_FACTOR.xxx);
+
+ float3 rgbPost;
+
+ // various ACES RRT approximations
+
+ // Stephen Hill - clips blacks?
+ // rgbPost = RRTAndODTFit(rgbPre);
+
+ // Krzysztof Narkowicz
+ // rgbPost = ACESFilm(rgbPre);
+
+ // Unity
+ rgbPost = ACESUnity(rgbPre);
+
+ float3 oces = rgbPost;
+
+ return oces;
+}
+
+//=================================================================================================
+// Look Modification Transform
+// global modifiers to the image before tonemapping
+// blue highlight fix is included, however it is for AP0, so using it requires 3 matrix tranforms
+//
+// load custom behaviours from another file
+#include "ACES_LMT.h"
+
+//=================================================================================================
+// ACES implementation
+// ACEScg is the main color space, similar to the implementation in UE4
+//
+float3 ACES(float3 color)
+{
+ // Input Display Transform into ACEScg (linear gamma space with AP1 primaries)
+ float3 aces = ACES_IDT(color);
+
+ // Look Modification Transform (preset color modifications)
+ ACES_LMT(aces);
+
+ // Reference Render Transform (tonemapping including the global desaturation but without the 'glow module')
+ float3 oces = ACES_RRT(aces);
+
+ // Output Display Tranform into sRGB (linear gamma space with sRGB primaries)
+ oces = ACES_ODT(oces);
+
+ return oces;
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_Color_Grading.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_Color_Grading.h
new file mode 100644
index 0000000000..1493dfb7c1
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_Color_Grading.h
@@ -0,0 +1,52 @@
+//=================================================================================================
+// Color grading - Color Decision List
+// ACEScc compatible CDL https://github.com/ampas/aces-dev/blob/518c27f577e99cdecfddf2ebcfaa53444b1f9343/documents/LaTeX/S-2014-003/appendixB.tex#L1
+//=================================================================================================
+
+float ASC_CDL(float x, float Slope, float Offset, float Power)
+{
+ x *= Slope;
+ x += Offset;
+
+ // ACEScc has negative values that must not be clamped
+ // Use this to apply power to the negative range
+ float IsNeg = x >= 0 ? 1 : -1;
+ x = abs(x);
+ x = pow(x, Power);
+ x *= IsNeg;
+
+ return x;
+}
+
+void Color_Grading(inout float3 aces)
+{
+ float3 x = aces;
+
+ // ASC-CDL (SOP-S) style color grading
+ float3 Slope = {1.000, 1.000, 1.000};
+ float3 Offset = {0.000, 0.000, 0.000};
+ float3 Power = {1.000, 1.000, 1.000};
+ float Saturation = 1;
+
+// load custom settings from another file
+#include "ACES_settings.h"
+
+#ifdef USE_LOG_GRADING
+ // to ACEScc log space
+ x = lin_to_ACEScc(x);
+#endif
+
+ // apply CDL color grading
+ x = float3(ASC_CDL(x.r, Slope.r, Offset.r, Power.r), ASC_CDL(x.g, Slope.g, Offset.g, Power.g), ASC_CDL(x.b, Slope.b, Offset.b, Power.b));
+
+ // apply saturation
+ float luma = dot(x, LUMINANCE_VECTOR);
+ x = luma + Saturation * (x - luma);
+
+#ifdef USE_LOG_GRADING
+ // from ACEScc log space
+ x = ACEScc_to_lin(x);
+#endif
+
+ aces = x;
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMT.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMT.h
new file mode 100644
index 0000000000..a4adb20ac9
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMT.h
@@ -0,0 +1,42 @@
+//=================================================================================================
+// Look Modification Transforms
+// Stackable preset color modifications (linear ACEScg in/out)
+//=================================================================================================
+// Console commands
+// These can be used in LMTs to control their effect in engine
+// RGB + Offset
+// uniform float4 shader_param_1; // Slope
+// uniform float4 shader_param_2; // Offset
+// uniform float4 shader_param_3; // Power
+// uniform float4 shader_param_4;
+// uniform float4 shader_param_5;
+// uniform float4 shader_param_6;
+// uniform float4 shader_param_7;
+// uniform float4 shader_param_8; //Used by Beef's NVGs
+//=================================================================================================
+#include "ACES_Color_Grading.h"
+#include "ACES_LMTs\LMT_Contrast_Reduction.h"
+#include "ACES_LMTs\LMT_Technicolor.h"
+#include "ACES_LMTs\LMT_Bleach_Bypass.h"
+#include "ACES_LMTs\LMT_Blue_Fix.h"
+
+void ACES_LMT(inout float3 aces)
+{
+#ifdef USE_ACES
+ // do color grading in ACEScg primaries for more predictable results
+ aces = ACES_to_ACEScg(aces);
+#endif
+
+ Color_Grading(aces);
+ Contrast_Reduction(aces);
+
+ // Technicolor(aces);
+ // Bleach_Bypass(aces);
+
+#ifdef USE_ACES
+ // Return to ACES AP0
+ aces = ACEScg_to_ACES(aces);
+
+ Blue_Fix(aces); // ACES AP0 blue color shift fix
+#endif
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Bleach_Bypass.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Bleach_Bypass.h
new file mode 100644
index 0000000000..6241d77901
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Bleach_Bypass.h
@@ -0,0 +1,38 @@
+//=================================================================================================
+// LMT - Bleach Bypass by Nvidia
+// Creates a highly contrasted and desaturated look
+//=================================================================================================
+
+float Bleach_Bypass_Amount = 0.75; // strength of the effect
+
+void Bleach_Bypass(inout float3 aces)
+{
+ float3 x = aces;
+#ifdef USE_ACES
+ x = ACEScg_to_sRGB(x);
+ x = max(0, x);
+#endif
+
+ x = x / (1 + x); // compress to LDR
+
+ float4 base = float4(x.rgb, 1); // compress to LDR
+ float3 lumCoeff = float3(0.25, 0.65, 0.1);
+ float lum = dot(lumCoeff, base.rgb);
+ float3 blend = lum.rrr;
+ float L = min(1, max(0, 10 * (lum - 0.45)));
+ float3 result1 = 2.0f * base.rgb * blend;
+ float3 result2 = 1.0f - 2.0f * (1.0f - blend) * (1.0f - base.rgb);
+ float3 newColor = lerp(result1, result2, L);
+ float A2 = Bleach_Bypass_Amount * base.a;
+ float3 mixRGB = A2 * newColor.rgb;
+ mixRGB += ((1.0f - A2) * base.rgb);
+ mixRGB = saturate(mixRGB);
+
+ x = mixRGB / max(0.004, 1 - mixRGB); // expand to HDR
+
+#ifdef USE_ACES
+ x = sRGB_to_ACEScg(x);
+#endif
+
+ aces = lerp(aces, x, Technicolor_Amount);
+}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Blue_Fix.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Blue_Fix.h
new file mode 100644
index 0000000000..305bc7bc6d
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Blue_Fix.h
@@ -0,0 +1,7 @@
+//=================================================================================================
+// LMT for fixing occasional image artifacts seen in bright highlights (e.g. sirens,headlights,etc.)
+// Note that this will change scene colorimetry! (but tends to do so in a pleasing way)
+//=================================================================================================
+static const float3x3 correctionMatrix = {{0.9404372683, 0.0083786969, 0.0005471261}, {-0.0183068787, 0.8286599939, -0.0008833746}, {0.0778696104, 0.1629613092, 1.0003362486}};
+
+void Blue_Fix(inout float3 aces) { aces = mul(aces, correctionMatrix); }
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Contrast_Reduction.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Contrast_Reduction.h
new file mode 100644
index 0000000000..1038a12caf
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Contrast_Reduction.h
@@ -0,0 +1,11 @@
+//=================================================================================================
+// LMT - Contrast Reduction
+// Match STALKER's original tonemapping by reducing the contrast
+//=================================================================================================
+
+void Contrast_Reduction(inout float3 aces)
+{
+ float Contrast_Amount = 0.7;
+ const float mid = 0.18;
+ aces = pow(aces, Contrast_Amount) * mid / pow(mid, Contrast_Amount);
+}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Technicolor.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Technicolor.h
new file mode 100644
index 0000000000..f2dd7e18aa
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_LMTs/LMT_Technicolor.h
@@ -0,0 +1,42 @@
+//=================================================================================================
+// LMT - Technicolor from http://enbseries.enbdev.com/forum/viewtopic.php?f=7&t=3552
+// Saturation boost that emulates the vibrancy of 3 strip technicolor
+//=================================================================================================
+
+float Technicolor_Amount = .4;
+
+void Technicolor(inout float3 aces)
+{
+ float3 x = aces;
+#ifdef USE_ACES
+ x = ACEScg_to_sRGB(x);
+ x = max(0, x);
+#endif
+
+ float3 colStrength = .4;
+ float brightness = 0;
+
+ x = x / (1 + x); // compress to LDR
+
+ float3 source = saturate(x.rgb);
+ float3 temp = 1 - source.rgb;
+ float3 target = temp.grg;
+ float3 target2 = temp.bbr;
+ float3 temp2 = source.rgb * target.rgb;
+ temp2.rgb *= target2.rgb;
+ temp.rgb = temp2.rgb * colStrength.rgb;
+ temp2.rgb *= brightness;
+ target.rgb = temp.grg;
+ target2.rgb = temp.bbr;
+ temp.rgb = source.rgb - target.rgb;
+ temp.rgb += temp2.rgb;
+ temp2.rgb = saturate(temp.rgb - target2.rgb);
+
+ x = temp2 / max(0.004, 1 - temp2); // expand to HDR
+
+#ifdef USE_ACES
+ x = sRGB_to_ACEScg(x);
+#endif
+
+ aces = lerp(aces, x, Technicolor_Amount);
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_settings.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_settings.h
new file mode 100644
index 0000000000..da84674d65
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ACES_settings.h
@@ -0,0 +1,21 @@
+//=================================================================================================
+// Defines for and variables for ACES and color grading
+//=================================================================================================
+#define USE_LOG_GRADING // Use log space for color grading
+//=================================================================================================
+
+//
+// manual settings
+//
+/*
+ Slope = float3(1.000, 1.000, 1.000);
+ Offset = float3(0.000, 0.000, 0.000);
+ Power = float3(1.000, 1.000, 1.000);
+ Saturation = 1.000;
+*/
+//
+// settings for supporting in-game console commands
+//
+Slope = pp_img_corrections.xxx; // brightness
+Power = 2 * (1 - pp_img_cg.rgb); // color grading
+Saturation = pp_img_corrections.z; // saturation
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_base.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_base.ps
index 31cd861ffe..cf91eaff18 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_base.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_base.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissive.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissive.ps
index 0dd5896ecb..655e431d59 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissive.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissive.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissivel.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissivel.ps
index 95629a7503..dc0633a359 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissivel.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_emissivel.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_indirect.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_indirect.ps
index 4e8f2eeaf1..8111ce574b 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_indirect.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_indirect.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_omni_unshadowed.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_omni_unshadowed.ps
index 5c523dbc1a..53a7a07465 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_omni_unshadowed.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_omni_unshadowed.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun.ps
index 70eaece5c2..005ae255dd 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_far.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_far.ps
index c6c3851d0f..d69c2d3836 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_far.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_far.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_mask.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_mask.ps
index d36e5b7720..441fac28de 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_mask.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_mask.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_near.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_near.ps
index bfa191de61..d264cb0577 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_near.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_sun_near.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_volumetric.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_volumetric.ps
index c6887f0ce2..b7126a4c06 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_volumetric.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/accum_volumetric.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/bloom_luminance_3.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/bloom_luminance_3.ps
index 1a78b6f833..4188001fc5 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/bloom_luminance_3.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/bloom_luminance_3.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace.h
index 54afff0e9f..0246dc1391 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace.h
@@ -8,4 +8,5 @@
#include "check_screenspace_FOG.h"
#include "check_screenspace_IL.h"
#include "check_screenspace_FLORA.h"
-#include "check_screenspace_INTER_GRASS.h"
\ No newline at end of file
+#include "check_screenspace_INTER_GRASS.h"
+#include "check_screenspace_NEWGLOSS.h"
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_ES.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_ES.h
index 29990495c6..d2e5b562a1 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_ES.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_ES.h
@@ -1 +1 @@
-//#define SSFX_ENHANCED_SHADERS
\ No newline at end of file
+#define SSFX_ENHANCED_SHADERS
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_NEWGLOSS.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_NEWGLOSS.h
new file mode 100644
index 0000000000..6103880e3a
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/check_screenspace_NEWGLOSS.h
@@ -0,0 +1 @@
+#define SSFX_NEWGLOSS
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.ps
index 0446e9068b..599084fd51 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.vs
index 3a7d34dbe3..b3b7b2a36a 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/clouds.vs
@@ -22,8 +22,6 @@ vf main(vi v)
o.hpos = mul(m_WVP, v.p); // xform, input in world coords
- // if (length(float3(v.p.x,0,v.p.z))>CLOUD_FADE) o.color.w = 0 ;
-
// generate tcs
float2 d0 = v.dir.xy * 2 - 1;
float2 d1 = v.dir.wz * 2 - 1;
@@ -35,9 +33,8 @@ vf main(vi v)
o.color = v.color; // copy color, low precision, cannot prescale even by 2
o.color.w *= pow(v.p.y, 25);
- // float scale = tex2Dlod (s_tonemap,float4(.5,.5,.5,.5)).x ;
float scale = s_tonemap.Load(int3(0, 0, 0)).x;
- // float scale = s_tonemap.Load( int3(1,1,0) ).x;
+
o.color.rgb *= scale; // high precision
return o;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_1.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_1.ps
index 7790a129a2..f8a9f4c0a9 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_1.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_1.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_2_naa.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_2_naa.ps
index 304edd3b11..33dc6cd4f3 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_2_naa.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_2_naa.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_volumetric.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_volumetric.s
index 17e80e7b93..f01a15d382 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_volumetric.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/combine_volumetric.s
@@ -2,12 +2,9 @@ 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)
+ : blend (true,blend.invdestcolor,blend.one)
-- : aref (true,0) -- enable to save bandwith?
: sorting (2, false)
--- TOD0: DX10: Implement samplers
--- shader:sampler ("s_vollight") :texture ("$user$generic2")
--- shader:sampler ("s_tonemap") :texture ("$user$tonemap")
shader:dx10texture ("s_vollight", "$user$generic2")
shader:dx10texture ("s_tonemap", "$user$tonemap")
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_brdf.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_brdf.h
index 365a2f5500..0047de5993 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_brdf.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_brdf.h
@@ -19,10 +19,10 @@
#define MAT_FLORA_ELIPSON 0.04f
// Simple subsurface scattering
-float SSS(float3 N, float3 V, float3 L)
+float3 SSS(float3 N, float3 V, float3 L)
{
- float S = saturate(dot(V, -(L + N))) * G_SSS_INTENSITY;
- return S;
+ 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);
}
#endif
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_defines.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_defines.h
index 1c13bbe000..f08220c6eb 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_defines.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_defines.h
@@ -17,7 +17,7 @@
#define def_hdr float(9.h) // hight luminance range float(3.h)
#define def_hdr_clip float(0.75h) //
-#define LUMINANCE_VECTOR float3(0.3f, 0.38f, 0.22f) // anomaly: float3(0.2125, 0.7154, 0.0721)
+#define LUMINANCE_VECTOR float3(0.2125, 0.7154, 0.0721)
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef SMAP_size
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_functions.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_functions.h
index ed3987a385..d956e4a455 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_functions.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/common_functions.h
@@ -1,14 +1,23 @@
#ifndef common_functions_h_included
#define common_functions_h_included
+#include "srgb.h"
+
uniform float4 m_actor_params;
-float3 vibrance(float3 img, half val)
+float3 vibrance(float3 img, float val)
{
float luminance = dot(float3(img.rgb), LUMINANCE_VECTOR);
return float3(lerp(luminance, float3(img.rgb), val));
}
+float2 hash22(float2 p)
+{
+ float3 p3 = frac(float3(p.xyx) * float3(.1031, .1030, .0973));
+ p3 += dot(p3, p3.yzx + 19.19);
+ return frac((p3.xx + p3.yz) * p3.zy);
+}
+
float noise(float2 tc) { return frac(sin(dot(tc, float2(12.0, 78.0) + (timers.x))) * 43758.0) * 0.25f; }
// contrast function
@@ -24,26 +33,53 @@ float Contrast(float Input, float ContrastPower)
void tonemap(out float4 low, out float4 high, float3 rgb, float scale)
{
+ rgb = SRGBToLinear(rgb);
rgb = rgb * scale;
+ rgb = LinearTosRGB(rgb);
- if (m_actor_params.a > 0.0f)
- {
- const float fWhiteIntensity = 1.7;
+ const float fWhiteIntensity = 11.2;
- const float fWhiteIntensitySQR = fWhiteIntensity * fWhiteIntensity;
+ low = float4(tonemap_sRGB(rgb, fWhiteIntensity), 0);
+ high = float4(rgb / def_hdr, 0);
+}
- low = ((rgb * (1 + rgb / fWhiteIntensitySQR)) / (rgb + 1)).xyzz;
+void tonemap_hipri(out float4 low, out float4 high, float3 rgb, float scale) { tonemap(low, high, rgb, scale); }
- high = rgb.xyzz / def_hdr; // 8x dynamic range
- }
- else
- {
- low = rgb.xyzz;
- high = low / def_hdr; // 8x dynamic range
- }
+// CUSTOM
+float3 blend_soft(float3 a, float3 b)
+{
+ // return 1.0 - (1.0 - a) * (1.0 - b);
+
+ // gamma correct and inverse tonemap to add bloom
+ a = SRGBToLinear(a); // post tonemap render
+ a = a / max(0.004, 1 - a); // inverse tonemap
+ // a = a / max(0.001, 1-a); //inverse tonemap
+ b = SRGBToLinear(b); // bloom
+
+ // constrast reduction of ACES output
+ float Contrast_Amount = 0.7;
+ const float mid = 0.18;
+ a = pow(a, Contrast_Amount) * mid / pow(mid, Contrast_Amount);
+
+ ACES_LMT(b); // color grading bloom
+ a += b; // bloom add
+
+ // Boost the contrast to match ACES RRT
+ float Contrast_Boost = 1.42857;
+ a = pow(a, Contrast_Boost) * mid / pow(mid, Contrast_Boost);
+
+ a = a / (1 + a); // tonemap
+
+ a = LinearTosRGB(a);
+ return a;
}
-float4 combine_bloom(float3 low, float4 high) { return float4(low + high * high.a, 1.h); }
+/*float4 combine_bloom(float3 low, float4 high)
+{
+ // return float4(low + high*high.a, 1); //add
+ high.rgb *= high.a;
+ return float4(blend_soft(low.rgb, high.rgb), 1); // screen
+}*/
float calc_fogging(float4 w_pos) { return dot(w_pos, fog_plane); }
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_base_aref_bump-hq.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_base_aref_bump-hq.ps
index 9622d17ab6..c25fe6d369 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_base_aref_bump-hq.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_base_aref_bump-hq.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.ps
index 8e6a2ae3f3..edbfea6431 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.vs
index 52bb2d39f9..ec2d6c9254 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_grass.vs
@@ -9,6 +9,10 @@ float4 wave; // cx,cy,cz,tm
float4 dir2D;
float4 array[61 * 4];
+#define SSFX_WIND_ISGRASS
+
+#include "screenspace_wind.h"
+
v2p_bumped main(v_detail v)
{
v2p_bumped O;
@@ -20,22 +24,16 @@ v2p_bumped main(v_detail v)
float4 c0 = array[i + 3];
// Transform pos to world coords
- float4 pos;
- pos.x = dot(m0, v.pos);
- pos.y = dot(m1, v.pos);
- pos.z = dot(m2, v.pos);
- pos.w = 1;
+ float4 P;
+ P.x = dot(m0, v.pos);
+ P.y = dot(m1, v.pos);
+ P.z = dot(m2, v.pos);
+ P.w = 1;
// Wave effect
- float base = m1.w;
- float dp = calc_cyclic(dot(pos, wave));
- float H = pos.y - base; // height of vertex (scaled)
- float frac = v.misc.z * consts.x; // fractional
- float inten = H * dp;
- float2 result = calc_xz_wave(dir2D.xz * inten, frac);
-
- // Add wind
- pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ float H = P.y - m1.w; // height of vertex (scaled)
+ float3 wind_result = ssfx_wind_grass(P.xyz, H, ssfx_wind_setup());
+ float4 pos = float4(P.xyz + wind_result.xyz, 1);
// INTERACTIVE GRASS - SSS Update 15.4
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
@@ -72,7 +70,7 @@ v2p_bumped main(v_detail v)
// https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
// Fake Normal, Bi-Normal and Tangent
- float3 N = normalize(float3(pos.x - m0.w, pos.y - m1.w + 1.0f, pos.z - m2.w));
+ float3 N = normalize(float3(P.x - m0.w, P.y - m1.w + 1.0f, P.z - m2.w));
float3x3 xform = mul((float3x3)m_WV, float3x3(0, 0, N.x, 0, 0, N.y, 0, 0, N.z));
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_impl_flat.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_impl_flat.ps
index 6f7ca8271b..cae14e24a8 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_impl_flat.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_impl_flat.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_bump-hq.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_bump-hq.vs
index c6503d72f4..578df93562 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_bump-hq.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_bump-hq.vs
@@ -1,3 +1,11 @@
+/**
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 19
+ * @ Description: Trees - Branches/Bushes
+ * @ Modified time: 2023-11-07 13:27
+ * @ 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"
@@ -10,6 +18,8 @@ uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale, c_bias, wind, wave;
uniform float2 c_sun; // x=*, y=+
+#include "screenspace_wind.h"
+
v2p_bumped main(v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
@@ -19,18 +29,13 @@ v2p_bumped main(v_tree I)
// 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 * 2.0f, frac);
+ float H = pos.y - m_xform._24; // height of vertex
+ float2 tc = (I.tc * consts).xy;
+ float3 wind_result = ssfx_wind_tree_branches(pos, H, tc.y, ssfx_wind_setup());
#ifdef USE_TREEWAVE
- result = 0;
+ wind_result = 0;
#endif
- float4 w_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
- float2 tc = (I.tc * consts).xy;
+ 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/
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_flat.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_flat.vs
index 6e09ad1c84..24371b5d5a 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_flat.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_branch_flat.vs
@@ -12,6 +12,8 @@ uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale, c_bias, wind, wave;
uniform float2 c_sun; // x=*, y=+
+#include "screenspace_wind.h"
+
v2p_flat main(v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
@@ -23,18 +25,13 @@ v2p_flat main(v_tree I)
// 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);
+ float H = pos.y - m_xform._24; // height of vertex
+ float2 tc = (I.tc * consts).xy;
+ float3 wind_result = ssfx_wind_tree_branches(pos, H, tc.y, ssfx_wind_setup());
#ifdef USE_TREEWAVE
- result = 0;
+ wind_result = 0;
#endif
- float4 w_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
- float2 tc = (I.tc * consts).xy;
+ 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/
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump-hq.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump-hq.vs
index 305b78652c..080d52551c 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump-hq.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump-hq.vs
@@ -1,3 +1,11 @@
+/**
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 19
+ * @ Description: Trees - Trunk
+ * @ Modified time: 2023-11-17 11:11
+ * @ Author: https://www.moddb.com/members/ascii1457
+ * @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
+ */
+
#include "common.h"
uniform float3x4 m_xform;
@@ -6,6 +14,8 @@ uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale, c_bias, wind, wave;
uniform float2 c_sun; // x=*, y=+
+#include "screenspace_wind.h"
+
v2p_bumped main(v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
@@ -14,18 +24,12 @@ v2p_bumped main(v_tree I)
// 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);
+ float H = pos.y - m_xform._24; // height of vertex
+ float2 wind_result = ssfx_wind_tree_trunk(pos, H, ssfx_wind_setup()).xy;
#ifdef USE_TREEWAVE
- result = 0;
+ wind_result = 0;
#endif
- float4 w_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ 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;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump.vs
index ef68e0ec47..f06e6d187e 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_bump.vs
@@ -1,3 +1,11 @@
+/**
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 19
+ * @ Description: Trees - Trunk ( Burn Sections )
+ * @ Modified time: 2023-11-17 10:57
+ * @ Author: https://www.moddb.com/members/ascii1457
+ * @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
+ */
+
#include "common.h"
uniform float3x4 m_xform;
@@ -6,33 +14,29 @@ uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale, c_bias, wind, wave;
uniform float2 c_sun; // x=*, y=+
+#include "screenspace_wind.h"
+
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 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);
+ float H = pos.y - m_xform._24; // height of vertex
+ float2 wind_result = ssfx_wind_tree_trunk(pos, H, ssfx_wind_setup()).xy;
#ifdef USE_TREEWAVE
- result = 0;
+ wind_result = 0;
#endif
- float4 w_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ 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;
- // float hemi = I.Nh.w;
+ // float hemi = I.Nh.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul(m_V, w_pos);
+ // float3 Pe = mul(m_V, float4(pos.xyz,1));
O.tcdh = float4(tc.xyyy);
O.hpos = mul(m_VP, w_pos);
O.position = float4(Pe, hemi);
@@ -44,11 +48,35 @@ v2p_bumped main(v_tree I)
// 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)
+ // = 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);
+ float3 N = unpack_bx2(I.Nh); // just scale (assume normal in the -.5f, .5f)
+ float3 sphereOffset = float3(0.1, 1.0, 0.2);
+ float3 sphereScale = float3(1.0, 2.0, 1.0);
+ float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); // Spherical normals trick
+ float3 T = unpack_bx2(I.T); //
+ float3 B = unpack_bx2(I.B); //
+ N = normalize(N);
+ B = normalize(B);
+ T = normalize(T);
+
+ // tangent basis
+ float3 flatB = float3(0, 0, 1);
+
+ if (abs(dot(sphereN, flatB)) > 0.99f)
+ flatB = float3(0, 1, 0);
+
+ float3 flatT = normalize(cross(sphereN, flatB));
+ flatB = normalize(cross(sphereN, flatT));
+
+ // foliage
+ float foliageMat = 0.5; // foliage
+ // float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
+ float foliageMask = (abs(xmaterial - foliageMat) >= 0.2) ? 1 : 0; // foliage
+ // float foliageMask = 1; //foliage
+ N = normalize(lerp(N, sphereN, foliageMask)); // blend to foliage normals
+ // B = normalize(lerp(B, flatB, foliageMask)); //blend to foliage normals
+ // T = normalize(lerp(T, flatT, foliageMask)); //blend to foliage normals
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));
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_flat.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_flat.vs
index 6ded31c7de..fe491cb878 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_flat.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_flat.vs
@@ -29,13 +29,35 @@ v2p_flat main(v_tree I)
#endif
float4 f_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ // Normal mapping
+ float3 N = unpack_bx2(I.Nh);
+ float3 sphereOffset = float3(0.0, 1.0, 0.0);
+ float3 sphereScale = float3(1.0, 2.0, 1.0);
+ float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); // Spherical normals trick
+ float3 flatN = (float3(0, 1, 0));
+ /*
+ float3 camFacingN = normalize((f_pos - eye_position.xyz) * float3(-1,0,-1));
+ sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
+
+ sphereN.xz *= 0.5;
+ sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
+ sphereN = normalize(sphereN);
+ */
+ // foliage
+ float foliageMat = 0.5; // foliage
+ // float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
+ float foliageMask = (abs(xmaterial - foliageMat) >= 0.2) ? 1 : 0; // foliage
+ // float foliageMask = 1; //foliage
+ N = normalize(lerp(N, sphereN, foliageMask)); // blend to foliage normals
+
// Final xform(s)
// Final xform
float3 Pe = mul(m_V, f_pos);
+ // float3 Pe = mul(m_V, float4(pos.xyz,1));
float hemi = I.Nh.w * c_scale.w + c_bias.w;
- // float hemi = I.Nh.w;
+ // float hemi = I.Nh.w;
o.hpos = mul(m_VP, f_pos);
- o.N = mul((float3x3)m_xform_v, unpack_bx2(I.Nh));
+ o.N = mul((float3x3)m_xform_v, N);
o.tcdh = float4((I.tc * consts).xyyy);
o.position = float4(Pe, hemi);
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_bump.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_bump.vs
index 46a8cc0a2f..2ddc796799 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_bump.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_bump.vs
@@ -1,2 +1,101 @@
-#define USE_TREEWAVE
-#include "deffer_tree_bump.vs"
+#include "common.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=+
+
+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 = I.P;
+
+ //
+ float2 result = 0;
+ float4 w_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ float2 tc = (I.tc * consts).xy;
+ float hemi = I.Nh.w * c_scale.w + c_bias.w;
+ // float hemi = I.Nh.w;
+
+ // Eye-space pos/normal
+ v2p_bumped O;
+ float3 Pe = mul(m_V, w_pos);
+ // float3 Pe = mul(m_V, float4(pos.xyz,1));
+ 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)
+ float3 N = unpack_bx2(I.Nh); // just scale (assume normal in the -.5f, .5f)
+ float3 T = unpack_bx2(I.T); //
+ float3 B = unpack_bx2(I.B); //
+ N = normalize(N);
+ B = normalize(B);
+ T = normalize(T);
+
+ float3 sphereOffset = float3(0.0, 1.0, 0.0);
+ float3 sphereScale = float3(1.0, 2.0, 1.0);
+ float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); // Spherical normals trick
+ /*
+ float3 camFacingN = normalize((w_pos - eye_position.xyz) * float3(-1,0,-1));
+ sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
+
+ sphereN.xz *= 0.5;
+ sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
+ sphereN = normalize(sphereN);
+ */
+
+ // tangent basis
+ float3 flatB = float3(0, 0, 1);
+
+ if (abs(dot(sphereN, flatB)) > 0.99f)
+ flatB = float3(0, 1, 0);
+
+ float3 flatT = normalize(cross(sphereN, flatB));
+ flatB = normalize(cross(sphereN, flatT));
+
+ // foliage
+ float foliageMat = 0.5; // foliage
+ // float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
+ float foliageMask = (abs(xmaterial - foliageMat) >= 0.2) ? 1 : 0; // foliage
+ // float foliageMask = 1; //foliage
+ N = normalize(lerp(N, sphereN, foliageMask)); // blend to foliage normals
+ // B = normalize(lerp(B, flatB, foliageMask)); //blend to foliage normals
+ // T = normalize(lerp(T, flatT, foliageMask)); //blend to foliage normals
+
+ 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;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_flat.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_flat.vs
index 7661ad3264..3596e5f938 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_flat.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/deffer_tree_s_flat.vs
@@ -1,2 +1,67 @@
-#define USE_TREEWAVE
-#include "deffer_tree_flat.vs"
+#include "common.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=+
+
+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 H = I.P;
+
+ //
+ float2 result = 0;
+ float4 f_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+
+ // Normal mapping
+ float3 N = unpack_bx2(I.Nh);
+ float3 sphereOffset = float3(0.0, 1.0, 0.0);
+ float3 sphereScale = float3(1.0, 2.0, 1.0);
+ float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); // Spherical normals trick
+ float3 flatN = (float3(0, 1, 0));
+ /*
+ float3 camFacingN = normalize((f_pos - eye_position.xyz) * float3(-1,0,-1));
+ sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
+
+ sphereN.xz *= 0.5;
+ sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
+ sphereN = normalize(sphereN);
+ */
+ // foliage
+ float foliageMat = 0.5; // foliage
+ // float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
+ float foliageMask = (abs(xmaterial - foliageMat) >= 0.2) ? 1 : 0; // foliage
+ // float foliageMask = 1; //foliage
+ N = normalize(lerp(N, sphereN, foliageMask)); // blend to foliage normals
+
+ // Final xform(s)
+ float3 Pe = mul(m_V, f_pos);
+ // float3 Pe = mul(m_V, float4(pos.xyz,1));
+ 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 = mul((float3x3)m_xform_v, N);
+ o.tcdh = float4((I.tc * consts).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;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/details_blend.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/details_blend.s
index c87f9097cb..8a0c1c533d 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/details_blend.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/details_blend.s
@@ -9,8 +9,14 @@ function normal (shader, t_base, t_second, t_detail)
shader:dx10cullmode (1)
shader:dx10texture("s_base", t_base)
+ --local opt = shader:dx10Options()
+ --shader:dx10texture("s_bump", "levels\\" .. opt:getLevel() .. "\\" .. t_base.."_bump")
shader:dx10texture("s_bump", 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
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/hmodel.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/hmodel.h
index ca0dd09284..711e1f9c7f 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/hmodel.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/hmodel.h
@@ -1,80 +1,135 @@
+/**
+ * @ 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 HMODEL_H
#define HMODEL_H
+#define CUBE_MIPS 6 // mipmaps for ambient shading and specular
-#include "common.h"
+#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
-uniform float3x4 m_v2w;
+uniform float4 env_color; // color.w = lerp factor
-void hmodel(out float3 hdiffuse, out float3 hspecular, float m, float h, float s, float3 Pnt, float3 normal)
+void hmodel(out float3 hdiffuse, out float3 hspecular, float m, float h, float4 alb_gloss, float3 Pnt, float3 normal)
{
- // hscale - something like diffuse reflection
- float3 nw = mul(m_v2w, normal);
- float hscale = h; //. * (.5h + .5h*nw.y);
+ // [ 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);
-#ifdef USE_GAMMA_22
- hscale = (hscale * hscale); // make it more linear
-#endif
+ // 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 v2PntL = normalize(Pnt);
- float3 v2Pnt = mul(m_v2w, v2PntL);
float3 vreflect = reflect(v2Pnt, nw);
- float hspec = .5h + .5h * dot(vreflect, v2Pnt);
- // material // sample material
- float4 light = s_material.SampleLevel(smp_material, float3(hscale, hspec, m), 0).xxxy;
+ // 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;
- // diffuse color
- // float3 e0d = texCUBE( env_s0, nw );
- // float3 e1d = texCUBE( env_s1, nw );
- // float3 e0d = env_s0.Sample( smp_rtlinear, nw );
- // float3 e1d = env_s1.Sample( smp_rtlinear, nw );
- float3 e0d = env_s0.SampleLevel(smp_rtlinear, nw, 0);
- float3 e1d = env_s1.SampleLevel(smp_rtlinear, nw, 0);
- float3 env_d = env_color.xyz * lerp(e0d, e1d, env_color.w);
- env_d *= env_d; // contrast
- hdiffuse = env_d * light.xyz + L_ambient.rgb;
+ 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
- vreflect.y = vreflect.y * 2 - 1; // fake remapping
- // float3 e0s = texCUBE( env_s0, vreflect );
- // float3 e1s = texCUBE( env_s1, vreflect );
- // float3 e0s = env_s0.Sample( smp_rtlinear, vreflect );
- // float3 e1s = env_s1.Sample( smp_rtlinear, vreflect );
- float3 e0s = env_s0.SampleLevel(smp_rtlinear, vreflect, 0);
- float3 e1s = env_s1.SampleLevel(smp_rtlinear, vreflect, 0);
- float3 env_s = env_color.xyz * lerp(e0s, e1s, env_color.w);
- env_s *= env_s; // contrast
- hspecular = env_s * light.w * s; //*h*m*s ; //env_s *light.w * s;
-}
+ float3 e0s = env_s0.SampleLevel(smp_base, vreflectRemap, RoughMip);
+ float3 e1s = env_s1.SampleLevel(smp_base, vreflectRemap, RoughMip);
-/*
-void hmodel_table (out float3 hdiffuse, out float3 hspecular, float m, float h, float s, float3 point, float3 normal)
-{
- // hscale - something like diffuse reflection
- float hscale = h;
+ // 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;
- // reflection vector
- float3 v2point = normalize (Pnt);
- float3 vreflect= reflect (v2point,normal);
- float hspec = .5h+.5h*dot (vreflect,v2point);
+ env_d *= env_col;
+ env_s *= env_col;
- // material
- float4 light = tex3D (s_material, float3(hscale, hspec, m) ); // sample material
+ // lightmap ambient
+ env_d *= light.xxx;
+ env_s *= light.www;
- // diffuse color
- float3 env_d = texCUBE (env_s0,normal);
+ // ambient color
+ float3 amb_col = L_ambient.rgb;
+ env_d += amb_col;
+ env_s += amb_col; //*(env_s/env_d);
- // specular color
- float3 env_s = texCUBE (env_s0,vreflect);
+ env_d = SRGBToLinear(env_d);
+ env_s = SRGBToLinear(env_s); // gamma correct
- //
- hdiffuse = env_d *light.xyz + L_ambient.rgb ;
- hspecular = env_s *light.w * s ;
+ hdiffuse = Amb_BRDF(rough, albedo, specular, env_d, env_s * !m_flora, -v2Pnt, nw).rgb;
+ hspecular = 0; // do not use hspec at all
}
-*/
#endif
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/img_corrections.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/img_corrections.h
new file mode 100644
index 0000000000..8f9f7b4c53
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/img_corrections.h
@@ -0,0 +1,37 @@
+// DISABLED FOR ACES
+
+#ifndef IMG_CORRECTIONS_H
+#define IMG_CORRECTIONS_H
+#include "common.h"
+//#include "anomaly_shaders.h"
+#define COLOR_GRADING_LUMINANCE float3(0.213, 0.715, 0.072)
+float3 img_corrections(float3 img)
+{
+ /*
+ //exposure
+ img.xyz *= pp_img_corrections.x;
+
+ //do color in tonemap
+ //color grading (thanks KD and Crytek)
+ float fLum = dot(img.xyz, COLOR_GRADING_LUMINANCE)*2;
+ float3 cMin = 0.0;
+ float3 cMed = pp_img_cg.xyz;
+ float3 cMax = 1.0;
+ float3 cColor = lerp(cMin, cMed , saturate(fLum * 2.0 ) );
+ cColor = lerp(cColor, cMax, 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.15f ) ));
+ }
+
+ //saturation
+ img.xyz = max(0, lerp(img.xyz, dot(img.xyz, LUMINANCE_VECTOR), (1.0 - pp_img_corrections.z)));
+ */
+ // gamma correction
+ img.xyz = pow(img, (1. / pp_img_corrections.y));
+
+ // that's all :)
+ return img.xyz;
+}
+#endif
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/lmodel.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/lmodel.h
index 9da7865a45..880346a27b 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/lmodel.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/lmodel.h
@@ -1,58 +1,101 @@
+/**
+ * @ 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, float mat_id)
+
+float4 compute_lighting(float3 N, float3 V, float3 L, float4 alb_gloss, float mat_id)
{
- // Half vector
- float3 H = normalize(L + V);
+ // [ 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);
- // Combined light
- float4 light = s_material.Sample(smp_material, float3(dot(L, N), dot(H, N), mat_id)).xxxy;
+ float3 light = Lit_BRDF(rough, albedo, specular, V, N, L);
- if (mat_id == MAT_FLORA) // Be aware of precision loss/errors
+ // 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
- float subsurface = SSS(N, V, L);
- light.rgb += subsurface;
+ float3 subsurface = SSS(N, V, L);
+ light.rgb += subsurface * albedo;
}
- return light;
+ return float4(light, 0);
}
-float4 plight_infinity(float m, float3 pnt, float3 normal, float3 light_direction)
+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
+ float3 V = normalize(-pnt); // vector2eye
+ float3 L = normalize(-light_direction); // vector2light
- float4 light = compute_lighting(N, V, L, m);
+ float4 light = compute_lighting(N, V, L, c_tex, m);
- return light * 2.0f / 3.0f; // output (albedo.gloss)
+ return light; // output (albedo.gloss)
}
-float4 plight_local(float m, float3 pnt, float3 normal, float3 light_position, float light_range_rsq, out float rsqr)
+float4 plight_local(float m, float3 pnt, float3 normal, float4 c_tex, float3 light_position, float light_range_rsq, out float rsqr)
{
- float3 N = normalize(normal); // normal
+ float atteps = 0.1;
+
float3 L2P = pnt - light_position; // light2point
- float3 V = -normalize(pnt); // vector2eye
- float3 L = -normalize((float3)L2P); // vector2light
- float3 H = normalize(L + V); // half-angle-vector
rsqr = dot(L2P, L2P); // distance 2 light (squared)
- float att = saturate(1 - rsqr * light_range_rsq); // q-linear attenuate
+ rsqr = max(rsqr, atteps);
+ // rsqr = rsqr + 1.0;
- float4 light = compute_lighting(N, V, L, m);
+ // 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
- return att * light * 2.0f / 3.0f; // output (albedo.gloss)
+ 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
-float4 blendp(float4 value, float4 tcp) { return value; }
-float4 blend(float4 value, float2 tc) { return value; }
+half4 blendp(half4 value, float4 tcp) { return value; }
+
+half4 blend(half4 value, float2 tc) { return value; }
#endif
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_compscreen.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_compscreen.s
index d1e89ee8cd..34d0234fb9 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_compscreen.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_compscreen.s
@@ -11,8 +11,11 @@ function normal (shader, t_base, t_second, t_detail)
end
function l_special (shader, t_base, t_second, t_detail)
- shader:begin ("shadow_direct_model", "accum_emissivel")
+ shader:begin ("deffer_model_flat", "accum_emissivel")
: zb (true,false)
: fog (false)
: emissive (true)
+
+ shader:dx10texture ("s_base", t_base)
+ shader:dx10sampler ("smp_base")
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.ps
index cfc0d3cd4d..03790d197e 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.s
index 789a36eceb..e620304281 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_detector_3.s
@@ -18,7 +18,9 @@ function l_special(shader, t_base, t_second, t_detail)
:zb(true, false)
:fog(false)
:emissive(true)
+ shader:dx10texture("s_base", t_base)
+ shader:dx10sampler("smp_base")
shader:dx10texture("s_numbers", t_numbers)
shader:dx10sampler("smp_linear")
- shader:dx10color_write_enable(true, true, true, false)
+ --shader:dx10color_write_enable(true, true, true, false) --в ES отключено
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight.s
index d0942623b9..6b075e7bd4 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight.s
@@ -2,18 +2,25 @@ function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_model_flat","deffer_base_flat")
: fog (false)
: emissive (true)
- --shader:sampler ("s_base") :texture (t_base)
+-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
+
+ --shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
- shader:begin ("shadow_direct_model", "accum_emissive")
+ shader:begin ("deffer_model_flat", "accum_emissive")
: zb (true,false)
: fog (false)
: emissive (true)
+
+ shader:dx10texture ("s_base", t_base)
+ shader:dx10sampler ("smp_base")
+
+ --shader: dx10color_write_enable( true, true, true, true)
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight_det.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight_det.s
index a669116e3a..c86de973b7 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight_det.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflight_det.s
@@ -9,13 +9,19 @@ function normal (shader, t_base, t_second, t_detail)
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
- shader: dx10color_write_enable( true, true, true, false)
+
+ --shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
- shader:begin ("shadow_direct_model", "accum_emissivel")
+ shader:begin ("deffer_model_flat", "accum_emissivel")
: zb (true,false)
: fog (false)
: emissive (true)
- shader: dx10color_write_enable( true, true, true, false)
+
+ shader:dx10texture ("s_base", t_base)
+ shader:dx10sampler ("smp_base")
+
+ --shader: dx10color_write_enable( true, true, true, false)
+ --shader: dx10color_write_enable( true, true, true, true)
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflightl.s b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflightl.s
index 2c3b3edeab..81fef781b8 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflightl.s
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/models_selflightl.s
@@ -9,11 +9,18 @@ function normal (shader, t_base, t_second, t_detail)
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
+
+ --shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
- shader:begin ("shadow_direct_model", "accum_emissivel")
+ shader:begin ("deffer_model_flat", "accum_emissivel")
: zb (true,false)
: fog (false)
: emissive (true)
+
+ shader:dx10texture ("s_base", t_base)
+ shader:dx10sampler ("smp_base")
+
+ --shader: dx10color_write_enable( true, true, true, true)
end
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf.h
new file mode 100644
index 0000000000..71409e3e4a
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf.h
@@ -0,0 +1,293 @@
+/**
+ * @ 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
+ */
+
+//=================================================================================================
+// 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);
+
+ return (diffuse_term + specular_term) * 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;
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_blinn.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_blinn.h
new file mode 100644
index 0000000000..35349e3cd1
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_blinn.h
@@ -0,0 +1,61 @@
+// BLOPS 2 blinn phong PBR
+// credit to Treyarch
+
+float CalcGlossmap(float rough) { return 1.0 - rough; }
+
+float RoughToGlossExp(float rough)
+{
+ // return = 2 / ((rough*rough) - 2); UE4 blinn
+ return pow(8192, CalcGlossmap(rough)); // blops2
+ // return pow(2, 11 * CalcGlossmap(rough)) - 1;
+}
+
+float D_Blinn(float a, float nDotH)
+{
+ return pow(nDotH, a) * ((a + 2) / (8 * PI)); // BLOPS2
+}
+
+float G_Smith(float a, float nDotX)
+{
+ float k = 2 / sqrt(PI * (a + 2)); // remapping for BLOPS
+ return nDotX / (nDotX * (1 - k) + k);
+}
+
+float G_SmithBLOPS(float a, float nDotl, float nDotv)
+{
+ float k = 2 / sqrt(PI * (a + 2)); // remapping for BLOPS
+ float A = nDotl * (1 - k) + k; // remapping for BLOPS
+ float B = nDotv * (1 - k) + k; // remapping for BLOPS
+
+ return 1 / (A * B);
+}
+
+float3 Lit_Blinn(float nDotL, float nDotH, float nDotV, float vDotH, float3 f0, float rough)
+{
+ float a = RoughToGlossExp(rough);
+
+ float d = D_Blinn(a, nDotH);
+
+ // float v = G_Smith(a, nDotL) * G_Smith(a, nDotV);
+ float v = G_SmithBLOPS(a, nDotL, nDotV);
+
+ float3 f90Atten = saturate(50 * f0); // UE4 specular shadowing
+ float3 f = F_Shlick(f0, f90Atten, vDotH);
+
+ return d * f * v;
+}
+
+float3 EnvBlops2(float3 f0, float rough, float NoV)
+{
+ float g = CalcGlossmap(rough);
+ float3 f90Atten = saturate(50 * f0); // UE4 specular shadowing
+
+ float4 t = float4(1 / 0.96, 0.475, (0.0275 - 0.25 * 0.04) / 0.96, 0.25);
+ t *= float4(g, g, g, g);
+ t += float4(0, 0, (0.015 - 0.75 * 0.04) / 0.96, 0.75);
+
+ float a0 = t.x * min(t.y, exp2(-9.28 * NoV)) + t.z;
+ float a1 = t.w;
+
+ return saturate(f90Atten * a0 + f0 * (a1 - a0));
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_ggx.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_ggx.h
new file mode 100644
index 0000000000..4ef624a1b6
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_brdf_ggx.h
@@ -0,0 +1,119 @@
+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);
+}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_cubemap_check.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_cubemap_check.h
new file mode 100644
index 0000000000..b3d485283b
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_cubemap_check.h
@@ -0,0 +1,2 @@
+// No PBR Cubemaps
+//#define USE_PBR_CUBEMAPS
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_settings.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_settings.h
new file mode 100644
index 0000000000..d8ad3bfd78
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pbr_settings.h
@@ -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
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pnv.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pnv.h
index 10ab152031..94dc220d8a 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pnv.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/pnv.h
@@ -21,7 +21,7 @@
float4 calc_night_vision_effect(float2 tc0, float4 color, float3 NV_COLOR)
{
- float lum = dot(color.rgb, float3(0.3f, 0.38f, 0.22f) * NV_BRIGHTNESS); // instead of float3 use LUMINANCE_floatTOR in stalker
+ float lum = dot(color.rgb, LUMINANCE_VECTOR * NV_BRIGHTNESS); // instead of float3 use LUMINANCE_floatTOR in stalker
color.rgb = NV_COLOR * lum;
// cheap noise function
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_apply_gloss.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_apply_gloss.ps
index 24f50c6840..7d1bea1a6c 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_apply_gloss.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_apply_gloss.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_patch_normal.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_patch_normal.ps
index 1b18f217e3..456193a53f 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_patch_normal.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/rain_patch_normal.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_common_ripples.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_common_ripples.h
index acc5db618e..736c328f17 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_common_ripples.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_common_ripples.h
@@ -1,43 +1,61 @@
/**
- * @ Version: SCREEN SPACE SHADERS - UPDATE 12
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 18
* @ Description: Ripples code
- * @ Modified time: 2022-10-29 05:05
+ * @ 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 float4 SSFX_ripples_timemul = float4(1.0f, 0.85f, 0.93f, 1.13f);
-static const float4 SSFX_ripples_timeadd = float4(0.0f, 0.2f, 0.45f, 0.7f);
+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);
-// https://seblagarde.wordpress.com/2013/01/03/water-drop-2b-dynamic-rain-and-its-effects/
-float3 SSFX_computeripple(float4 Ripple, float CurrentTime, float Weight)
+static const float SSFX_ripples_PI = 3.141592f;
+
+float2 ssfx_process_ripples(float4 ripples, float3 setup)
{
- Ripple.yz = Ripple.yz * 2 - 1; // Decompress perturbation
+ // 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
- float DropFrac = frac(Ripple.w + CurrentTime); // Apply time shift
- float TimeFrac = DropFrac - 1.0f + Ripple.x;
- float DropFactor = saturate(0.2f + Weight * 0.8f - DropFrac);
- float FinalFactor = DropFactor * Ripple.x * sin(clamp(TimeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359f);
+ // Fade
+ FinalFactor *= smoothstep(4.0f, 0, RFreq);
- return float3(Ripple.yz * FinalFactor * 0.65f, 1.0f);
+ // Apply intensity
+ ripples_N *= FinalFactor * setup.y;
+
+ return ripples_N;
}
-float3 SSFX_ripples(Texture2D ripple_tex, float2 tc)
+float2 ssfx_rain_ripples(Texture2D ripples_tex, float2 uvs, float3 setup, float depth)
{
- float4 Times = (timers.x * SSFX_ripples_timemul + SSFX_ripples_timeadd) * 1.5f;
- Times = frac(Times);
+ // Falloff
+ float Dist = 15.0f - depth;
+
+ // Discard when depth > 15
+ if (Dist < 0)
+ return 0;
- float4 Weights = float4(0, 1.0, 0.65, 0.25);
+ // 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);
- // Compute ripples
- float3 Ripple1 = SSFX_computeripple(ripple_tex.Sample(smp_base, tc + float2(0.25f, 0.0f)), Times.x, Weights.x);
- float3 Ripple2 = SSFX_computeripple(ripple_tex.Sample(smp_base, tc + float2(-0.55f, 0.3f)), Times.y, Weights.y);
- float3 Ripple3 = SSFX_computeripple(ripple_tex.Sample(smp_base, tc + float2(0.6f, 0.85f)), Times.z, Weights.z);
- float3 Ripple4 = SSFX_computeripple(ripple_tex.Sample(smp_base, tc + float2(0.5f, -0.75f)), Times.w, Weights.w);
+ // 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));
- Weights = saturate(Weights * 4);
- float4 Z = lerp(1, float4(Ripple1.z, Ripple2.z, Ripple3.z, Ripple4.z), Weights);
- float3 Normal = float3(Weights.x * Ripple1.xy + Weights.y * Ripple2.xy + Weights.z * Ripple3.xy + Weights.w * Ripple4.xy, Z.x * Z.y * Z.z * Z.w);
+ result *= Dist * 0.0666f; // 0.0 ~ 15.0 To 0.0 ~ 1.0
- return normalize(Normal) * 0.5 + 0.5;
+ return clamp(result, -1.0f, 1.0f);
}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_fog.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_fog.h
index 4889f360a3..5c938cd7b5 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_fog.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_fog.h
@@ -32,7 +32,7 @@ float SSFX_HEIGHT_FOG(float3 P, float World_Py, inout float3 color)
float3 FOG_COLOR = lerp(fog_color, Sun, FogBlend);
// Apply fog to color
- color = lerp(color, FOG_COLOR * 2.0f / 3.0f, fogresult);
+ color = lerp(color, FOG_COLOR, fogresult);
// Return distance fog.
return fog;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_reflections.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_reflections.h
index 956669b65e..48e98795a9 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_reflections.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_reflections.h
@@ -1,7 +1,7 @@
/**
- * @ Version: SCREEN SPACE SHADERS - UPDATE 14.3
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 18
* @ Description: SSR implementation
- * @ Modified time: 2023-01-29 08:40
+ * @ Modified time: 2023-09-29 06:42
* @ Author: https://www.moddb.com/members/ascii1457
* @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
*/
@@ -9,7 +9,7 @@
#include "screenspace_common.h"
#include "settings_screenspace_SSR.h"
-uniform float4 rain_params;
+uniform float4 ssfx_is_underground;
static const int2 q_ssr_steps[6] =
{
@@ -163,9 +163,9 @@ void SSFX_ScreenSpaceReflections(float2 tc, float4 P, float3 N, float gloss, ino
// Sky is the reflection base...
#ifdef G_SSR_CHEAP_SKYBOX
- reflection = SSFX_calc_env(v2reflect) * G_SSR_SKY_INTENSITY;
+ reflection = SSFX_calc_env(v2reflect) * G_SSR_SKY_INTENSITY * !ssfx_is_underground.x;
#else
- reflection = SSFX_calc_sky(v2reflect) * G_SSR_SKY_INTENSITY;
+ reflection = SSFX_calc_sky(v2reflect) * G_SSR_SKY_INTENSITY * !ssfx_is_underground.x;
#endif
// Valid UV coor? SSFX_trace_ssr_ray return 0.0f if uv is out of bounds or sky.
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_wind.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_wind.h
new file mode 100644
index 0000000000..0e8856bfd9
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/screenspace_wind.h
@@ -0,0 +1,163 @@
+/**
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 19
+ * @ Description: Wind Main File
+ * @ Modified time: 2023-11-23 21:02
+ * @ Author: https://www.moddb.com/members/ascii1457
+ * @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
+ */
+
+// wind_direction wind_velocity E.m_fTreeAmplitudeIntensity
+uniform float4 wind_params;
+
+uniform float4 ssfx_wind; // DBG: X: Wind intensity - Y: North Dir - Z: South Dir
+uniform float4 ssfx_wind_gust; // X: Intensity
+uniform float4 ssfx_wind_anim;
+
+uniform float is_bugged_flora;
+
+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 : [x:time] [y:TreeAmplitudeIntensity] [z:gust] [w:ExtraPerlin]
+ wind_setup wsetup;
+
+ // Direction, speed and wind gust.
+ wsetup.direction = normalize(ssfx_wind.yz);
+
+ if (ssfx_wind.y == 0 && ssfx_wind.z == 0)
+ {
+ // Radians to Vector
+ float r = -wind_params.x + 1.57079f;
+ wsetup.direction = float2(cos(r), sin(r));
+ }
+
+ wsetup.speed = saturate(ssfx_wind.x);
+
+ if (wsetup.speed <= 0)
+ wsetup.speed = saturate(wind_params.y * 0.001);
+
+ wsetup.sqrt_speed = saturate(sqrt(wsetup.speed * 1.66f));
+
+ wsetup.trees_animspeed = 11.0f;
+ wsetup.trees_trunk_animspeed = 0.15f;
+ wsetup.trees_bend = 0.5f;
+
+ wsetup.grass_animspeed = 10.0;
+ wsetup.grass_turbulence = 1.5f;
+ wsetup.grass_push = 1.5f;
+ wsetup.grass_wave = 0.2f;
+
+ 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) * W.sqrt_speed;
+
+ // Grass Motion ( -1.0 ~ 1.0 ). Turbulence.
+ float2 GrassMotion = (Flow.xy * 2.0f - 1.0f) * W.sqrt_speed * W.grass_turbulence;
+
+ // Apply wind direction and flow. Wind push.
+ float2 WindDir = Flow.z * W.sqrt_speed * 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) * 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) * ssfx_wind_gust.x * W.trees_bend;
+
+ float WSpeed = saturate(W.sqrt_speed * 1.5f);
+
+ // Base wind speed displacement
+ float Base_Bend = WSpeed * 0.007f * 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 = 0;
+
+ // Base Motion
+ if (!is_bugged_flora)
+ branchMotion.xyz = 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
+ if (!is_bugged_flora)
+ 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
+ if (!is_bugged_flora)
+ branchMotion *= (1.0f - tc_y) * W.speed;
+
+ // Add trunk animation
+ branchMotion.xz += Trunk.xy;
+
+ return branchMotion;
+}
+
+#endif
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_FLORA.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_FLORA.h
index 71134c0388..d8d4cbc8f0 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_FLORA.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_FLORA.h
@@ -1,5 +1,9 @@
// [ SETTINGS ] [ FLORA FIXES ]
-#define G_TREES_SPECULAR 1.0f // Trees specular intensity
-#define G_GRASS_SPECULAR 1.0f // Grass specular intensity
-#define G_SSS_INTENSITY 0.5f // Subsurface Scattering intensity
+#ifndef settings_screenspace_FLORA
+#define settings_screenspace_FLORA
+
+uniform float4 ssfx_florafixes_1;
+uniform float4 ssfx_florafixes_2;
+
+#endif
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_SSR.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_SSR.h
index 5f5a721f3d..2c7d5dd2bf 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_SSR.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_SSR.h
@@ -7,7 +7,7 @@
#define G_SSR_INTENSITY 1.3f // Global reflection intensity ( 1.0f = 100% ~ 0.0f = 0% )
#define G_SSR_MAX_INTENSITY 0.5f // Global reflection MAX intensity.
#define G_SSR_SKY_INTENSITY 0.6f // Sky reflection intensity ( 1.0f = 100% ~ 0.0f = 0% )
-#define G_SSR_FLORA_INTENSITY 0.5f // Adjust grass and tree branches intensity
+#define G_SSR_FLORA_INTENSITY 0.2f // Adjust grass and tree branches intensity
#define G_SSR_TERRAIN_BUMP_INTENSITY 0.6f // Terrain bump intensity ( Lower values will generate cleaner reflections )
#define G_SSR_WEAPON_INTENSITY 0.5f // Weapons & arms reflection intensity. ( 1.0f = 100% ~ 0.0f = 0% )
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_WATER.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_WATER.h
index 6e6a2e27bb..9e51e8c194 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_WATER.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/settings_screenspace_WATER.h
@@ -14,7 +14,7 @@
#define G_SSR_WATER_FOG_MAXDEPTH 2.0f // Maximum visibility underwater.
-#define G_SSR_WATER_RAIN 0.4f // Max intensity of rain drops
+#define G_SSR_WATER_RAIN 1.25f // Intensity of rain ripples
#define G_SSR_WATER_SPECULAR 6.0f // Sun/Moon specular intensity
#define G_SSR_WATER_SPECULAR_NORMAL 0.2f // Specular normal intensity. ( You may need to adjust this if you change the value of G_SSR_WATER_WAVES )
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow.h
index 54487e4484..45fd7bcfcf 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow.h
@@ -16,10 +16,6 @@ sampler smp_jitter;
Texture2D jitter0;
Texture2D jitter1;
-// uniform sampler2D jitter2;
-// uniform sampler2D jitter3;
-// uniform float4 jitterS;
-
Texture2D jitterMipped;
#ifndef USE_ULTRA_SHADOWS
@@ -28,6 +24,11 @@ Texture2D jitterMipped;
#define KERNEL 1.0f
#endif
+#define PCSS_PIXEL int(4)
+#define PCSS_STEP int(2)
+#define PCSS_PIXEL_MIN float(1.0)
+#define PCSS_SUN_WIDTH float(150.0)
+
float modify_light(float light) { return (light > 0.7 ? 1.0 : lerp(0.0, 1.0, saturate(light / 0.7))); }
//////////////////////////////////////////////////////////////////////////////////////////
@@ -43,8 +44,6 @@ float sample_hw_pcf(float4 tc, float4 shift)
return s_smap.SampleCmpLevelZero(smp_smap, tc.xy, tc.z).x;
}
-#define GS2 3
-
float shadow_hw(float4 tc)
{
float s0 = sample_hw_pcf(tc, float4(-1, -1, 0, 0));
@@ -55,452 +54,6 @@ float shadow_hw(float4 tc)
return (s0 + s1 + s2 + s3) / 4.h;
}
-#if SUN_QUALITY >= 4
-#define FILTER_SIZE 11
-#define FS FILTER_SIZE
-#define FS2 (FILTER_SIZE / 2)
-
-static const float W2[11][11] = {
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.0}, {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0},
- {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0}, {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0}, {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0},
- {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0}, {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0}, {0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0},
- {0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-};
-
-static const float W1[11][11] = {
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.0, 0.0},
- {0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0}, {0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0}, {0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0},
- {0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0}, {0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0}, {0.0, 0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-};
-
-static const float W0[11][11] = {
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.1, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.1, 1.0, 0.1, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.1, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-};
-
-float Fw(int r, int c, float fL)
-{
- return (1.0 - fL) * (1.0 - fL) * (1.0 - fL) * W0[r][c] + 3.0f * (1.0 - fL) * (1.0 - fL) * fL * W1[r][c] + 3.0f * fL * fL * (1.0 - fL) * W2[r][c] + fL * fL * fL * 1.0f;
-}
-
-#define BLOCKER_FILTER_SIZE 11
-#define BFS BLOCKER_FILTER_SIZE
-#define BFS2 (BLOCKER_FILTER_SIZE / 2)
-
-#define SUN_WIDTH 300.0f
-
-// uses gather for DX11/10.1 and visibilty encoding for DX10.0
-float shadow_extreme_quality(float3 tc)
-{
- float s = 0.0f;
- float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
- float2 tcs = floor(stc);
- float2 fc;
- int row;
- int col;
- float w = 0.0;
- float avgBlockerDepth = 0;
- float blockerCount = 0;
- float fRatio;
- float4 v1[FS2 + 1];
- float2 v0[FS2 + 1];
- float2 off;
-
- fc = stc - tcs;
- tc.xy = tc.xy - ((1.0f / SMAP_size) * fc);
- tc.z -= 0.0001f;
-
-#if defined(SM_4_1) || defined(SM_5)
- // find number of blockers and sum up blocker depth
- for (row = -BFS2; row <= BFS2; row += 2)
- {
- for (col = -BFS2; col <= BFS2; col += 2)
- {
- float4 d4 = s_smap.Gather(smp_nofilter, tc.xy, int2(col, row));
- float4 b4 = (tc.zzzz <= d4) ? (0.0f).xxxx : (1.0f).xxxx;
-
- blockerCount += dot(b4, (1.0f).xxxx);
- avgBlockerDepth += dot(d4, b4);
- }
- }
-#else // SM_4_0
- uint vmask[FS + 1];
-
- [unroll] for (col = 0; col <= FS; ++col) vmask[col] = uint(0);
-
- [unroll(11)] for (row = -FS2; row <= FS2; row += 2)
- {
- [unroll] for (int col = -FS2; col <= FS2; col += 2)
- {
- float4 d4;
- float b;
-
- d4.w = s_smap.SampleLevel(smp_nofilter, tc.xy, 0, int2(col, row)).x;
- b = (tc.z <= d4.w) ? (0.0f) : (1.0f);
- vmask[col + FS2 + 0] += ((tc.z <= d4.w) ? (uint(1) << uint(row + FS2 + 0)) : uint(0));
- blockerCount += b;
- avgBlockerDepth += d4.w * b;
-
- d4.z = s_smap.SampleLevel(smp_nofilter, tc.xy, 0, int2(col + 1, row)).x;
- b = (tc.z <= d4.z) ? (0.0f) : (1.0f);
- vmask[col + FS2 + 1] += ((tc.z <= d4.z) ? (uint(1) << uint(row + FS2 + 0)) : uint(0));
- blockerCount += b;
- avgBlockerDepth += d4.z * b;
-
- d4.x = s_smap.SampleLevel(smp_nofilter, tc.xy, 0, int2(col, row + 1)).x;
- vmask[col + FS2 + 0] += ((tc.z <= d4.x) ? (uint(1) << uint(row + FS2 + 1)) : uint(0));
- b = (tc.z <= d4.x) ? (0.0f) : (1.0f);
- blockerCount += b;
- avgBlockerDepth += d4.x * b;
-
- d4.y = s_smap.SampleLevel(smp_nofilter, tc.xy, 0, int2(col + 1, row + 1)).x;
- vmask[col + FS2 + 1] += ((tc.z <= d4.y) ? (uint(1) << uint(row + FS2 + 1)) : uint(0));
- b = (tc.z <= d4.y) ? (0.0f) : (1.0f);
- blockerCount += b;
- avgBlockerDepth += d4.y * b;
- }
- }
-#endif
-
- // compute ratio average blocker depth vs. pixel depth
- if (blockerCount > 0.0)
- {
- avgBlockerDepth /= blockerCount;
- fRatio = saturate(((tc.z - avgBlockerDepth) * SUN_WIDTH) / avgBlockerDepth);
- fRatio *= fRatio;
- }
- else
- {
- fRatio = 0.0;
- }
-
- for (row = 0; row < FS; ++row)
- {
- for (col = 0; col < FS; ++col)
- w += Fw(row, col, fRatio);
- }
-
- // filter shadow map samples using the dynamic weights
- [unroll(11)] for (row = -FS2; row <= FS2; row += 2)
- {
- [unroll] for (int col = -FS2; col <= FS2; col += 2)
- {
-#if (defined(SM_5)) || (defined(SM_4_1))
-#ifdef SM_5
- v1[(col + FS2) / 2] = s_smap.GatherCmpRed(smp_smap, tc.xy, tc.z, int2(col, row));
-#else // SM_4_1
- float4 d4 = s_smap.Gather(smp_linear, tc.xy, int2(col, row));
- v1[(col + FS2) / 2] = (tc.zzzz <= d4) ? (1.0f).xxxx : (0.0f).xxxx;
-#endif
-#else
- v1[(col + FS2) / 2].w = ((vmask[col + FS2 + 0] & (uint(1) << uint(row + FS2 + 0))) ? 1.0f : 0.0f);
- v1[(col + FS2) / 2].z = ((vmask[col + FS2 + 1] & (uint(1) << uint(row + FS2 + 0))) ? 1.0f : 0.0f);
- v1[(col + FS2) / 2].x = ((vmask[col + FS2 + 0] & (uint(1) << uint(row + FS2 + 1))) ? 1.0f : 0.0f);
- v1[(col + FS2) / 2].y = ((vmask[col + FS2 + 1] & (uint(1) << uint(row + FS2 + 1))) ? 1.0f : 0.0f);
-#endif
- if (col == -FS2)
- {
- s += (1 - fc.y) *
- (v1[0].w * (Fw(row + FS2, 0, fRatio) - Fw(row + FS2, 0, fRatio) * fc.x) +
- v1[0].z * (fc.x * (Fw(row + FS2, 0, fRatio) - Fw(row + FS2, 1, fRatio)) + Fw(row + FS2, 1, fRatio)));
- s += (fc.y) *
- (v1[0].x * (Fw(row + FS2, 0, fRatio) - Fw(row + FS2, 0, fRatio) * fc.x) +
- v1[0].y * (fc.x * (Fw(row + FS2, 0, fRatio) - Fw(row + FS2, 1, fRatio)) + Fw(row + FS2, 1, fRatio)));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[0].x * (Fw(row + FS2 - 1, 0, fRatio) - Fw(row + FS2 - 1, 0, fRatio) * fc.x) +
- v0[0].y * (fc.x * (Fw(row + FS2 - 1, 0, fRatio) - Fw(row + FS2 - 1, 1, fRatio)) + Fw(row + FS2 - 1, 1, fRatio)));
- s += (fc.y) *
- (v1[0].w * (Fw(row + FS2 - 1, 0, fRatio) - Fw(row + FS2 - 1, 0, fRatio) * fc.x) +
- v1[0].z * (fc.x * (Fw(row + FS2 - 1, 0, fRatio) - Fw(row + FS2 - 1, 1, fRatio)) + Fw(row + FS2 - 1, 1, fRatio)));
- }
- }
- else if (col == FS2)
- {
- s += (1 - fc.y) *
- (v1[FS2].w * (fc.x * (Fw(row + FS2, FS - 2, fRatio) - Fw(row + FS2, FS - 1, fRatio)) + Fw(row + FS2, FS - 1, fRatio)) +
- v1[FS2].z * fc.x * Fw(row + FS2, FS - 1, fRatio));
- s += (fc.y) *
- (v1[FS2].x * (fc.x * (Fw(row + FS2, FS - 2, fRatio) - Fw(row + FS2, FS - 1, fRatio)) + Fw(row + FS2, FS - 1, fRatio)) +
- v1[FS2].y * fc.x * Fw(row + FS2, FS - 1, fRatio));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[FS2].x * (fc.x * (Fw(row + FS2 - 1, FS - 2, fRatio) - Fw(row + FS2 - 1, FS - 1, fRatio)) + Fw(row + FS2 - 1, FS - 1, fRatio)) +
- v0[FS2].y * fc.x * Fw(row + FS2 - 1, FS - 1, fRatio));
- s += (fc.y) *
- (v1[FS2].w * (fc.x * (Fw(row + FS2 - 1, FS - 2, fRatio) - Fw(row + FS2 - 1, FS - 1, fRatio)) + Fw(row + FS2 - 1, FS - 1, fRatio)) +
- v1[FS2].z * fc.x * Fw(row + FS2 - 1, FS - 1, fRatio));
- }
- }
- else
- {
- s += (1 - fc.y) *
- (v1[(col + FS2) / 2].w * (fc.x * (Fw(row + FS2, col + FS2 - 1, fRatio) - Fw(row + FS2, col + FS2 + 0, fRatio)) + Fw(row + FS2, col + FS2 + 0, fRatio)) +
- v1[(col + FS2) / 2].z * (fc.x * (Fw(row + FS2, col + FS2 - 0, fRatio) - Fw(row + FS2, col + FS2 + 1, fRatio)) + Fw(row + FS2, col + FS2 + 1, fRatio)));
- s += (fc.y) *
- (v1[(col + FS2) / 2].x * (fc.x * (Fw(row + FS2, col + FS2 - 1, fRatio) - Fw(row + FS2, col + FS2 + 0, fRatio)) + Fw(row + FS2, col + FS2 + 0, fRatio)) +
- v1[(col + FS2) / 2].y * (fc.x * (Fw(row + FS2, col + FS2 - 0, fRatio) - Fw(row + FS2, col + FS2 + 1, fRatio)) + Fw(row + FS2, col + FS2 + 1, fRatio)));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[(col + FS2) / 2].x *
- (fc.x * (Fw(row + FS2 - 1, col + FS2 - 1, fRatio) - Fw(row + FS2 - 1, col + FS2 + 0, fRatio)) + Fw(row + FS2 - 1, col + FS2 + 0, fRatio)) +
- v0[(col + FS2) / 2].y *
- (fc.x * (Fw(row + FS2 - 1, col + FS2 - 0, fRatio) - Fw(row + FS2 - 1, col + FS2 + 1, fRatio)) + Fw(row + FS2 - 1, col + FS2 + 1, fRatio)));
- s += (fc.y) *
- (v1[(col + FS2) / 2].w *
- (fc.x * (Fw(row + FS2 - 1, col + FS2 - 1, fRatio) - Fw(row + FS2 - 1, col + FS2 + 0, fRatio)) + Fw(row + FS2 - 1, col + FS2 + 0, fRatio)) +
- v1[(col + FS2) / 2].z *
- (fc.x * (Fw(row + FS2 - 1, col + FS2 - 0, fRatio) - Fw(row + FS2 - 1, col + FS2 + 1, fRatio)) + Fw(row + FS2 - 1, col + FS2 + 1, fRatio)));
- }
- }
- if (row != FS2)
- v0[(col + FS2) / 2] = v1[(col + FS2) / 2].xy;
- }
- }
-
- return s / w;
-}
-
-float4 Fw(int r, int c) { return float4(W0[r][c], W1[r][c], W2[r][c], 1.0f); }
-
-//======================================================================================
-// This shader computes the contact hardening shadow filter
-//======================================================================================
-float shadow_extreme_quality_fused(float3 tc)
-{
- float4 s = (0.0f).xxxx;
- float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
- float2 tcs = floor(stc);
- float2 fc;
- int row;
- int col;
- float w = 0.0;
- float avgBlockerDepth = 0;
- float blockerCount = 0;
- float fRatio;
- float4 v1[FS2 + 1];
- float2 v0[FS2 + 1];
- float2 off;
-
- fc = stc - tcs;
- tc.xy = tc.xy - (fc * (1.0f / SMAP_size));
-
- // filter shadow map samples using the dynamic weights
- [unroll(FS)] for (row = -FS2; row <= FS2; row += 2)
- {
- for (col = -FS2; col <= FS2; col += 2)
- {
- float4 d4;
-
-#ifndef PS_4
- d4 = s_smap.Gather(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row));
-#else
- d4.w = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row), 0).x;
- d4.z = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col + 1, row), 0).x;
- d4.y = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col + 1, row + 1), 0).x;
- d4.x = s_smap.SampleLevel(smp_nofilter, tc.xy + (1.0f / SMAP_size) * float2(col, row + 1), 0).x;
-#endif
- float4 b4 = (tc.zzzz <= d4) ? (0.0f).xxxx : (1.0f).xxxx;
-
- v1[(col + FS2) / 2] = (tc.zzzz <= d4) ? (1.0f).xxxx : (0.0f).xxxx;
- blockerCount += dot(b4, (1.0).xxxx);
- avgBlockerDepth += dot(d4, b4);
-
- if (col == -FS2)
- {
- s += (1 - fc.y) * (v1[0].w * (Fw(row + FS2, 0) - Fw(row + FS2, 0) * fc.x) + v1[0].z * (fc.x * (Fw(row + FS2, 0) - Fw(row + FS2, 1)) + Fw(row + FS2, 1)));
- s += (fc.y) * (v1[0].x * (Fw(row + FS2, 0) - Fw(row + FS2, 0) * fc.x) + v1[0].y * (fc.x * (Fw(row + FS2, 0) - Fw(row + FS2, 1)) + Fw(row + FS2, 1)));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[0].x * (Fw(row + FS2 - 1, 0) - Fw(row + FS2 - 1, 0) * fc.x) + v0[0].y * (fc.x * (Fw(row + FS2 - 1, 0) - Fw(row + FS2 - 1, 1)) + Fw(row + FS2 - 1, 1)));
- s += (fc.y) *
- (v1[0].w * (Fw(row + FS2 - 1, 0) - Fw(row + FS2 - 1, 0) * fc.x) + v1[0].z * (fc.x * (Fw(row + FS2 - 1, 0) - Fw(row + FS2 - 1, 1)) + Fw(row + FS2 - 1, 1)));
- }
- }
- else if (col == FS2)
- {
- s += (1 - fc.y) * (v1[FS2].w * (fc.x * (Fw(row + FS2, FS - 2) - Fw(row + FS2, FS - 1)) + Fw(row + FS2, FS - 1)) + v1[FS2].z * fc.x * Fw(row + FS2, FS - 1));
- s += (fc.y) * (v1[FS2].x * (fc.x * (Fw(row + FS2, FS - 2) - Fw(row + FS2, FS - 1)) + Fw(row + FS2, FS - 1)) + v1[FS2].y * fc.x * Fw(row + FS2, FS - 1));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[FS2].x * (fc.x * (Fw(row + FS2 - 1, FS - 2) - Fw(row + FS2 - 1, FS - 1)) + Fw(row + FS2 - 1, FS - 1)) + v0[FS2].y * fc.x * Fw(row + FS2 - 1, FS - 1));
- s += (fc.y) *
- (v1[FS2].w * (fc.x * (Fw(row + FS2 - 1, FS - 2) - Fw(row + FS2 - 1, FS - 1)) + Fw(row + FS2 - 1, FS - 1)) + v1[FS2].z * fc.x * Fw(row + FS2 - 1, FS - 1));
- }
- }
- else
- {
- s += (1 - fc.y) *
- (v1[(col + FS2) / 2].w * (fc.x * (Fw(row + FS2, col + FS2 - 1) - Fw(row + FS2, col + FS2 + 0)) + Fw(row + FS2, col + FS2 + 0)) +
- v1[(col + FS2) / 2].z * (fc.x * (Fw(row + FS2, col + FS2 - 0) - Fw(row + FS2, col + FS2 + 1)) + Fw(row + FS2, col + FS2 + 1)));
- s += (fc.y) *
- (v1[(col + FS2) / 2].x * (fc.x * (Fw(row + FS2, col + FS2 - 1) - Fw(row + FS2, col + FS2 + 0)) + Fw(row + FS2, col + FS2 + 0)) +
- v1[(col + FS2) / 2].y * (fc.x * (Fw(row + FS2, col + FS2 - 0) - Fw(row + FS2, col + FS2 + 1)) + Fw(row + FS2, col + FS2 + 1)));
- if (row > -FS2)
- {
- s += (1 - fc.y) *
- (v0[(col + FS2) / 2].x * (fc.x * (Fw(row + FS2 - 1, col + FS2 - 1) - Fw(row + FS2 - 1, col + FS2 + 0)) + Fw(row + FS2 - 1, col + FS2 + 0)) +
- v0[(col + FS2) / 2].y * (fc.x * (Fw(row + FS2 - 1, col + FS2 - 0) - Fw(row + FS2 - 1, col + FS2 + 1)) + Fw(row + FS2 - 1, col + FS2 + 1)));
- s += (fc.y) *
- (v1[(col + FS2) / 2].w * (fc.x * (Fw(row + FS2 - 1, col + FS2 - 1) - Fw(row + FS2 - 1, col + FS2 + 0)) + Fw(row + FS2 - 1, col + FS2 + 0)) +
- v1[(col + FS2) / 2].z * (fc.x * (Fw(row + FS2 - 1, col + FS2 - 0) - Fw(row + FS2 - 1, col + FS2 + 1)) + Fw(row + FS2 - 1, col + FS2 + 1)));
- }
- }
-
- if (row != FS2)
- {
- v0[(col + FS2) / 2] = v1[(col + FS2) / 2].xy;
- }
- }
- }
-
- // compute ratio using formulas from PCSS
- if (blockerCount > 0.0)
- {
- avgBlockerDepth /= blockerCount;
- fRatio = saturate(((tc.z - avgBlockerDepth) * SUN_WIDTH) / avgBlockerDepth);
- fRatio *= fRatio;
- }
- else
- {
- fRatio = 0.0;
- }
-
- // sum up weights of dynamic filter matrix
- for (row = 0; row < FS; ++row)
- {
- for (col = 0; col < FS; ++col)
- {
- w += Fw(row, col, fRatio);
- }
- }
-
- return dot(s,
- float4((1.0f - fRatio) * (1.0f - fRatio) * (1.0f - fRatio), 3.0f * (1.0 - fRatio) * (1.0 - fRatio) * fRatio, 3.0f * fRatio * fRatio * (1.0 - fRatio),
- fRatio * fRatio * fRatio)) /
- w;
-}
-#endif
-
-#ifdef SM_4_1
-
-float dx10_1_hw_hq_7x7(float3 tc)
-{
- float s = 0.0f;
- float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
- float2 tcs = floor(stc);
- float2 fc;
- int row;
- int col;
-
- fc.xy = stc - tcs;
- tc.xy = tcs * (1.0 / SMAP_size);
-
- // loop over the rows
- for (row = -GS2; row <= GS2; row += 2)
- {
- [unroll] for (col = -GS2; col <= GS2; col += 2)
- {
- float4 v = (tc.zzzz <= s_smap.Gather(smp_nofilter, tc.xy, int2(col, row))) ? (1.0).xxxx : (0.0).xxxx;
-
- if (row == -GS2) // top row
- {
- if (col == -GS2) // left
- s += dot(float4(1.0 - fc.x, 1.0, 1.0 - fc.y, (1.0 - fc.x) * (1.0 - fc.y)), v);
- else if (col == GS2) // right
- s += dot(float4(1.0f, fc.x, fc.x * (1.0 - fc.y), 1.0 - fc.y), v);
- else // center
- s += dot(float4(1.0, 1.0, 1.0 - fc.y, 1.0 - fc.y), v);
- }
- else if (row == GS2) // bottom row
- {
- if (col == -GS2) // left
- s += dot(float4((1.0 - fc.x) * fc.y, fc.y, 1.0, (1.0 - fc.x)), v);
- else if (col == GS2) // right
- s += dot(float4(fc.y, fc.x * fc.y, fc.x, 1.0), v);
- else // center
- s += dot(float4(fc.yy, 1.0, 1.0), v);
- }
- else // center rows
- {
- if (col == -GS2) // left
- s += dot(float4((1.0 - fc.x), 1.0, 1.0, (1.0 - fc.x)), v);
- else if (col == GS2) // right
- s += dot(float4(1.0, fc.x, fc.x, 1.0), v);
- else // center
- s += dot((1.0).xxxx, v);
- }
- }
- }
-
- return s * (1.0 / 49.0);
-}
-
-#endif
-
-float dx10_0_hw_hq_7x7(float4 tc)
-{
- tc.xyz /= tc.w;
-
- float s = 0.0;
- float2 stc = (SMAP_size * tc.xy) + float2(0.5, 0.5);
- float2 tcs = floor(stc);
- float2 fc;
-
- fc = stc - tcs;
- tc.xy = tc.xy - (fc * (1.0 / SMAP_size));
-
- float2 pwAB = ((2.0).xx - fc);
- float2 tcAB = (1.0 / SMAP_size).xx / pwAB;
- float2 tcM = (0.5 / SMAP_size).xx;
- float2 pwGH = ((1.0).xx + fc);
- float2 tcGH = (1.0 / SMAP_size) * (fc / pwGH);
-
- for (int row = -GS2; row <= GS2; row += 2)
- {
- for (int col = -GS2; col <= GS2; col += 2)
- {
- if (row == -GS2) // top row
- {
- if (col == -GS2) // left
- s += (pwAB.x * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcAB, tc.z, int2(col, row)).x;
- else if (col == GS2) // right
- s += (pwGH.x * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcGH.x, tcAB.y), tc.z, int2(col, row)).x;
- else // center
- s += (2.0 * pwAB.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcM.x, tcAB.y), tc.z, int2(col, row)).x;
- }
- else if (row == GS2) // bottom row
- {
- if (col == -GS2) // left
- s += (pwAB.x * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcAB.x, tcGH.y), tc.z, int2(col, row)).x;
- else if (col == GS2) // right
- s += (pwGH.x * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcGH, tc.z, int2(col, row)).x;
- else // center
- s += (2.0 * pwGH.y) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcM.x, tcGH.y), tc.z, int2(col, row)).x;
- }
- else // center rows
- {
- if (col == -GS2) // left
- s += (pwAB.x * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcAB.x, tcM.y), tc.z, int2(col, row)).x;
- else if (col == GS2) // right
- s += (pwGH.x * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + float2(tcGH.x, tcM.y), tc.z, int2(col, row)).x;
- else // center
- s += (2.0 * 2.0) * s_smap.SampleCmpLevelZero(smp_smap, tc.xy + tcM, tc.z, int2(col, row)).x;
- }
- }
- }
-
- return s / 49.0;
-}
-
#ifdef SM_MINMAX
bool cheap_reject(float3 tc, inout bool full_light)
{
@@ -536,42 +89,98 @@ bool cheap_reject(float3 tc, inout bool full_light)
}
}
+// Sunshafts
+float shadow_dx10_1_sunshafts(float4 tc, float2 pos2d)
+{
+ float3 t = tc.xyz / tc.w;
+ float minmax = s_smap_minmax.SampleLevel(smp_nofilter, t, 0).x;
+ bool umbra = ((minmax.x < 0) && (t.z > -minmax.x));
+
+ [branch] if (umbra) { return 0.0; }
+ else { return shadow_hw(tc); }
+}
#endif // SM_MINMAX
-float shadow_hw_hq(float4 tc)
+// PCSS shadows
+static const float2 poissonDisk[32] = {
+ float2(0.0617981, 0.07294159), float2(0.6470215, 0.7474022), float2(-0.5987766, -0.7512833), float2(-0.693034, 0.6913887), float2(0.6987045, -0.6843052),
+ float2(-0.9402866, 0.04474335), float2(0.8934509, 0.07369385), float2(0.1592735, -0.9686295), float2(-0.05664673, 0.995282), float2(-0.1203411, -0.1301079),
+ float2(0.1741608, -0.1682285), float2(-0.09369049, 0.3196758), float2(0.185363, 0.3213367), float2(-0.1493771, -0.3147511), float2(0.4452095, 0.2580113),
+ float2(-0.1080467, -0.5329178), float2(0.1604507, 0.5460774), float2(-0.4037193, -0.2611179), float2(0.5947998, -0.2146744), float2(0.3276062, 0.9244621),
+ float2(-0.6518704, -0.2503952), float2(-0.3580975, 0.2806469), float2(0.8587891, 0.4838005), float2(-0.1596546, -0.8791054), float2(-0.3096867, 0.5588146),
+ float2(-0.5128918, 0.1448544), float2(0.8581337, -0.424046), float2(0.1562584, -0.5610626), float2(-0.7647934, 0.2709858), float2(-0.3090832, 0.9020988),
+ float2(0.3935608, 0.4609676), float2(0.3929337, -0.5010948),
+};
+
+// Quality tokens --Fine
+#if !defined(SUN_QUALITY)
+#define PCSS_NUM_SAMPLES int(1)
+#elif SUN_QUALITY == 1
+#define PCSS_NUM_SAMPLES int(8)
+#elif SUN_QUALITY == 2
+#define PCSS_NUM_SAMPLES int(12)
+#elif SUN_QUALITY == 3
+#define PCSS_NUM_SAMPLES int(20)
+#elif (SUN_QUALITY == 4 || SUN_QUALITY == 5)
+#define PCSS_NUM_SAMPLES int(32)
+#endif
+
+float shadow_pcss(float4 tc)
{
-#ifdef SM_MINMAX
- bool full_light = false;
- bool cheap_path = cheap_reject(tc.xyz / tc.w, full_light);
+ // - Small modification to fix flickering and black squares.
+ // - Added a extra performance option with lower SUN_QUALITY settings.
+ // - Extended the blocker search from 3x3 to 4x4 for better results.
+ // https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders/
- [branch] if (cheap_path)
+ tc.xyz /= tc.w;
+
+#if SUN_QUALITY > 3 // Blocker search ( Penumbra ) and filter
+
+ int3 uv = int3(tc.xy * float(SMAP_size), 0);
+ float zBlock = tc.z - 0.0001;
+ float avgBlockerDepth = 0.0;
+ float blockerCount = 0.0;
+
+ [unroll] for (int row = -PCSS_PIXEL; row <= PCSS_PIXEL; row += PCSS_STEP)
{
- [branch] if (full_light == true) return 1.0;
- else return sample_hw_pcf(tc, (0).xxxx);
+ [unroll] for (int col = -PCSS_PIXEL; col <= PCSS_PIXEL; col += PCSS_STEP)
+ {
+ float shadowMapDepth = s_smap.Load(uv, int2(col, row)).x;
+ float b1 = (shadowMapDepth < zBlock) ? 1.0 : 0.0;
+ blockerCount += b1;
+ avgBlockerDepth += shadowMapDepth * b1;
+ }
}
- else
+
+ if (blockerCount < 1)
+ return 1.0;
+
+ avgBlockerDepth /= blockerCount;
+ float fRatio = saturate(((tc.z - avgBlockerDepth) * PCSS_SUN_WIDTH) / avgBlockerDepth);
+ fRatio *= fRatio;
+ fRatio = max(PCSS_PIXEL_MIN, fRatio * float(PCSS_PIXEL)) / float(SMAP_size);
+
+ float s = 0.0;
+ [unroll] for (uint i = 0; i < PCSS_NUM_SAMPLES; ++i)
{
-#if SUN_QUALITY >= 4 // extreme quality
- return shadow_extreme_quality(tc.xyz / tc.w);
-#else // SUN_QUALITY<4
-#ifdef SM_4_1
- return dx10_1_hw_hq_7x7(tc.xyz / tc.w);
-#else // SM_4_1
- return dx10_0_hw_hq_7x7(tc);
-#endif // SM_4_1
-#endif // SUN_QUALITY==4
+ float2 offset = poissonDisk[i] * fRatio;
+ s += s_smap.SampleCmpLevelZero(smp_smap, tc.xy + offset, tc.z).x;
}
-#else // SM_MINMAX
-#if SUN_QUALITY >= 4 // extreme quality
- return shadow_extreme_quality(tc.xyz / tc.w);
-#else // SUN_QUALITY<4
-#ifdef SM_4_1
- return dx10_1_hw_hq_7x7(tc.xyz / tc.w);
-#else // SM_4_1
- return dx10_0_hw_hq_7x7(tc);
-#endif // SM_4_1
-#endif // SUN_QUALITY==4
-#endif // SM_MINMAX
+ return s / PCSS_NUM_SAMPLES;
+
+#else // No blocker search ( Penumbra ), just filter
+
+ float fRatio = max(PCSS_PIXEL_MIN, 0.5f * float(PCSS_PIXEL)) / float(SMAP_size);
+
+ float s = 0.0;
+ [unroll] for (uint i = 0; i < PCSS_NUM_SAMPLES; ++i)
+ {
+ float2 offset = poissonDisk[i] * fRatio;
+ s += s_smap.SampleCmpLevelZero(smp_smap, tc.xy + offset, tc.z).x;
+ }
+ return s / PCSS_NUM_SAMPLES;
+
+#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -580,91 +189,43 @@ float shadow_hw_hq(float4 tc)
float4 test(float4 tc, float2 offset)
{
- // float4 tcx = float4 (tc.xy + tc.w*offset, tc.zw);
- // return tex2Dproj (s_smap,tcx);
-
tc.xyz /= tc.w;
tc.xy += offset;
return s_smap.SampleCmpLevelZero(smp_smap, tc.xy, tc.z).x;
}
-/*half shadowtest_sun (float4 tc, float4 tcJ) // jittered sampling
-{
- half4 r;
-
- const float scale = (0.5f/float(SMAP_size));
-
- float texsize = 2*SMAP_size;
- float2 tc_J = tc.xy/tc.w*texsize/8.0f;
- float2 fr = frac(tc_J)*.5f;
-
-// half4 J0 = tex2D (jitter0,fr)*scale;
-// half4 J1 = tex2D (jitter1,fr)*scale*2;
- float4 J0 = jitter0.Sample( smp_jitter, fr )*scale;
-// float4 J1 = jitter1.Sample( smp_jitter, fr )*scale;
-
- float k = 0.99f/float(SMAP_size);
- r.x = test (tc,J0.xy+float2(-k,-k)).x;
- r.y = test (tc,J0.wz+float2( k,-k)).y;
-
- r.z = test (tc,J0.xy+float2(-k, k)).z;
- r.w = test (tc,J0.wz+float2( k, k)).x;
-
- half4 f;
- float k1 = 1.5f/float(SMAP_size);
- f.x = test (tc,-J0.xy+float2(-k1,0)).x;
- f.y = test (tc,-J0.wz+float2( 0,-k1)).y;
-
- f.z = test (tc,-J0.xy+float2( k1, 0)).z;
- f.w = test (tc,-J0.wz+float2( 0, k1)).x;
-
- half res = ( r.x + r.y + r.z + r.w + f.x + f.y + f.z + f.w )*1.h/(4.h + 4.h );
- return res;
-}*/
half shadowtest_sun(float4 tc, float4 tcJ) // jittered sampling
{
half4 r;
+ const float scale = (0.7 / float(SMAP_size));
- // const float scale = (2.0f/float(SMAP_size));
- const float scale = (0.7f / float(SMAP_size));
-
- float2 tc_J = frac(tc.xy / tc.w * SMAP_size / 4.0f) * .5f;
+ float2 tc_J = frac(tc.xy / tc.w * SMAP_size / 4.0) * 0.5;
float4 J0 = jitter0.Sample(smp_jitter, tc_J) * scale;
- // half4 J1 = tex2D (jitter1,tc_J)*scale;
- const float k = .5f / float(SMAP_size);
+ const float k = 0.5 / float(SMAP_size);
r.x = test(tc, J0.xy + half2(-k, -k)).x;
r.y = test(tc, J0.wz + half2(k, -k)).y;
r.z = test(tc, -J0.xy + half2(-k, k)).z;
r.w = test(tc, -J0.wz + half2(k, k)).x;
- return dot(r, 1.h / 4.h);
+ return dot(r, 1.0 / 4.0);
}
-half shadow_high(float4 tc) // jittered sampling
+float shadow_hw_hq(float4 tc)
{
- const float scale = (0.5f / float(SMAP_size));
-
- float2 tc_J = frac(tc.xy / tc.w * SMAP_size / 4.0f) * .5f;
- float4 J0 = jitter0.Sample(smp_jitter, tc_J) * scale;
-
- const float k = 1.f / float(SMAP_size);
- half4 r;
- r.x = test(tc, J0.xy + half2(-k, -k)).x;
- r.y = test(tc, J0.wz + half2(k, -k)).y;
-
- r.z = test(tc, J0.xy + half2(-k, k)).z;
- r.w = test(tc, J0.wz + half2(k, k)).x;
-
- const float k1 = 1.3f / float(SMAP_size);
- half4 r1;
- r1.x = test(tc, -J0.xy + half2(-k1, 0)).x;
- r1.y = test(tc, -J0.wz + half2(0, -k1)).y;
-
- r1.z = test(tc, -2 * J0.xy + half2(k1, 0)).z;
- r1.w = test(tc, -2 * J0.wz + half2(0, k1)).x;
+#ifdef SM_MINMAX
+ bool full_light = false;
+ bool cheap_path = cheap_reject(tc.xyz / tc.w, full_light);
- return (r.x + r.y + r.z + r.w + r1.x + r1.y + r1.z + r1.w) * 1.h / 8.h;
+ [branch] if (cheap_path)
+ {
+ [branch] if (full_light == true) return 1.0;
+ else return sample_hw_pcf(tc, (0).xxxx);
+ }
+ else { return shadow_pcss(tc); }
+#else // SM_MINMAX
+ return shadow_pcss(tc);
+#endif // SM_MINMAX
}
float shadow(float4 tc)
@@ -676,69 +237,19 @@ float shadow(float4 tc)
return shadow_hw_hq(tc);
#endif
#else
-#if SUN_QUALITY >= 2 // Hight quality
- // return shadowtest_sun ( tc, float4(0,0,0,0) ); // jittered sampling;
- return shadow_hw(tc);
-#else
- return shadow_hw(tc);
-#endif
+ return shadow_pcss(tc);
#endif
}
-float shadow_volumetric(float4 tc) { return sample_hw_pcf(tc, float4(-1, -1, 0, 0)); }
-
-#ifdef SM_MINMAX
-
-//////////////////////////////////////////////////////////////////////////////////////////
-// hardware + PCF
-//////////////////////////////////////////////////////////////////////////////////////////
-
-float shadow_dx10_1(float4 tc, float2 tcJ, float2 pos2d) { return shadow(tc); }
-
-float shadow_dx10_1_sunshafts(float4 tc, float2 pos2d)
-{
- float3 t = tc.xyz / tc.w;
- float minmax = s_smap_minmax.SampleLevel(smp_nofilter, t, 0).x;
- bool umbra = ((minmax.x < 0) && (t.z > -minmax.x));
-
- [branch] if (umbra) { return 0.0; }
- else { return shadow_hw(tc); }
-}
-
-#endif
-
//////////////////////////////////////////////////////////////////////////////////////////
// testbed
-// uniform sampler2D jitter0;
-// uniform sampler2D jitter1;
-float shadowtest(float4 tc, float4 tcJ) // jittered sampling
-{
- float4 r;
-
- const float scale = (2.7f / float(SMAP_size));
-
- // float4 J0 = tex2Dproj (jitter0,tcJ)*scale;
- // float4 J1 = tex2Dproj (jitter1,tcJ)*scale;
- tcJ.xy /= tcJ.w;
- float4 J0 = jitter0.Sample(smp_jitter, tcJ) * scale;
- float4 J1 = jitter1.Sample(smp_jitter, tcJ) * scale;
-
- r.x = test(tc, J0.xy).x;
- r.y = test(tc, J0.wz).y;
- r.z = test(tc, J1.xy).z;
- r.w = test(tc, J1.wz).x;
-
- return dot(r, 1.h / 4.h);
-}
-
float shadow_rain(float4 tc, float2 tcJ) // jittered sampling
{
float4 r;
- const float scale = (4.0f / float(SMAP_size));
- // float4 J0 = jitter0.Sample( smp_jitter, tcJ )*scale;
- // float4 J1 = jitter1.Sample( smp_jitter, tcJ )*scale;
+ const float scale = (4.0 / float(SMAP_size));
+
float4 J0 = jitter0.Sample(smp_linear, tcJ) * scale;
float4 J1 = jitter1.Sample(smp_linear, tcJ) * scale;
@@ -746,27 +257,30 @@ float shadow_rain(float4 tc, float2 tcJ) // jittered sampling
r.y = test(tc, J0.wz).y;
r.z = test(tc, J1.xy).z;
r.w = test(tc, J1.wz).x;
-
- // float4 J0 = jitterMipped.Sample( smp_base, tcJ )*scale;
-
- // r.x = test (tc,J0.xy).x;
- // r.y = test (tc,J0.wz).y;
- // r.z = test (tc,J0.yz).z;
- // r.w = test (tc,J0.xw).x;
-
- return dot(r, 1.h / 4.h);
+ return dot(r, 1.0 / 4.0);
}
//////////////////////////////////////////////////////////////////////////////////////////
uniform float3x4 m_sunmask; // ortho-projection
#ifdef USE_SUNMASK
+float4 sun_shafts_intensity;
+
float sunmask(float4 P)
{
float2 tc = mul(m_sunmask, P);
- return s_lmap.SampleLevel(smp_linear, tc, 0).w; //Hemi map - ambient occlusion
+ float sunmask = s_lmap.SampleLevel(smp_linear, tc, 0).w;
+ float sunmask_correction;
+
+ const float intensity = 0.6, ss_bebuff = 10;
+
+ sunmask = sunmask * intensity + (1.0 - intensity);
+ sunmask_correction = saturate(sun_shafts_intensity.x * ss_bebuff);
+
+ sunmask = lerp(sunmask, 1.0h, sunmask_correction);
+ return sunmask;
}
#else
-float sunmask(float4 P) { return 1.h; } //
+float sunmask(float4 P) { return 1.0; } //
#endif
//////////////////////////////////////////////////////////////////////////////////////////
uniform float4x4 m_shadow;
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow_direct_tree.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow_direct_tree.vs
index dd985f9de7..d6bda4d602 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow_direct_tree.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shadow_direct_tree.vs
@@ -1,3 +1,11 @@
+/**
+ * @ Version: SCREEN SPACE SHADERS - UPDATE 19
+ * @ Description: Trees - Shadows
+ * @ Modified time: 2023-11-12 09:27
+ * @ Author: https://www.moddb.com/members/ascii1457
+ * @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
+ */
+
#include "common.h"
uniform float3x4 m_xform;
@@ -5,6 +13,7 @@ uniform float3x4 m_xform_v;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale, c_bias, wind, wave;
+#include "screenspace_wind.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Vertex
#ifdef USE_AREF
@@ -24,30 +33,30 @@ v2p_shadow_direct main(v_shadow_direct I)
//
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 inten = H * dp; // intensity
- float2 result;
+ float2 tc = 0;
+ float3 wind_result = 0;
#ifdef USE_TREEWAVE
- result = 0;
+ wind_result = 0;
#else // USE_TREEWAVE
#ifdef USE_AREF
- float frac = I.tc.z * consts.x; // fractional (or rigidity)
-#else // USE_AREF
- float frac = 0;
-#endif // USE_AREF
- result = calc_xz_wave(wind.xz * inten, frac);
-#endif // USE_TREEWAVE
+ tc = (I.tc * consts).xy;
+ wind_result = ssfx_wind_tree_branches(pos, H, tc.y, ssfx_wind_setup());
+#else
+ wind_result.xz = ssfx_wind_tree_trunk(pos, H, ssfx_wind_setup()).xy;
+#endif
+
+#endif
- float4 f_pos = float4(pos.x + result.x, pos.y, pos.z + result.y, 1);
+ float4 f_pos = float4(pos.xyz + wind_result.xyz, 1);
O.hpos = mul(m_VP, f_pos);
#ifdef USE_AREF
- O.tc0 = (I.tc * consts).xy; // + result;
+ O.tc0 = tc;
#endif // USE_AREF
#ifndef USE_HWSMAP
O.depth = O.hpos.z;
#endif
return O;
}
-FXVS;
+FXVS;
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
index 1d1352d9a9..8d0c420f55 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/shared/common.h
@@ -45,7 +45,11 @@ cbuffer static_globals
uniform float4 pos_decompression_params2;
uniform float4 parallax;
+ uniform float4 rain_params; // x = raindensity, y = wetness
uniform float4 screen_res; // Screen resolution (x-Width,y-Height, zw - 1/resolution)
+
+ uniform float4 pp_img_corrections;
+ uniform float4 pp_img_cg;
}
float calc_cyclic(float x)
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.ps
index 9b5e769654..9acb0e4c0a 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.vs b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.vs
index 09d1d8a6db..65e1fc7a57 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.vs
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sky2.vs
@@ -11,7 +11,7 @@ struct vi
struct v2p
{
float4 c : COLOR0;
- float3 tc0 : TEXCOORD0;
+ float4 tc0 : TEXCOORD0;
float3 tc1 : TEXCOORD1;
float4 hpos : SV_Position;
};
@@ -19,17 +19,23 @@ struct v2p
v2p main(vi v)
{
v2p o;
+ // v.c.rgb = v.c.bgr; // fix skybox color
- float4 tpos = mul(1000, v.p);
- o.hpos = mul(m_WVP, tpos); // xform, input in world coords, 1000 - magic number
+ float4 tpos = float4(2000 * v.p.x, 2000 * v.p.y, 2000 * v.p.z, 2000 * v.p.w);
+ o.hpos = mul(m_WVP, tpos);
o.hpos.z = o.hpos.w;
- o.tc0 = v.tc0; // copy tc
- o.tc1 = v.tc1; // copy tc
- // float scale = tex2Dlod (s_tonemap,float4(.5,.5,.5,.5)).x ;
+ o.tc0.xyz = v.tc0; // copy tc
+ o.tc1.xyz = v.tc1; // copy tc
float scale = s_tonemap.Load(int3(0, 0, 0)).x;
- // float scale = s_tonemap.Load( int3(1,1,0) ).x;
- // o.c = float4 ( v.c.rgb*(scale*1.7), v.c.a ); // copy color, pre-scale by tonemap //float4 ( v.c.rgb*scale*2, v.c.a );
- o.c = float4(v.c.rgb * (scale * 2.0), v.c.a); // copy color, pre-scale by tonemap //float4 ( v.c.rgb*scale*2, v.c.a );
+
+ float3 tint = v.c.rgb * 1.7;
+
+ // float3 tint = 1.0;
+ // float3 tint = env_color.rgb;
+ // float3 tint = fog_color.rgb * 2.0;
+
+ o.c = float4(tint, v.c.a); // copy color, pre-scale by tonemap //float4 (v.c.rgb*scale*2, v.c.a );
+ o.tc0.w = scale;
return o;
}
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sload.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sload.h
index 09015210b8..d7de825ee8 100644
--- a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sload.h
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/sload.h
@@ -1,3 +1,11 @@
+#define USE_ERROR_CORRECTION
+//#define RECALCULATENORMALZ
+//#define NORMALIZE_TEXTURES
+static const float NORMAL_STRENGTH = 1.0;
+static const float DETAIL_STRENGTH = 1.0;
+static const float DETAIL_TINT = 1.0;
+static const float DETAIL_GLOSS = 1.0;
+
#ifndef SLOAD_H
#define SLOAD_H
@@ -15,6 +23,62 @@ static const float2 MSAAOffsets[8] = {float2(1, -3), float2(-1, 3), float2(5, 1)
#endif
#endif // MSAA_ALPHATEST_DX10_1
+//////////////////////////////////////////////////////////////////////////////////////////
+// Texture samplers and blenders //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+float3 SampleNormal(float4 N, float4 NE)
+{
+ float3 Norm = unpack_normal(N.wzy);
+#ifdef USE_ERROR_CORRECTION
+ Norm += unpack_normal(NE.xyz);
+#endif
+#ifdef RECALCULATENORMALZ
+ Norm.z = sqrt(1 - saturate(dot(Norm.xy, Norm.xy)));
+#endif
+#ifdef NORMALIZE_TEXTURES
+ Norm = normalize(Norm);
+#endif
+ return Norm;
+}
+
+float3 NormalStrength(float3 N, float Strength)
+{
+ if (Strength != 1.0)
+ {
+ N.xy *= Strength;
+ N.z = sqrt(1 - saturate(dot(N.xy, N.xy)));
+ N = normalize(N);
+ }
+ return N;
+}
+
+float SampleGloss(float4 N) { return N.x; }
+
+float SampleHeight(float4 NE) { return NE.w; }
+
+float3 ApplyDetailAlbedo(float3 A1, float3 A2)
+{
+ // return saturate(A1 * A2 * 2);
+ return saturate(A1 * exp2(DETAIL_TINT * (A2 * 2 - 1)));
+}
+
+float3 ApplyDetailNormal(float3 N1, float3 N2)
+{
+ N1 += float3(0, 0, 1);
+ N2 *= float3(-1, -1, 1);
+ return normalize(N1 * dot(N1, N2) / N1.z - N2);
+}
+
+float ApplyDetailGloss(float G1, float G2)
+{
+ // return saturate(G1 * G2 * 2);
+ // return saturate(G1 + (DETAIL_GLOSS * (G2 * 2 - 1)));
+ return saturate(G1 * exp2(DETAIL_GLOSS * (G2 * 2 - 1)));
+}
+
+float ApplyDetailHeight(float H1, float H2) { return H1 + (H2 * 2 - 1); }
+
//////////////////////////////////////////////////////////////////////////////////////////
// Bumped surface loader //
//////////////////////////////////////////////////////////////////////////////////////////
@@ -30,73 +94,90 @@ float4 tbase(float2 tc) { return s_base.Sample(smp_base, tc); }
#if defined(ALLOW_STEEPPARALLAX) && defined(USE_STEEPPARALLAX)
-static const float fParallaxStartFade = 8.0f;
-static const float fParallaxStopFade = 12.0f;
+// Always remember to check defines, variables, and shit.... god
+#define PARALLAX_NEAR_PLANE 0.01
+#define PARALLAX_FAR_PLANE 35
+#define PARALLAX_DEPTH 0.045
+// Ok, we can comment old gsc parallax now.
+// We need to change input, to p_bumped struct like in GSC shader
+// We also change name of this function to GSC
+// Time to change input to stuff from p_bumped.
void UpdateTC(inout p_bumped I)
{
- if (I.position.z < fParallaxStopFade)
+ // Here's "limited" range of parallax. We use linear depth (z vector of view space position) to do that
+ if ((I.position.z > PARALLAX_NEAR_PLANE) && (I.position.z < PARALLAX_FAR_PLANE))
{
- const float maxSamples = 25;
- const float minSamples = 5;
- const float fParallaxOffset = -0.013;
+ // That M1/M2/M3 stuff is our TBN matrix (we aligin tangent normals/vectors to to just geometry normals
+ 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.xyz));
+
+ // steps minmax and refines minmax
+ int4 steps = int4(3, 10, 7, 16); // 3..10, 7..16
- float3 eye = 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.xyz);
+ bool need_disp_lerp = true;
+ bool need_refine = true; // Thats refinement steps, used to smoothout raymarched results
- eye = normalize(eye);
+ float view_angle = abs(dot(float3(0.0, 0.0, 1.0), eye));
- // Calculate number of steps
- float nNumSteps = lerp(maxSamples, minSamples, eye.z);
+ float layer_step = rcp(lerp(steps.y, steps.x, view_angle));
- float fStepSize = 1.0 / nNumSteps;
- float2 vDelta = eye.xy * fParallaxOffset * 1.2;
- float2 vTexOffsetPerStep = fStepSize * vDelta;
+ // float2 tc_step = layer_step * eye.xy * PARALLAX_DEPTH);
+ float2 tc_step = layer_step * eye.xy * (parallax.x);
- // Prepare start data for cycle
- float2 vTexCurrentOffset = I.tcdh;
- float fCurrHeight = 0.0;
- float fCurrentBound = 1.0;
+ // Now, we have to change this huita. p.tcdbump is our "tiled" texture coordinate
+ // I.tcdh is our "normal" texcoord, lets see above
+ float2 displaced_tc = I.tcdh;
- for (int i = 0; i < nNumSteps; ++i)
+ float curr_disp, curr_layer = 0.0;
+
+ do
+ {
+ displaced_tc -= tc_step;
+ curr_disp = 1 - s_bumpX.SampleLevel(smp_base, displaced_tc, 0).w; // Our heightmap sampler
+ curr_layer += layer_step;
+ } while (curr_layer < curr_disp);
+
+ if (need_refine)
{
- if (fCurrHeight < fCurrentBound)
+ displaced_tc += tc_step;
+ curr_layer -= layer_step;
+
+ float refine_steps = lerp(steps.w, steps.z, view_angle);
+
+ tc_step /= refine_steps;
+ layer_step /= refine_steps;
+
+ do
{
- vTexCurrentOffset += vTexOffsetPerStep;
- fCurrHeight = s_bumpX.SampleLevel(smp_base, vTexCurrentOffset.xy, 0).a;
- fCurrentBound -= fStepSize;
- }
+ displaced_tc -= tc_step;
+ curr_disp = 1.0 - s_bumpX.SampleLevel(smp_base, displaced_tc, 0).w;
+ curr_layer += layer_step;
+ } while (curr_layer < curr_disp);
}
- /*
- [unroll(25)] // Doesn't work with [loop]
- for( ;fCurrHeight < fCurrentBound; fCurrentBound -= fStepSize )
- {
- vTexCurrentOffset += vTexOffsetPerStep;
- fCurrHeight = s_bumpX.SampleLevel( smp_base, vTexCurrentOffset.xy, 0 ).a;
- }
- */
- // Reconstruct previouse step's data
- vTexCurrentOffset -= vTexOffsetPerStep;
- float fPrevHeight = s_bumpX.Sample(smp_base, float3(vTexCurrentOffset.xy, 0)).a;
-
- // Smooth tc position between current and previouse step
- float fDelta2 = ((fCurrentBound + fStepSize) - fPrevHeight);
- float fDelta1 = (fCurrentBound - fCurrHeight);
- float fParallaxAmount = (fCurrentBound * fDelta2 - (fCurrentBound + fStepSize) * fDelta1) / (fDelta2 - fDelta1);
- float fParallaxFade = smoothstep(fParallaxStopFade, fParallaxStartFade, I.position.z);
- float2 vParallaxOffset = vDelta * ((1 - fParallaxAmount) * fParallaxFade);
- float2 vTexCoord = I.tcdh + vParallaxOffset;
-
- // Output the result
- I.tcdh = vTexCoord;
+ if (need_disp_lerp)
+ {
+ float2 displaced_tc_prev = displaced_tc + tc_step;
+
+ float after_depth = curr_disp - curr_layer;
+ float before_depth = 1.0 - s_bumpX.SampleLevel(smp_base, displaced_tc_prev, 0).w - curr_layer + layer_step; // Another sampler name
+
+ float weight = after_depth / (after_depth - before_depth);
+
+ displaced_tc = lerp(displaced_tc, displaced_tc_prev, weight);
+ }
+ // Tiling for detail/tiled textures
#if defined(USE_TDETAIL) && defined(USE_STEEPPARALLAX)
- I.tcdbump = vTexCoord * dt_params;
+ I.tcdbump = I.tcdh * dt_params; // tiled UV
+ I.tcdbump += displaced_tc - I.tcdh; // offset
#endif
+
+ I.tcdh = displaced_tc;
}
}
-#elif defined(USE_PARALLAX) && defined(USE_STEEPPARALLAX)
+#elif defined(USE_PARALLAX) || defined(USE_STEEPPARALLAX)
void UpdateTC(inout p_bumped I)
{
@@ -108,6 +189,11 @@ void UpdateTC(inout p_bumped I)
height = height * (parallax.x) + (parallax.y); //
float2 new_tc = I.tcdh + height * normalize(eye); //
+ // Tiling for detail/tiled textures
+#if defined(USE_TDETAIL) && defined(USE_STEEPPARALLAX)
+ I.tcdbump = I.tcdh * dt_params + height * normalize(eye);
+#endif
+
// Output the result
I.tcdh.xy = new_tc;
}
@@ -124,101 +210,53 @@ surface_bumped sload_i(p_bumped I)
UpdateTC(I); // All kinds of parallax are applied here.
- float4 Nu = s_bump.Sample(smp_base, I.tcdh); // IN: normal.gloss
- float4 NuE = s_bumpX.Sample(smp_base, I.tcdh); // IN: normal_error.height
-
- S.base = tbase(I.tcdh); // IN: rgb.a
- S.normal = Nu.wzy + (NuE.xyz - 1.0h); // (Nu.wzyx - .5h) + (E-.5)
- S.gloss = Nu.x * Nu.x; // S.gloss = Nu.x*Nu.x;
- S.height = NuE.w;
- // S.height = 0;
-
+ // Base textures
+ //
+ S.base = tbase(I.tcdh);
+ float4 Nu = s_bump.Sample(smp_base, I.tcdh);
+ float4 NuE = s_bumpX.Sample(smp_base, I.tcdh);
+ float3 TangentNormal = NormalStrength(SampleNormal(Nu, NuE), NORMAL_STRENGTH);
+ S.normal = TangentNormal;
+ S.gloss = SampleGloss(Nu);
+ S.height = SampleHeight(NuE);
+
+ // Detail textures
+ //
#ifdef USE_TDETAIL
+ float4 detail = s_detail.Sample(smp_base, I.tcdbump);
+ S.base.rgb = ApplyDetailAlbedo(S.base.rgb, detail.rgb);
#ifdef USE_TDETAIL_BUMP
float4 NDetail = s_detailBump.Sample(smp_base, I.tcdbump);
float4 NDetailX = s_detailBumpX.Sample(smp_base, I.tcdbump);
- S.gloss = S.gloss * NDetail.x * 2;
- // S.normal += NDetail.wzy-.5;
- S.normal += NDetail.wzy + NDetailX.xyz - 1.0h; // (Nu.wzyx - .5h) + (E-.5)
-
- float4 detail = s_detail.Sample(smp_base, I.tcdbump);
- S.base.rgb = S.base.rgb * detail.rgb * 2;
-
-// S.base.rgb = float3(1,0,0);
-#else // USE_TDETAIL_BUMP
- float4 detail = s_detail.Sample(smp_base, I.tcdbump);
- S.base.rgb = S.base.rgb * detail.rgb * 2;
- S.gloss = S.gloss * detail.w * 2;
-
-#endif // USE_TDETAIL_BUMP
+ float3 DetailNormal = NormalStrength(SampleNormal(NDetail, NDetailX), DETAIL_STRENGTH);
+ S.normal = ApplyDetailNormal(TangentNormal, DetailNormal);
+ // float DetailGloss = SampleGloss(NDetail);
+ float DetailGloss = detail.w; // higher res most of the time
+ float DetailHeight = SampleHeight(NDetailX);
+ S.height = ApplyDetailHeight(S.height, DetailHeight);
+#else
+ float DetailGloss = detail.w;
+#endif
+ S.gloss = ApplyDetailGloss(S.gloss, DetailGloss);
#endif
+ //
return S;
}
-surface_bumped sload_i(p_bumped I, float2 pixeloffset)
-{
- surface_bumped S;
+surface_bumped sload(p_bumped I) { return sload_i(I); }
+surface_bumped sload(p_bumped I, float2 pixeloffset)
+{
// apply offset
#ifdef MSAA_ALPHATEST_DX10_1
I.tcdh.xy += pixeloffset.x * ddx(I.tcdh.xy) + pixeloffset.y * ddy(I.tcdh.xy);
-#endif
-
- UpdateTC(I); // All kinds of parallax are applied here.
-
- float4 Nu = s_bump.Sample(smp_base, I.tcdh); // IN: normal.gloss
- float4 NuE = s_bumpX.Sample(smp_base, I.tcdh); // IN: normal_error.height
-
- S.base = tbase(I.tcdh); // IN: rgb.a
- S.normal = Nu.wzyx + (NuE.xyz - 1.0h); // (Nu.wzyx - .5h) + (E-.5)
- S.gloss = Nu.x * Nu.x; // S.gloss = Nu.x*Nu.x;
- S.height = NuE.w;
- // S.height = 0;
-
#ifdef USE_TDETAIL
-#ifdef USE_TDETAIL_BUMP
-#ifdef MSAA_ALPHATEST_DX10_1
-#if ((!defined(ALLOW_STEEPPARALLAX)) && defined(USE_STEEPPARALLAX))
I.tcdbump.xy += pixeloffset.x * ddx(I.tcdbump.xy) + pixeloffset.y * ddy(I.tcdbump.xy);
#endif
#endif
- float4 NDetail = s_detailBump.Sample(smp_base, I.tcdbump);
- float4 NDetailX = s_detailBumpX.Sample(smp_base, I.tcdbump);
- S.gloss = S.gloss * NDetail.x * 2;
- // S.normal += NDetail.wzy-.5;
- S.normal += NDetail.wzy + NDetailX.xyz - 1.0h; // (Nu.wzyx - .5h) + (E-.5)
-
- float4 detail = s_detail.Sample(smp_base, I.tcdbump);
- S.base.rgb = S.base.rgb * detail.rgb * 2;
-
-// S.base.rgb = float3(1,0,0);
-#else // USE_TDETAIL_BUMP
-#ifdef MSAA_ALPHATEST_DX10_1
- I.tcdbump.xy += pixeloffset.x * ddx(I.tcdbump.xy) + pixeloffset.y * ddy(I.tcdbump.xy);
-#endif
- float4 detail = s_detail.Sample(smp_base, I.tcdbump);
- S.base.rgb = S.base.rgb * detail.rgb * 2;
- S.gloss = S.gloss * detail.w * 2;
-#endif // USE_TDETAIL_BUMP
-#endif
-
- return S;
-}
-
-surface_bumped sload(p_bumped I)
-{
- surface_bumped S = sload_i(I);
- // S.normal.z *= 0.5; //. make bump twice as contrast (fake, remove me if possible)
- return S;
-}
-
-surface_bumped sload(p_bumped I, float2 pixeloffset)
-{
- surface_bumped S = sload_i(I, pixeloffset);
- // S.normal.z *= 0.5; //. make bump twice as contrast (fake, remove me if possible)
- return S;
+ return sload_i(I);
}
#endif
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/srgb.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/srgb.h
new file mode 100644
index 0000000000..484afa65fb
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/srgb.h
@@ -0,0 +1,49 @@
+//=================================================================================================
+// Gamma Correction
+//=================================================================================================
+//#define USE_STRICT_GAMMA_CORRECTION //use gamma correction for sky blending, might distort the original colors
+//=================================================================================================
+
+float LinearTosRGB(float gammaPre)
+{
+ /*
+ float Low = gammaPre * 12.92;
+ float High = (pow(gammaPre, 1.0 / 2.4) * 1.055) - 0.055;
+ return (gammaPre <= 0.0031308) ? Low : High;
+ */
+ // return (gammaPre <= 0.00313080495356037151702786377709) ? gammaPre * 12.92 : (1.055 * pow(gammaPre, 0.41666666666666666666666666666667) - 0.055);
+ // return max(1.055 * pow(gammaPre, 0.416666667) - 0.055, 0.0);
+
+ // Cheap sRGB doesn't cause clipping
+ return pow(gammaPre, 0.45454545);
+}
+
+float3 LinearTosRGB(float3 gammaPre)
+{
+ gammaPre = max(0.0, gammaPre);
+ float3 gammaPost = float3(LinearTosRGB(gammaPre.r), LinearTosRGB(gammaPre.g), LinearTosRGB(gammaPre.b));
+ return gammaPost;
+}
+
+float SRGBToLinear(float gammaPre)
+{
+ /*
+ float Low = gammaPre / 12.92;
+ float High = pow((gammaPre + 0.055) / 1.055, 2.4);
+ return(gammaPre <= 0.04045) ? Low : High;
+ */
+ // return (gammaPre <= 0.04045) ? gammaPre * 0.07739938080495356037151702786378 : pow((gammaPre + 0.055) * 0.94786729857819905213270142180095, 2.4);
+ // return gammaPre * (gammaPre * (gammaPre * 0.305306011 + 0.682171111) + 0.012522878);
+
+ // Cheap sRGB doesn't cause clipping
+ return pow(gammaPre, 2.2);
+}
+
+float3 SRGBToLinear(float3 gammaPre)
+{
+ gammaPre = max(0.0, gammaPre);
+ float3 gammaPost = float3(SRGBToLinear(gammaPre.r), SRGBToLinear(gammaPre.g), SRGBToLinear(gammaPre.b));
+ return gammaPost;
+}
+
+#include "tonemap_srgb.h"
\ No newline at end of file
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_display.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_display.ps
index 53a2bdc074..18985ccbfb 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_display.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/ssss_mrmnwar_display.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/tonemap_srgb.h b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/tonemap_srgb.h
new file mode 100644
index 0000000000..a1283ff9c2
--- /dev/null
+++ b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/tonemap_srgb.h
@@ -0,0 +1,40 @@
+//=================================================================================================
+// Gamma Correct Tonemapping and Color Grading
+#include "ACES.h"
+//=================================================================================================
+
+float3 tonemap_sRGB(float3 x, float w)
+{
+#ifdef USE_ACES
+ // use ACES workflow for color grading and tonemapping
+ x = ACES(x);
+#else
+ // convert into linear gamma space
+ x = SRGBToLinear(x);
+
+ // color grading
+ ACES_LMT(x);
+
+ // clamp negative values
+ x = max(0.0, x);
+
+ // Boost the contrast to match ACES RRT
+ float Contrast_Boost = 1.42857;
+ x = pow(x, Contrast_Boost) * 0.18 / pow(0.18, Contrast_Boost);
+
+ // reinhard tonemapping
+ x = x / (x + 1);
+ x /= w / (w + 1);
+
+ // convert into sRGB gamma space
+ x = LinearTosRGB(x);
+#endif
+ /*
+ //debug highlights for clipping values
+ x = x < 0.0 ? float3(0.0,0.0,1.0) : x;
+ x = x > 1.0 ? float3(1.0,0.0,0.0) : x;
+ */
+
+ // return with saturate, everything should be in LDR sRGB
+ return saturate(x);
+}
diff --git a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/water.ps b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/water.ps
index c1f13291f6..03640fb090 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/shaders/r3/water.ps and b/Game/Resources_SoC_1.0006/gamedata/shaders/r3/water.ps differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/textures/fx/water_sbumpvolume.dds b/Game/Resources_SoC_1.0006/gamedata/textures/fx/water_sbumpvolume.dds
index a2c85659ce..4318104d27 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/textures/fx/water_sbumpvolume.dds and b/Game/Resources_SoC_1.0006/gamedata/textures/fx/water_sbumpvolume.dds differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/textures/fx/wind_wave.dds b/Game/Resources_SoC_1.0006/gamedata/textures/fx/wind_wave.dds
new file mode 100644
index 0000000000..4bf353cb0b
Binary files /dev/null and b/Game/Resources_SoC_1.0006/gamedata/textures/fx/wind_wave.dds differ
diff --git a/Game/Resources_SoC_1.0006/gamedata/textures/water/water_sbumpvolume.dds b/Game/Resources_SoC_1.0006/gamedata/textures/water/water_sbumpvolume.dds
index 574aecee23..4318104d27 100644
Binary files a/Game/Resources_SoC_1.0006/gamedata/textures/water/water_sbumpvolume.dds and b/Game/Resources_SoC_1.0006/gamedata/textures/water/water_sbumpvolume.dds differ