From a916c4f3fd73446cae5564c76df78ab65ed1dfc7 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sat, 18 Jul 2026 23:49:46 -0700 Subject: [PATCH 01/33] Shadow of War: HDR and more --- .../Includes/ColorGrade.hlsl | 59 ++ .../Includes/Common.hlsl | 17 +- .../Includes/GameCBuffers.hlsl | 27 +- .../Includes/HermiteSpline_portable.hlsl | 163 ++++ .../Includes/RCAS.hlsl | 149 +++ .../Includes/Settings.hlsl | 13 - .../Includes/ictcp_portable.hlsl | 195 ++++ .../bloomblend_0xA35C971A.ps_5_0.hlsl | 41 + ...adialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 | 80 ++ .../Middle-earth Shadow of War/common.hlsl | 301 ++++++ .../computeexposure_0xD2356014.cs_5_0.hlsl 1 | 778 +++++++++++++++ .../fire00_0x784E89AD.ps_5_0.hlsl | 155 +++ .../fire01_0xFEB3373E.ps_5_0.hlsl | 84 ++ ...e02_explosionflame0_0xEC01FC57.ps_5_0.hlsl | 73 ++ .../fire04_mega_0xFC3E803B.ps_5_0.hlsl | 109 +++ ...ftdistlutsmoothstep_0x922EBCCE.ps_5_0.hlsl | 108 +++ .../fire06_lutrandom_0x708498E1.ps_5_0.hlsl | 73 ++ ...checkmasksmoothstep_0x23FDC1DE.ps_5_0.hlsl | 98 ++ ...wordflamefallofflut_0x9E6060A0.ps_5_0.hlsl | 125 +++ ..._3dnoisedepthreveal_0xFAF088FD.ps_5_0.hlsl | 125 +++ ...istortsmoothsteplut_0xDD3A25B7.ps_5_0.hlsl | 116 +++ ...11_adddistortpantwo_0xBEF04EDB.ps_5_0.hlsl | 172 ++++ ...12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl | 106 ++ ...transsoftdistortlut_0x4A2FFA30.ps_5_0.hlsl | 100 ++ ...e14_explosionflame1_0x9DE77962.ps_5_0.hlsl | 65 ++ ...5_addsoftdistortlut_0xC033CA59.ps_5_0.hlsl | 103 ++ ...sselateanimcurvelut_0x32AD961A.ps_5_0.hlsl | 94 ++ .../motionblur_0xB3DC1377.ps_5_0.hlsl 1 | 621 ++++++++++++ .../mov_0xB2EAAA62.ps_5_0.hlsl | 53 + .../photomode_contrast_0xC2665219.ps_5_0.hlsl | 74 ++ .../photomode_exposure_0xF4316866.ps_5_0.hlsl | 52 + .../solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 | 144 +++ .../swapchain_hdr_0x68EABB8D.ps_5_0.hlsl | 97 ++ .../swapchain_sdr_0x09C22C0E.ps_5_0.hlsl | 138 +++ ...mapwithexposure_hdr_0xA4592384.ps_5_0.hlsl | 164 ++++ ...mapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl | 243 +++++ .../Games/Middle-earth Shadow of War/main.cpp | 917 ++++++++++++++---- 37 files changed, 5823 insertions(+), 209 deletions(-) create mode 100644 Shaders/Middle-earth Shadow of War/Includes/ColorGrade.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl delete mode 100644 Shaders/Middle-earth Shadow of War/Includes/Settings.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/Includes/ictcp_portable.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 create mode 100644 Shaders/Middle-earth Shadow of War/common.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 create mode 100644 Shaders/Middle-earth Shadow of War/fire00_0x784E89AD.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire01_0xFEB3373E.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire02_explosionflame0_0xEC01FC57.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire04_mega_0xFC3E803B.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire05_addsoftdistlutsmoothstep_0x922EBCCE.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire06_lutrandom_0x708498E1.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire07_lut4checkmasksmoothstep_0x23FDC1DE.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire08_trailswordflamefallofflut_0x9E6060A0.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire09_3dnoisedepthreveal_0xFAF088FD.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire10_adddistortsmoothsteplut_0xDD3A25B7.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire11_adddistortpantwo_0xBEF04EDB.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire13_transsoftdistortlut_0x4A2FFA30.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire14_explosionflame1_0x9DE77962.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire15_addsoftdistortlut_0xC033CA59.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/fire16_tesselateanimcurvelut_0x32AD961A.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 create mode 100644 Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/photomode_contrast_0xC2665219.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 create mode 100644 Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl create mode 100644 Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl diff --git a/Shaders/Middle-earth Shadow of War/Includes/ColorGrade.hlsl b/Shaders/Middle-earth Shadow of War/Includes/ColorGrade.hlsl new file mode 100644 index 00000000..d85f181c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/Includes/ColorGrade.hlsl @@ -0,0 +1,59 @@ +#include "../Includes/Color.hlsl" + +//from RenoDX clshortfuse +float RenoDX_Contrast(float x, float contrast, float mid_gray = 0.18f) { + return pow(max(0, x / mid_gray), contrast) * mid_gray; +} +float3 RenoDX_Contrast(float3 x, float contrast, float mid_gray = 0.18f) { + return pow(max(0, x / mid_gray), contrast) * mid_gray; +} +float RenoDX_Shadows(float x, float shadows, float mid_gray) { + float value; + if (shadows > 1.f) { + value = max(x, x * (1.f + (x * mid_gray / pow(x / mid_gray, shadows)))); + } else if (shadows < 1.f) { + value = clamp(x * (1.f - (x * mid_gray / pow(x / mid_gray, 2.f - shadows))), 0.f , x); + } else { + value = x; + } + return value; +} +float RenoDX_Highlights(float x, float highlights, float mid_gray) { + float value; + if (highlights > 1.f) { + value = max(x, lerp(x, mid_gray * pow(x / mid_gray, highlights), x)); + } else if (highlights < 1.f) { + value = min(x, x / (1.f + mid_gray * pow(x / mid_gray, 2.f - highlights) - x)); + } else { + value = x; + } + return value; +} + +float3 RenoDX_ColorGrade( + float3 x, + float contrast = 1, float contrast_mid = 0.18f, + float highlights = 1, float highlights_mid = 0.18f, + float shadows = 1, float shadows_mid = 0.18f, + float saturation = 1, + uint colorspace = CS_DEFAULT, + bool clampCs = false +) { + float l = GetLuminance(x, colorspace); + float lOrig = l; + if (l <= 0) return 0; //0 is redundant and div 0 + + //Luminance Grading + l = RenoDX_Contrast(l, contrast, contrast_mid); + l = RenoDX_Highlights(l, highlights, highlights_mid); + l = RenoDX_Shadows(l, shadows, shadows_mid); + x *= l / lOrig; + + //Saturation + if (saturation != 1.f) x = Saturation(x, saturation, colorspace); + + //Clamp + if (clampCs) x = max(0, x); + + return x; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl index 3c675ffc..76e4d0c5 100644 --- a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl +++ b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl @@ -5,4 +5,19 @@ // Global common #include "../../Includes/Common.hlsl" // Game specific settings -#include "Settings.hlsl" \ No newline at end of file +#include "Settings.hlsl" + +#define GS LumaSettings.GameSettings + +float4 sRGB_Encode(float4 x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} +float3 sRGB_Encode(float3 x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} +float sRGB_Encode(float x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} +float4 sRGB_Decode(float4 x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} +float3 sRGB_Decode(float3 x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} +float sRGB_Decode(float x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} + +#define HDR_ENABLED LumaSettings.DisplayMode == 1 +#define HDR_PEAK PeakWhiteNits / GamePaperWhiteNits +#define HDR_INTSCALING GamePaperWhiteNits / UIPaperWhiteNits +#define HDR_SHOULDERSTART GS.TonemapperRolloffStart / GamePaperWhiteNits +#define HDR_MAXEXPECTED GS.TonemapperMaxExpected / GamePaperWhiteNits \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl b/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl index df80f8ea..6d25e8b5 100644 --- a/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl +++ b/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl @@ -2,25 +2,24 @@ #define LUMA_GAME_CB_STRUCTS #ifdef __cplusplus -// This include is needed to allow reading shader types from c++. #include "../../../Source/Core/includes/shader_types.h" #endif -// Mirrors c++ name spaces. namespace CB { - // Define the game specific cbuffer settings here. They don't need 4 bytes alignment. - struct LumaGameSettings - { - float GameSetting01; - uint GameSetting02; - }; - - // Define the game specific cbuffer (instance/pass) data here - struct LumaGameData - { - float Dummy; // hlsl doesn't support empty structs - }; + struct LumaGameSettings + { + float WhiteClip; + float BlowoutCorrection; + float GodRays; + float Bloom; + float RCAS; + }; + + struct LumaGameData + { + float Dummy; + }; } #endif // LUMA_GAME_CB_STRUCTS diff --git a/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl b/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl new file mode 100644 index 00000000..1059254a --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl @@ -0,0 +1,163 @@ +//https://github.com/clshortfuse/renodx/blob/main/src/shaders/tonemap/hermite_spline.hlsl +#include "../Includes/Color.hlsl" + +namespace pq { + static const float M1 = 2610.f / 16384.f; // 0.1593017578125f; + static const float M2 = 128.f * (2523.f / 4096.f); // 78.84375f; + static const float C1 = 3424.f / 4096.f; // 0.8359375f; + static const float C2 = 32.f * (2413.f / 4096.f); // 18.8515625f; + static const float C3 = 32.f * (2392.f / 4096.f); // 18.6875f; + + float Encode(float color, float scaling = 10000.f) { + color *= (scaling / 10000.f); + float y_m1 = pow(color, M1); + return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); + } + + float3 Encode(float3 color, float scaling = 10000.f) { + color *= (scaling / 10000.f); + float3 y_m1 = pow(color, M1); + return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); + } + + float Decode(float color, float scaling = 10000.f) { + float e_m12 = pow(color, 1.f / M2); + float out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); + return out_color * (10000.f / scaling); + } + + float3 Decode(float3 color, float scaling = 10000.f) { + float3 e_m12 = pow(color, 1.f / M2); + float3 out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); + return out_color * (10000.f / scaling); + } + + float3 EncodeSafe(float3 color, float scaling = 10000.f) { + return Encode(max(0, color), scaling); + } + + float3 DecodeSafe(float3 color, float scaling = 10000.f) { + return Decode(max(0, color), scaling); + } +} + +float Rescale(float x, float x_min, float x_max, float y_min = 0, float y_max = 1, bool clamp = false) { + float value = lerp(y_min, y_max, (x - x_min) / (x_max - x_min)); + if (clamp) value = saturate(value); + return value; +} + +float HermiteSplineRolloff(float input, float target_white = 1.f, float max_white = 20.f) { + float l_w = max_white; + float l_max = target_white; + float e_1 = Rescale(input, 0, l_w); + float max_lum = Rescale(l_max, 0, l_w); + float knee_start = 1.5f * max_lum - 0.5f; + float t_b = Rescale(e_1, knee_start, 1.f); + float t_b_squared = t_b * t_b; + float t_b_cubed = t_b_squared * t_b; + float two_t_b_cubed = 2.f * t_b_cubed; + float three_t_b_squared = 3.f * t_b_squared; + float p_e1_h00 = (two_t_b_cubed - three_t_b_squared + 1.f); + float p_e1_h10 = (t_b_cubed - 2.f * t_b_squared + t_b); + float p_e1_h01 = (-two_t_b_cubed + three_t_b_squared); + float p_e1 = p_e1_h00 * knee_start + + p_e1_h10 * (1.f - knee_start) + + p_e1_h01 * max_lum; + float e_2 = (e_1 < knee_start) ? e_1 : p_e1; + float e_3 = e_2; + float e_4 = l_w * e_3; + return min(e_4, target_white); +} +float HermiteSplineRolloff( + float input, + float target_white, + float max_white, + float target_black, + float min_black = 0.f) { + float l_w = max_white; + float l_b = min_black; + float l_min = target_black; + float l_max = target_white; + float e_1 = Rescale(input, l_b, l_w); + float min_lum = Rescale(l_min, l_b, l_w); + float max_lum = Rescale(l_max, l_b, l_w); + float knee_start = 1.5f * max_lum - 0.5f; + float b = min_lum; + float t_b = Rescale(e_1, knee_start, 1.f); + float t_b_squared = t_b * t_b; + float t_b_cubed = t_b_squared * t_b; + float two_t_b_cubed = 2.f * t_b_cubed; + float three_t_b_squared = 3.f * t_b_squared; + float p_e1_h00 = (two_t_b_cubed - three_t_b_squared + 1.f); + float p_e1_h10 = (t_b_cubed - 2.f * t_b_squared + t_b); + float p_e1_h01 = (-two_t_b_cubed + three_t_b_squared); + float p_e1 = p_e1_h00 * knee_start + + p_e1_h10 * (1.f - knee_start) + + p_e1_h01 * max_lum; + float e_2 = (e_1 < knee_start) ? e_1 : p_e1; + float e_3a1 = (1 - e_2) * (1 - e_2); + float e_3a2 = e_3a1 * (1 - e_2); + float e_3 = e_2 + (b * e_3a2); + e_3 = saturate(e_3); + float e_4 = lerp(l_b, l_w, e_3); + return e_4; +} + +float HermiteSplineLuminanceRolloff(float luminance, float target_white, float max_white, float target_black, float min_black, float nits = 100.f) { + float luminance_pq = pq::Encode(luminance, nits); + float target_white_pq = pq::Encode(target_white, nits); + float max_white_pq = pq::Encode(max_white, nits); + float target_black_pq = pq::Encode(target_black, nits); + float min_black_pq = pq::Encode(min_black, nits); + + float scaled = HermiteSplineRolloff(luminance_pq, target_white_pq, max_white_pq, target_black_pq, min_black_pq); + + float unpq_scaled = pq::Decode(scaled, nits); + return unpq_scaled; +} + +float3 HermiteSplineLuminanceRolloff(float3 color, float target_white, float max_white, float target_black, float min_black = 0.f, float nits = 100.f) { + float y = GetLuminance(color, CS_BT709); + float new_y = HermiteSplineLuminanceRolloff(y, target_white, max_white, target_black, min_black, nits); + float3 new_color = y > 0 ? color * (new_y / y) : 0; + return new_color; +} + +float3 HermiteSplinePerChannelRolloff(float3 input, float target_white, float max_white, float target_black, float min_black = 0.f, float nits = 100.f) { + float3 input_pq = pq::Encode(input, nits); + float target_white_pq = pq::Encode(target_white, nits); + float max_white_pq = pq::Encode(max_white, nits); + float target_black_pq = pq::Encode(target_black, nits); + float min_black_pq = pq::Encode(min_black, nits); + + float3 scaled = float3( + HermiteSplineRolloff(input_pq.r, target_white_pq, max_white_pq, target_black_pq, min_black_pq), + HermiteSplineRolloff(input_pq.g, target_white_pq, max_white_pq, target_black_pq, min_black_pq), + HermiteSplineRolloff(input_pq.b, target_white_pq, max_white_pq, target_black_pq, min_black_pq)); + + float3 unpq_scaled = pq::Decode(scaled, nits); + return unpq_scaled; +} + +float HermiteSplineLuminanceRolloff(float luminance, float target_white = 1.f, float max_white = 20.f) { + if (luminance == 0) return 0; + return exp2(HermiteSplineRolloff(log2(luminance), log2(target_white), log2(max_white))); +} + +float3 HermiteSplineLuminanceRolloff(float3 color, float target_white = 1.f, float max_white = 20.f) { + float y = GetLuminance(color, CS_BT709); + float new_y = HermiteSplineLuminanceRolloff(y, target_white, max_white); + float3 new_color = y > 0 ? color * (new_y / y) : 0; + return new_color; +} + +float3 HermiteSplinePerChannelRolloff(float3 input, float target_white = 1.f, float max_white = 20.f) { + float target_white_log2 = log2(target_white); + float max_white_log2 = log2(max_white); + float3 scaled = float3( + input.r == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.r), target_white_log2, max_white_log2)), + input.g == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.g), target_white_log2, max_white_log2)), + input.b == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.b), target_white_log2, max_white_log2))); + return scaled; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl b/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl new file mode 100644 index 00000000..411874a9 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl @@ -0,0 +1,149 @@ +#ifndef SRC_RCAS_HLSL +#define SRC_RCAS_HLSL + +// RCAS (Robust Contrast-Adaptive Sharpening) +// https://github.com/GPUOpen-Effects/FidelityFX-FSR2?tab=readme-ov-file#robust-contrast-adaptive-sharpening-rcas +// +// Our implementation is based on: "https://github.com/cdozdil/OptiScaler/blob/master/OptiScaler/shaders/rcas/precompile/rcas.hlsl", +// which is in turn based on: "https://github.com/RdenBlaauwen/RCAS-for-ReShade", +// which is in turn based on AMD FSR 1 RCAS: https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/master/ffx-fsr/ffx_fsr1.h + +// Try to detect noise or grain and not over sharpen it. This seemengly assumes the input is in the SDR 0-1 range. +#ifndef RCAS_DENOISE +#define RCAS_DENOISE 0 +#endif +// Lower means less artifacts and "less sharpening", it's unclear what 16 stands for here, and whether this is meant for linear or gamma space (probably gamma space) +// This is set at the limit of providing unnatural results for sharpening (anything more generates artifacts). +#ifndef RCAS_LIMIT +#define RCAS_LIMIT (0.25-(1.0/16.0)) +#endif +// This should look better, avoid hue shifts and be more compatible with HDR (scRGB, which can have negative values). This appears to have stronger sharpening when enabled, but also causes more black dots to appear at extreme sharpening values. +// For now it's disabled by default as there's not enough proof to justify it, sharpening is a perceptual trick so hue shifts don't really matter (in fact, possibly they make it better). +#define RCAS_LUMINANCE_BASED 0 + +float getRCASLuma(float3 rgb) +{ +#if 0 // LUMA FT: changed to use the proper Rec.709 luminance formula (but multiplied by 2 as the sum of the original RCAS formula is 2) + return GetLuminance(rgb) * 2; +#else + return dot(rgb, float3(0.5, 1.0, 0.5)); +#endif +} + +float3 RCAS(float3 color, Texture2D texColor, SamplerState sampler1, float2 uv, float sharpness, float paperWhite) +{ + // if (sharpness == 0.0f) return color; + + // RCAS is always "pixel based" (the next 4 pixels) + // b + // d e f + // h + // We check for "maxPixelCoord" and "minPixelCoord" to support dynamic resolution scaling. We assume "pixelCoord" is already within the limits. + float3 e = color; + float3 b = texColor.Sample(sampler1, uv, int2( 0,-1)).rgb; + float3 d = texColor.Sample(sampler1, uv, int2(-1, 0)).rgb; + float3 f = texColor.Sample(sampler1, uv, int2( 1, 0)).rgb; + float3 h = texColor.Sample(sampler1, uv, int2( 0, 1)).rgb; + b = max(0, b); + d = max(0, d); + f = max(0, f); + h = max(0, h); + e /= paperWhite; + b /= paperWhite; + d /= paperWhite; + f /= paperWhite; + h /= paperWhite; + +#if RCAS_DENOISE >= 1 + // Get lumas times 2. Should use luma weights that are twice as large as normal. + float bL = getRCASLuma(b); + float dL = getRCASLuma(d); + float eL = getRCASLuma(e); + float fL = getRCASLuma(f); + float hL = getRCASLuma(h); + + // denoise + float nz = (bL + dL + fL + hL) * 0.25 - eL; + float range = max(max(max(bL, dL), max(hL, fL)), eL) - min(min(min(bL, dL), min(eL, fL)), hL); + nz = saturate(abs(nz) * rcp(range)); + nz = -0.5 * nz + 1.0; +#endif + + static const float samplesNum = 4.0; // There's 4 (5) colors to be mixed + // Immediate constants for peak range. + static const float2 peakC = float2(1.0, -samplesNum); + +#if RCAS_LUMINANCE_BASED + // These should all be >= 0, but tiny values below zero shouldn't hurt anyway, still, we clip them below as they'd be clipped by the screen anyway + float bLum = GetLuminance(b); + float dLum = GetLuminance(d); + float eLum = GetLuminance(e); + float fLum = GetLuminance(f); + float hLum = GetLuminance(h); + + float minLum = max(min(min(bLum, dLum), min(fLum, hLum)), 0.0); + float maxLum = max(max(bLum, dLum), max(fLum, hLum)); + + float hitMin = minLum * rcp(samplesNum * maxLum); + float hitMax = (peakC.x - maxLum) * rcp(samplesNum * minLum + peakC.y); + + float localLobe = max(-hitMin, hitMax); +#else // !RCAS_LUMINANCE_BASED + // Min and max of ring. + float3 minRGB = min(min(b, d), min(f, h)); + float3 maxRGB = max(max(b, d), max(f, h)); + +#if 0 // It seems like it's ok if these values aren't in the 0-1 range, the code below will still work as expected, and avoid clipping HDR (or anyway ignoring values beyond SDR) //TODOFT3: Lilium claims the code below can break for negative rgb (scRGB) values, investigate and fix it + minRGB = saturate(minRGB); + maxRGB = saturate(maxRGB); +#endif + + // Limiters, these need to use high precision reciprocal operations. + // Decided to use standard rcp for now in hopes of optimizing it. + // It's fine if either of these can go below zero! + float3 hitMin = minRGB * rcp(samplesNum * maxRGB); + float3 hitMax = (peakC.xxx - maxRGB) * rcp(samplesNum * minRGB + peakC.yyy); + + float3 lobeRGB = max(-hitMin, hitMax); +#if 0 // An attempt to make this code, which branches by r g b channel, color space agnostic. Without this, the result heavily depends by where the rgb coordinates are in the CIE color graph, and by how luminous they are. Unfortunately this drastically reduces the sharpening intensity, even if it makes it look even more natural. + float localLobe = max(lobeRGB.r * Rec709_Luminance.r * 3.0, max(lobeRGB.g * Rec709_Luminance.g * 3.0, lobeRGB.b * Rec709_Luminance.b * 3.0)); +#else + float localLobe = max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)); +#endif +#endif // RCAS_LUMINANCE_BASED + + float lobe = max(-RCAS_LIMIT, min(localLobe, 0.0)) * sharpness; + +#if RCAS_DENOISE >= 1 + // denoise + lobe *= nz; +#endif + + // Resolve, which needs medium precision rcp approximation to avoid visible tonality changes. + float rcpL = rcp(samplesNum * lobe + 1.0); + +#if RCAS_LUMINANCE_BASED + float outputLum = ((bLum + dLum + hLum + fLum) * lobe + eLum) * rcpL; + // Questionable choice: in case the source center pixel had luminance zero (even if the rgb ratio wasn't flat), elevate it to grey and match the target luminance, or we'd have a division by zero. + // The alternative would be to keep "e" intact, but that then wouldn't have applied any sharpening. + float3 output = eLum != 0 ? (e * (outputLum / eLum)) : outputLum; +#else // !RCAS_LUMINANCE_BASED + float3 output = ((b + d + f + h) * lobe + e) * rcpL; +#endif // RCAS_LUMINANCE_BASED + +#if 0 // Debug + if (dynamicSharpening) + { + if (originalSharpness < sharpness) + output.r *= 1 + (12.0 * (sharpness - originalSharpness)); + else + output.g *= 1 + (12.0 * (originalSharpness - sharpness)); + } +#endif + + output *= paperWhite; + + return output; +} + +#endif // SRC_RCAS_HLSL \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/Settings.hlsl b/Shaders/Middle-earth Shadow of War/Includes/Settings.hlsl deleted file mode 100644 index fba927a6..00000000 --- a/Shaders/Middle-earth Shadow of War/Includes/Settings.hlsl +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SRC_GAME_SETTINGS_HLSL -#define SRC_GAME_SETTINGS_HLSL - -// Include this after the global "Settings.hlsl" file - -///////////////////////////////////////// -// Template LUMA advanced settings -// (note that the defaults might be mirrored in c++, the shader values will be overridden anyway) -///////////////////////////////////////// - -#define EXAMPLE_TEMPLATE_DEFINE 1 - -#endif // SRC_GAME_SETTINGS_HLSL \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/ictcp_portable.hlsl b/Shaders/Middle-earth Shadow of War/Includes/ictcp_portable.hlsl new file mode 100644 index 00000000..48073985 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/Includes/ictcp_portable.hlsl @@ -0,0 +1,195 @@ +namespace renodx { +namespace color { + +namespace pq { +static const float M1 = 2610.f / 16384.f; // 0.1593017578125f; +static const float M2 = 128.f * (2523.f / 4096.f); // 78.84375f; +static const float C1 = 3424.f / 4096.f; // 0.8359375f; +static const float C2 = 32.f * (2413.f / 4096.f); // 18.8515625f; +static const float C3 = 32.f * (2392.f / 4096.f); // 18.6875f; + +float Encode(float color, float scaling = 10000.f) { + color *= (scaling / 10000.f); + float y_m1 = pow(color, M1); + return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); +} + +float3 Encode(float3 color, float scaling = 10000.f) { + color *= (scaling / 10000.f); + float3 y_m1 = pow(color, M1); + return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); +} + +float Decode(float color, float scaling = 10000.f) { + float e_m12 = pow(color, 1.f / M2); + float out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); + return out_color * (10000.f / scaling); +} + +float3 Decode(float3 color, float scaling = 10000.f) { + float3 e_m12 = pow(color, 1.f / M2); + float3 out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); + return out_color * (10000.f / scaling); +} + +float3 EncodeSafe(float3 color, float scaling = 10000.f) { + return Encode(max(0, color), scaling); +} + +float3 DecodeSafe(float3 color, float scaling = 10000.f) { + return Decode(max(0, color), scaling); +} + +} // namespace pq + +// According to Dolby +static const float3x3 XYZ_D65_TO_HUNT_POINTER_ESTEVEZ_LMS_MAT = float3x3( + +0.4002f, 0.7076f, -0.0808f, + -0.2263f, 1.1653f, +0.0457f, + +0.0000f, 0.0000f, +0.9182f); + +float3x3 Invert3x3(float3x3 m) { + float a = m[0][0], b = m[0][1], c = m[0][2]; + float d = m[1][0], e = m[1][1], f = m[1][2]; + float g = m[2][0], h = m[2][1], i = m[2][2]; + + float A = (e * i - f * h); + float B = -(d * i - f * g); + float C = (d * h - e * g); + float D = -(b * i - c * h); + float E = (a * i - c * g); + float F = -(a * h - b * g); + float G = (b * f - c * e); + float H = -(a * f - c * d); + float I = (a * e - b * d); + + float det = a * A + b * B + c * C; + float invDet = det > 0 ? 1.0 / det : 0.0; + + return float3x3( + A, D, G, + B, E, H, + C, F, I) + * invDet; +} + +static const float3x3 PLMS_TO_IPT_MAT = float3x3( + 0.4f, 0.4f, 0.2f, + 4.4550f, -4.8510f, 0.3960f, + 0.8056f, 0.3572f, -1.1628f); + +static const float3x3 BT709_TO_XYZ_MAT = float3x3( + 0.4123907993f, 0.3575843394f, 0.1804807884f, + 0.2126390059f, 0.7151686788f, 0.0721923154f, + 0.0193308187f, 0.1191947798f, 0.9505321522f); + +static const float3x3 BT2020_TO_XYZ_MAT = float3x3( + 0.6369580483f, 0.1446169036f, 0.1688809752f, + 0.2627002120f, 0.6779980715f, 0.0593017165f, + 0.0000000000f, 0.0280726930f, 1.0609850577f); + +namespace ictcp { +// https://professional.dolby.com/siteassets/pdfs/ictcp_dolbywhitepaper_v071.pdf + +static const float3x3 XYZ_TO_ICTCP_LMS_MAT = float3x3( + 0.359168797f, 0.697604775f, -0.0357883982f, + -0.192186400f, 1.10039842f, 0.0755404010f, + 0.00695759989f, 0.0749168023f, 0.843357980f); + +static const float3x3 ICTCP_LMS_TO_XYZ_MAT = float3x3( + 2.07036161f, -1.32659053f, 0.206681042f, + 0.364990383f, 0.680468797f, -0.0454616732f, + -0.0495028905f, -0.0495028905f, 1.18806946f); + +static const float3x3 BT709_TO_ICTCP_LMS_MAT = float3x3( + 0.295764088f, 0.623072445f, 0.0811667516f, + 0.156191974f, 0.727251648f, 0.116557933f, + 0.0351022854f, 0.156589955f, 0.808302998f); + +static const float3x3 ICTCP_LMS_TO_BT709_MAT = float3x3( + 6.17353248f, -5.32089900f, 0.147354885f, + -1.32403194f, 2.56026983f, -0.236238613f, + -0.0115983877f, -0.264921456f, 1.27652633f); + +static const float CROSSTALK = 0.04f; +static const float IPT_OPTIMIZATION = 1.0f; + +static const float3x3 CROSSTALK_MAT = float3x3( + 1.0f - (2 * CROSSTALK), CROSSTALK, CROSSTALK, + CROSSTALK, 1.0f - (2 * CROSSTALK), CROSSTALK, + CROSSTALK, CROSSTALK, 1.0f - (2 * CROSSTALK)); + +static const float3x3 XYZ_TO_DOLBY_LMS_MAT = mul(XYZ_D65_TO_HUNT_POINTER_ESTEVEZ_LMS_MAT, CROSSTALK_MAT); + +static const float3x3 PLMS_TO_IPT_OPTIMIZED_MAT = float3x3( + lerp(PLMS_TO_IPT_MAT[0], float3(0.5f, 0.5f, 0.0f), IPT_OPTIMIZATION), + PLMS_TO_IPT_MAT[1], + PLMS_TO_IPT_MAT[2]); + +static const float VECTORSCOPE_DEGREES = 65.f; +static const float ROTATION_POINT = VECTORSCOPE_DEGREES * 3.14159265358979323846f / 180.f; + +static const float3x3 IPT_ROTATION_MAT = float3x3( + 1.f, 0, 0.f, + 0, cos(ROTATION_POINT), -sin(ROTATION_POINT), + 0, sin(ROTATION_POINT), cos(ROTATION_POINT)); + +static const float SCALE_FACTOR = 1.4f; +static const float3x3 IPT_SCALE_MAT = float3x3( + 1.0f, 1.0f, 1.0f, + SCALE_FACTOR, SCALE_FACTOR, SCALE_FACTOR, + 1.0f, 1.0f, 1.0f); + +static const float3x3 PLMS_TO_ICTCP_MAT = mul(IPT_ROTATION_MAT, PLMS_TO_IPT_OPTIMIZED_MAT) * IPT_SCALE_MAT; + +namespace internal { +float3 BT709(float3 bt709_color, float scaling = 100.f) { + float3 lms = mul(mul(XYZ_TO_DOLBY_LMS_MAT, BT709_TO_XYZ_MAT), bt709_color); + float3 plms = pq::Encode(max(0, lms), scaling); + float3 ictcp_color = mul(PLMS_TO_ICTCP_MAT, plms); + return ictcp_color; +} +float3 BT2020(float3 bt2020_color, float scaling = 100.f) { + float3 lms = mul(mul(XYZ_TO_DOLBY_LMS_MAT, BT2020_TO_XYZ_MAT), bt2020_color); + float3 plms = pq::Encode(max(0, lms), scaling); + float3 ictcp_color = mul(PLMS_TO_ICTCP_MAT, plms); + return ictcp_color; +} +float3 ICtCpBT709(float3 ictcp_color, float scaling = 100.f) { + float3 plms_color = mul(Invert3x3(ictcp::PLMS_TO_ICTCP_MAT), ictcp_color); + float3 lms_color = pq::Decode(plms_color, scaling); + float3 bt709_color = mul( + mul( + Invert3x3(BT709_TO_XYZ_MAT), + Invert3x3(ictcp::XYZ_TO_DOLBY_LMS_MAT)), + lms_color); + return bt709_color; +} +float3 ICtCpBT2020(float3 ictcp_color, float scaling = 100.f) { + float3 plms_color = mul(Invert3x3(ictcp::PLMS_TO_ICTCP_MAT), ictcp_color); + float3 lms_color = pq::Decode(plms_color, scaling); + float3 bt709_color = mul( + mul( + Invert3x3(BT2020_TO_XYZ_MAT), + Invert3x3(ictcp::XYZ_TO_DOLBY_LMS_MAT)), + lms_color); + return bt709_color; +} +} + +float3 To(float3 rgb, uint colorSpace) +{ + if (colorSpace == 1) return internal::BT2020(rgb); + return internal::BT709(rgb); +} + +float3 From(float3 ictcp_color, uint colorSpace) +{ + if (colorSpace == 1) return internal::ICtCpBT2020(ictcp_color); + return internal::ICtCpBT709(ictcp_color); +} + + +} +} +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl new file mode 100644 index 00000000..e15eccc8 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl @@ -0,0 +1,41 @@ +// ---- Created with 3Dmigoto v1.3.16 on Tue Jul 14 22:11:10 2026 +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb3 : register(b3) +{ + float4 cb3[1]; +} + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + uint v2 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = min(cb3[0].zw, v1.xy); + r1.xyz = t0.SampleLevel(s0_s, r0.xy, 0).xyz * GS.Bloom; //bloom + r0.xyz = t1.SampleLevel(s0_s, r0.xy, 0).xyz; //godrays + o0.xyz = max(r1.xyz, r0.xyz); + // o0.xyz = r1.xyz + r0.xyz; + // { + // float y = GetLuminance(o0.xyz, CS_BT709); + // float y1 = y; + // y1 = Neutwo(y1, 0.055); + // y1 *= 1.25; + // o0.xyz *= DivideSafe(y1, y, 0); + // } + o0.w = 1; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 new file mode 100644 index 00000000..c1e827d1 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 @@ -0,0 +1,80 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:21 2026 +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb3 : register(b3) +{ + float4 cb3[4]; +} + + + + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + uint v2 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ +#if 0 + // Base sample at current pixel (unweighted) + float3 accum = t0.SampleLevel(s0_s, v1.xy, 0).xyz; + + // Radial step direction (from pixel towards light source center) + float2 dir = cb3[1].x * (cb3[2].xy - v1.xy); + + // Weight falls off with distance from center + float dist = sqrt(dot(dir, dir)); + float weight = cb3[1].y * (1.0 - saturate(dist * 2.0 - 1.0)); + + // Per-sample UV offset (1/48 of full direction) + float2 stepUV = dir * 0.020833334; + float2 uv = v1.xy + stepUV; + + [loop] + for (int i = 0; i < 48; i++) + { + bool oob = any(uv < float2(0, 0)) || any(uv > cb3[0].zw); + float3 color = oob ? float3(0, 0, 0) : t0.SampleLevel(s0_s, uv, 0).xyz; + accum += color * weight; + uv += stepUV; + weight *= cb3[1].z; + } + + o0.xyz = accum; + o0.w = 1; + return; +#else + static const int NUM_SAMPLES = 96; + + // Base + float3 accum = t0.SampleLevel(s0_s, v1.xy, 0).xyz; + + // Direction + float2 dir = cb3[1].x * (cb3[2].xy - v1.xy); + + // Weight + float dist = sqrt(dot(dir, dir)); + float weight = cb3[1].y * (1.0 - saturate(dist * 2.0 - 1.0)); + + // Step + float2 stepUV = dir / NUM_SAMPLES; + float decayPerStep = pow(cb3[1].z, 48.0 / NUM_SAMPLES); + float2 uv = v1.xy + stepUV; + + [loop] + for (int i = 0; i < NUM_SAMPLES; i++) + { + bool oob = any(uv < float2(0, 0)) || any(uv > cb3[0].zw); + float3 color = oob ? float3(0, 0, 0) : t0.SampleLevel(s0_s, uv, 0).xyz; + accum += color * weight; + uv += stepUV; + weight *= decayPerStep; + } + + o0.xyz = accum * 0.6; //fudge + o0.w = 1; + return; +#endif +} diff --git a/Shaders/Middle-earth Shadow of War/common.hlsl b/Shaders/Middle-earth Shadow of War/common.hlsl new file mode 100644 index 00000000..3b9a857a --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/common.hlsl @@ -0,0 +1,301 @@ +#include "./Includes/Common.hlsl" +// #include "./Includes/HermiteSpline_portable.hlsl" +#include "./Includes/ictcp_portable.hlsl" + +#define FIRE_PEAK 1.26 +#define FIRE_BOOST 2.6 + +///////////////////////////////////////////////////////////////////////////////////////// +// rect is top left (x,y), bottom right (x,y) +float3 DrawRect(float2 uv, float4 rect, float3 color, float3 rectColor) { + float r = step(rect.x, uv.x) * step(uv.x, rect.z) * step(rect.y, uv.y) * step(uv.y, rect.w); + if (r == 0) return color; + return rectColor; +} +//////////////////////////////////////////////////////////////////////////////////////// +float3 RestoreHueAndChrominanceUcsInternal(float3 targetUcs, float3 sourceUcs, float currentChrominance, float hueStrength, float chrominanceStrength, float minChromaRatio = 0.f) +{ + if (targetUcs.x == 0) return targetUcs; + + if (hueStrength != 0.0) + { + const float chrominancePre = currentChrominance; + targetUcs.yz = lerp(targetUcs.yz, sourceUcs.yz, hueStrength); + const float chrominancePost = length(targetUcs.yz); + float chrominanceRatio = safeDivision(chrominancePre, chrominancePost, 1); + targetUcs.yz *= chrominanceRatio; + } + + if (chrominanceStrength != 0.0) + { + const float sourceChrominance = length(sourceUcs.yz); + float targetChrominanceRatio = safeDivision(sourceChrominance, currentChrominance, 1); + targetChrominanceRatio = clamp(targetChrominanceRatio, minChromaRatio, FLT_MAX); + targetUcs.yz *= lerp(1.0, targetChrominanceRatio, chrominanceStrength); + } + + return targetUcs; +} + +float3 RestoreHueAndChrominanceUcs(float3 targetUcs, float3 sourceUcs, float hueStrength, float chrominanceStrength, float minChromaRatio = 0.f) +{ + return RestoreHueAndChrominanceUcsInternal(targetUcs, sourceUcs, length(targetUcs.yz), hueStrength, chrominanceStrength, minChromaRatio); +} +//////////////////////////////////////////////////////////////////////////////////////// +float3 UCS_Encode(float3 x) { + return renodx::color::ictcp::To(x, CS_BT709); +} +float3 UCS_Decode(float3 x) { + return renodx::color::ictcp::From(x, CS_BT709); +} +///////////////////////////////////////////////////////////////////////////////////////// +// float GetLuminance(float3 x) { +// return dot(x, float3(0.2126390059f, 0.7151686788f, 0.0721923154f)); +// } +float3 ClampByMaxChannel(float3 x, float p) { + float m = max(max(x.x, x.y), x.z); + if (m > p) x *= p / m; + return x; +} +float DivideSafe(float numerator, float denominator, float defaultValue) { + return denominator != 0.0f ? numerator / denominator : defaultValue; +} +float3 DivideSafe(float3 numerator, float3 denominator, float3 defaultValue) { + return denominator != 0.0f ? numerator / denominator : defaultValue; +} +bool FloatEquals(float a, float b, float epsilon) { + return abs(a - b) <= epsilon; +} +///////////////////////////////////////////////////////////////////////////////////////// +float Neutwo(float x) { + float numerator = x; + float denominator_squared = mad(x, x, 1.0); + return numerator * rsqrt(denominator_squared); +} +float Neutwo(float x, float peak) { + float p = peak; + + float numerator = p * x; + float denominator_squared = mad(x, x, p * p); + return numerator * rsqrt(denominator_squared); +} +float3 Neutwo(float3 x, float peak) { + float p = peak; + + float3 numerator = p * x; + float3 denominator_squared = mad(x, x, p * p); + return numerator * rsqrt(denominator_squared); +} +float3 Neupow(float3 x, float peak, float power) { + float p = peak; + float3 numerator = p * x; + float3 denominator_pow = pow(x, power) + pow(p, power); + return numerator / pow(denominator_pow, rcp(power)); +} +float Neupow(float x, float peak, float power) { + float p = peak; + float numerator = p * x; + float denominator_pow = pow(x, power) + pow(p, power); + return numerator / pow(denominator_pow, rcp(power)); +} + +float Neutwo(float x, float peak, float clip) { + float p = peak; + float c = clip; + float cc = c * c; + float pp = p * p; + float xx = x * x; + + float numerator = c * p * x; + float denominator_squared = mad(xx, (cc - pp), cc * pp); + + return numerator * rsqrt(denominator_squared); +} +float3 Neutwo(float3 x, float peak, float clip) { + float p = peak; + float c = clip; + float cc = c * c; + float pp = p * p; + float3 xx = x * x; + + float3 numerator = c * p * x; + float3 denominator_squared = mad(xx, (cc - pp), cc * pp); + + return numerator * rsqrt(denominator_squared); +} +float2 Neutwo(float2 x, float peak, float clip) { + float p = peak; + float c = clip; + float cc = c * c; + float pp = p * p; + float2 xx = x * x; + + float2 numerator = c * p * x; + float2 denominator_squared = mad(xx, (cc - pp), cc * pp); + + return numerator * rsqrt(denominator_squared); +} +float NeutwoI(float x, float peak, float clip) { + float p = peak; + float c = clip; + float cc = c * c; + float pp = p * p; + float xx = x * x; + float numerator = c * p * x; + float denominator_squared = mad(-xx, (cc - pp), cc * pp); + return numerator * rsqrt(denominator_squared); +} +float3 NeutwoI(float3 x, float peak, float clip) { + float p = peak; + float c = clip; + float cc = c * c; + float pp = p * p; + float3 xx = x * x; + float3 numerator = c * p * x; + float3 denominator_squared = mad(-xx, (cc - pp), cc * pp); + return numerator * rsqrt(denominator_squared); +} +float3 Neupow(float3 x, float peak, float clip, float power) { + float p = peak; + float c = clip; + float cc = pow(c, power); + float pp = pow(p, power); + float3 xx = pow(x, power); + + float3 numerator = c * p * x; + float3 denominator_pow = xx * ((cc - pp)) + (cc * pp); + return numerator / pow(denominator_pow, rcp(power)); +} +float Neupow(float x, float peak, float clip, float power) { + float p = peak; + float c = clip; + float cc = pow(c, power); + float pp = pow(p, power); + float xx = pow(x, power); + + float numerator = c * p * x; + float denominator_pow = xx * ((cc - pp)) + (cc * pp); + return numerator / pow(denominator_pow, rcp(power)); +} +///////////////////////////////////////////////////////////////////////////////////////// +float ReinhardSimple(float x, float peak = 1.0) +{ + return x / ((abs(x) / peak) + 1.0); +} +float3 ReinhardSimple(float3 x, float peak = 1.0) +{ + return x / ((abs(x) / peak) + 1.0); +} +float ReinhardExtended(float color, float white_max = 1000.f / 203.f, float peak = 1.f) { + return ReinhardSimple(color, peak) * (1.f + (peak * color) / (white_max * white_max)); +} +float3 ReinhardExtended(float3 color, float white_max = 1000.f / 203.f, float peak = 1.f) { + return ReinhardSimple(color, peak) * (1.f + (peak * color) / (white_max * white_max)); +} +float ComputeReinhardScale(float channel_max = 1.f, float channel_min = 0.f, float gray_in = MidGray, float gray_out = MidGray) { + return (channel_max * (channel_min * gray_out + channel_min - gray_out)) + / (gray_in * (gray_out - channel_max)); +} +float3 ReinhardPiecewise(float3 x, float x_max = 1.f, float shoulder = 0.18f) { + const float x_min = 0.f; + float exposure = ComputeReinhardScale(x_max, x_min, shoulder, shoulder); + float3 tonemapped = mad(x, exposure, x_min) / mad(x, exposure / x_max, 1.f - x_min); + return lerp(x, tonemapped, step(shoulder, x)); +} +float ReinhardPiecewise(float x, float x_max = 1.f, float shoulder = 0.18f) { + const float x_min = 0.f; + float exposure = ComputeReinhardScale(x_max, x_min, shoulder, shoulder); + float tonemapped = mad(x, exposure, x_min) / mad(x, exposure / x_max, 1.f - x_min); + return lerp(x, tonemapped, step(shoulder, x)); +} +//////////////////////////////////////////////////////////////////////////////////////// +/// Piecewise linear + exponential compression to a target value starting from a specified number. +/// https://www.ea.com/frostbite/news/high-dynamic-range-color-grading-and-display-in-frostbite +#define EXPONENTIALROLLOFF_GENERATOR(T) \ + T ExponentialRollOff(T input, float rolloff_start = 0.20f, float output_max = 1.0f) { \ + T rolloff_size = output_max - rolloff_start; \ + T overage = -max((T)0, input - rolloff_start); \ + T rolloff_value = (T)1.0f - exp(overage / rolloff_size); \ + T new_overage = mad(rolloff_size, rolloff_value, overage); \ + return input + new_overage; \ + } +#define EXPONENTIALROLLOFF_CLIP_GENERATOR(T) \ + T ExponentialRollOff(T input, float rolloff_start, float output_max, float clip) { \ + T rolloff_size = output_max - rolloff_start; \ + T overage = -max((T)0, input - rolloff_start); \ + T clip_size = rolloff_start - clip; \ + T rolloff_value = (T)1.0f - exp(overage / rolloff_size); \ + T clip_value = (T)1.0f - exp(clip_size / rolloff_size); \ + T new_overage = mad(rolloff_size, rolloff_value / clip_value, overage); \ + return input + new_overage; \ + } +EXPONENTIALROLLOFF_GENERATOR(float) +EXPONENTIALROLLOFF_GENERATOR(float3) +EXPONENTIALROLLOFF_CLIP_GENERATOR(float) +EXPONENTIALROLLOFF_CLIP_GENERATOR(float3) +#undef EXPONENTIALROLLOFF_GENERATOR +#undef EXPONENTIALROLLOFF_CLIP_GENERATOR +////////////////////////////////////////////////////////////////////////////////////// +// Uchimura 2018, "Practical HDR and Wide Color Techniques in Gran Turismo SPORT" +// https://www.desmos.com/calculator/gslcdxvipg +// http://cdn2.gran-turismo.com/data/www/pdi_publications/PracticalHDRandWCGinGTS.pdf +#define GTTONEMAP_GENERATOR(T) \ + T GTTonemap(T x, \ + float P = 1.f, \ + float a = 1.f, \ + float m = 0.22f, \ + float l = 0.4f, \ + float c = 1.33f, \ + float b = 0.f) { \ + float l0 = ((P - m) * l) / a; \ + float L0 = m - (m / a); \ + float L1 = m + (1.0f - m) / a; \ + \ + T S0 = m + l0; \ + T S1 = m + a * l0; \ + T C2 = (a * P) / (P - S1); \ + T CP = -C2 / P; \ + \ + T w0 = 1.0f - smoothstep(0.0f, m, x); \ + T w2 = step(m + l0, x); \ + T w1 = 1.0f - w0 - w2; \ + \ + T T_ = m * pow(x / m, c) + b; \ + T S_ = P - (P - S1) * exp(CP * (x - S0)); \ + T L_ = m + a * (x - m); \ + \ + return T_ * w0 + L_ * w1 + S_ * w2; \ + } +GTTONEMAP_GENERATOR(float) +GTTONEMAP_GENERATOR(float3) +#undef GTTONEMAP_GENERATOR +float3 GTTonemapToe(float3 x, float m = 100/203, float c = 1.027) { + m = max(m, 0.0001f); + float3 w0 = 1.0f - smoothstep(0.0f, m, x); + float3 T_ = m * pow(x / m, c); + return T_ * w0 + x * (1.0f - w0); +} +//////////////////////////////////////////////////////////////////////////////////////// +float3 HDRTonemap(float3 x, float peak, float start = 0.18) { + x = Neupow(x, peak, 1 * GS.WhiteClip); + // x = ExponentialRollOff(x, start, peak); + // x = ReinhardExtended(x, 10, peak); + // x = ReinhardPiecewise(x, peak, start); + return x; +} +//////////////////////////////////////////////////////////////////////////////////////// +float FireTonemap(float x, float clip = FIRE_PEAK, float output_max = 1.0f) { + x = min(x, clip); + x = Neutwo(x, output_max, clip); + return x; +} +float2 FireTonemap(float2 x, float clip = FIRE_PEAK, float output_max = 1.0f) { + x = min(x, clip); + x = Neutwo(x, output_max, clip); + return x; +} +float3 FireTonemap(float3 x, float clip = FIRE_PEAK, float output_max = 1.0f) { + x = min(x, clip); + x = Neutwo(x, output_max, clip); + return x; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 new file mode 100644 index 00000000..73da697b --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 @@ -0,0 +1,778 @@ +//Even if this is right, it seems like the CPU does stuff afterwards before tonemap? + + + + + + + + + + + + +// +// ExposureTonemap_CS.hlsl +// Compute shader: calculates scene exposure (median luminance from a tile texture) +// and computes coefficients for a modified Reinhard-like SDR tonemapper. +// +// Resources: +// t0 : Texture2D – per-tile luminance/luma texture +// u0 : RWBuffer – output: exposure / tonemapper coefficients [0..5] +// u1 : RWBuffer – output: second set of tonemapper coefficients [0..5] +// CB3[0] : (x=width, y=height, zw=unused) +// CB3[1] : (x=maxLog, y=gamma0, z=gamma1, w=unused) +// CB3[2] : (x=minLum0, y=minLum1, z=minExposure, w=minLum2) +// CB3[3] : (x=maxExposure, y=maxLum2, z=maxLum0, w=maxLum1) +// CB3[4] : (x=white0, y=white1, z=normScale0, w=normScale1) +// + +Texture2D t0 : register(t0); +RWBuffer u0 : register(u0); +RWBuffer u1 : register(u1); + +cbuffer CB3 : register(b3) +{ + float4 CB3_0; // x = tileWidth, y = tileHeight + float4 CB3_1; // x = maxLog, y = gamma0, z = gamma1 + float4 CB3_2; // x = minLum0, y = minLum1, z = minExposure, w = minLum2 + float4 CB3_3; // x = maxExposure, y = maxLum2, z = maxLum0, w = maxLum1 + float4 CB3_4; // x = white0, y = white1, z = normScale0, w = normScale1 +} + +groupshared float g0[256]; + +// Helper: sample luminance from tile texture at linear index idx, +// returning 1e6 if out of range. +// The original fetches the .y swizzle component (green / luminance channel). +float SampleTile(uint idx, uint totalTiles) +{ + if (idx < totalTiles) + { + float fi = (float)idx; + float w = CB3_0.x; + + // Absolute-value division to get integer column and fractional row + // (mirrors the ge/movc abs-value trick in the disasm) + float absW = (fi * w >= -(fi * w)) ? w : -w; + float invAbsW = 1.0f / absW; + float col = frac(fi * invAbsW) * absW; + float row = floor(fi / w); + + uint2 coord = uint2((uint)col, (uint)row); + return t0.Load(int3(coord, 0)).y; // .yzxw swizzle -> .y component + } + return 1000000.0f; +} + +[numthreads(128, 1, 1)] +void main(uint3 vThreadID : SV_DispatchThreadID) +{ + uint tid = vThreadID.x; + + // ------------------------------------------------------------------------- + // Phase 1: Each thread loads two elements into groupshared memory. + // Indices: even = tid*2, odd = tid*2+1 + // ------------------------------------------------------------------------- + uint totalTiles = (uint)(CB3_0.y * CB3_0.x); + + uint idx0 = tid * 2; + uint idx1 = tid * 2 + 1; + + g0[idx0] = SampleTile(idx0, totalTiles); + g0[idx1] = SampleTile(idx1, totalTiles); + + GroupMemoryBarrierWithGroupSync(); + + // ------------------------------------------------------------------------- + // Phase 2: Initial compare-and-swap on the two loaded elements. + // ------------------------------------------------------------------------- + float v0 = g0[idx0]; + float v1 = g0[idx1]; + + if (v1 < v0) + { + g0[idx0] = v1; + g0[idx1] = v0; + } + + GroupMemoryBarrierWithGroupSync(); + + // ------------------------------------------------------------------------- + // Phase 3: Bitonic sort across the full 256-element shared array. + // + // Outer loop doubles the sub-sequence size k (4, 8, 16, ... up to 256). + // Inner loop does the comparisons for each level of the butterfly. + // ------------------------------------------------------------------------- + for (uint k = 4; k <= 256; k <<= 1) + { + // Outer butterfly pass for sub-sequence size k + { + uint halfK = k >> 1; + uint blockId = tid / halfK; + uint posA = blockId * k + (tid % halfK); // = imad(blockId, k, tid%halfK) → r0.w + uint posB = blockId * k + k - 1 - (tid % halfK); // complementary index → r1.x + + // posB recomputed from disasm: imad(blockId,k,k) - (tid%halfK) - 1 + // i.e. iadd(iadd(imad(blockId,k,k), -tid%halfK), -1) + + float va = g0[posB]; + float vb = g0[posA]; + + if (va < vb) + { + g0[posA] = va; + g0[posB] = vb; + } + + GroupMemoryBarrierWithGroupSync(); + } + + // Inner merge passes (sub-sequence size shrinks: halfK, halfK/2, ... 2) + for (uint subK = k >> 1; subK >= 2; subK >>= 1) + { + uint halfSub = subK >> 1; + uint blockId = tid / halfSub; + uint posA = blockId * subK + (tid % halfSub); // → r1.y + uint posB = posA + halfSub; // → r1.z + + float va = g0[posA]; + float vb = g0[posB]; + + if (vb < va) + { + g0[posA] = vb; + g0[posB] = va; + } + + GroupMemoryBarrierWithGroupSync(); + } + } + + // ------------------------------------------------------------------------- + // Phase 4: Thread 0 reads the median and computes all outputs. + // ------------------------------------------------------------------------- + if (tid == 0) + { + // --- Median luminance --- + // If totalTiles is odd, median is the center element. + // If even, median is average of the two center elements. + float median; + if (totalTiles & 1) + { + median = g0[totalTiles >> 1]; + } + else + { + uint half = totalTiles >> 1; + float lo = g0[half]; + float hi = g0[half + 1]; + median = (lo + hi) * 0.5f; + } + median = max(median, 1e-5f); + + // ----------------------------------------------------------------------- + // Exposure / tonemapper computations + // Uses log-space clamping: if |log(ratio)| > maxLog, clamp to ±maxLog. + // ----------------------------------------------------------------------- + + // --- u0 source: current auto-exposure value --- + float curExposure = u0[0].y; // read back current exposure from u0[0] + + // Clamp raw exposure to [minExposure, maxExposure] + float2 medianScaled = median / CB3_4.zw; // div by normScale0, normScale1 + medianScaled = clamp(medianScaled, CB3_2.zz, CB3_3.xx); // [minExposure, maxExposure] + curExposure = clamp(curExposure, CB3_2.z, CB3_3.x); + + // Log-space step for u0 dimension 0: ratio = medianScaled.x / curExposure + float ratio0 = medianScaled.x / curExposure; + float logR0 = log2(ratio0); // shader uses log (natural log base-e; approximated here as log2 for readability—actual is base-e) + float sign0 = (logR0 > 0.0f) ? 1.0f : ((logR0 < 0.0f) ? -1.0f : 0.0f); + if (abs(logR0) > CB3_1.x) + logR0 = sign0 * CB3_1.x; + float newExposure0 = exp2(logR0) * curExposure; + + // Apply gamma0 in log space + float logE0 = log2(newExposure0); + float E0 = exp2(logE0 * CB3_1.y); // pow(newExposure0, gamma0) + + // Compute minLum0 and minLum1 raised to gamma0 + float2 logMin01 = log2(CB3_2.xy); + float2 minG01 = exp2(logMin01 * CB3_1.yy); // pow(minLum0, gamma0), pow(minLum1, gamma0) – but only .xz used + + float rangeW0 = minG01.x - E0; // r1.w (add -E0 + minG01.x) + rangeW0 = max(rangeW0, 1e-5f); + + // Coefficient 1 for u0 (index 1): (minG01.x/white0 - E0/maxLum0) / rangeW0 + float coeff0_u0 = (minG01.x / CB3_4.x - E0 / CB3_3.z) / rangeW0; // r2.x + + // Coefficient 2 for u0 (index 2): (E0*minG01.x/maxLum0 - E0*minG01.x/white0) / rangeW0 + float E0min0 = E0 * minG01.x; + float coeff2_u0 = (E0min0 / CB3_3.z - E0min0 / CB3_4.x) / rangeW0; // r0.w + + // --- u1 source: secondary exposure value --- + float curLum1 = u1[0].x; + curLum1 = clamp(curLum1, CB3_2.w, CB3_3.y); + + // Log-space step for u1 dimension 0: ratio = medianScaled.y / curLum1 + float ratio1 = medianScaled.y / curLum1; + float logR1 = log2(ratio1); + float sign1 = (logR1 > 0.0f) ? 1.0f : ((logR1 < 0.0f) ? -1.0f : 0.0f); + if (abs(logR1) > CB3_1.x) + logR1 = sign1 * CB3_1.x; + float newLum1 = exp2(logR1) * curLum1; + + // Apply gamma1 in log space + float logL1 = log2(newLum1); + float L1 = exp2(logL1 * CB3_1.z); // pow(newLum1, gamma1) + + // Compute minLum1 raised to gamma1 (reuse minG01.y ~ r1.z) + float minG1 = exp2(log2(CB3_2.y) * CB3_1.z); // pow(minLum1, gamma1) + + float rangeW1 = minG1 - L1; + rangeW1 = max(rangeW1, 1e-5f); + + // Coefficient 1 for u1 (index 1): (minG1/white1 - L1/maxLum1) / rangeW1 + float coeff1_u1 = (minG1 / CB3_4.y - L1 / CB3_3.w) / rangeW1; // r2.y + + // Coefficient 2 for u1 (index 2): (L1*minG1/maxLum1 - L1*minG1/white1) / rangeW1 + float L1min1 = L1 * minG1; + float coeff2_u1 = (L1min1 / CB3_3.w - L1min1 / CB3_4.y) / rangeW1; // r1.y + + // ----------------------------------------------------------------------- + // Write outputs (only if not NaN/Inf — the shader checks for infinity bits) + // ----------------------------------------------------------------------- + // u0[0] = curExposure (passthrough, only if finite) + if (isfinite(curExposure)) + u0[0] = curExposure; + + // u0[1] = coeff0_u0 + if (isfinite(coeff0_u0)) + u0[1] = coeff0_u0; + + // u0[2] = coeff2_u0 + if (isfinite(coeff2_u0)) + u0[2] = coeff2_u0; + + // u1[0] = curLum1 + if (isfinite(curLum1)) + u1[0] = curLum1; + + // u1[1] = coeff1_u1 + if (isfinite(coeff1_u1)) + u1[1] = coeff1_u1; + + // u1[2] = coeff2_u1 + if (isfinite(coeff2_u1)) + u1[2] = coeff2_u1; + + // ----------------------------------------------------------------------- + // Median value (g0[0] = minimum of sorted array), normalized — u0[3..5] / u1[3..5] + // ----------------------------------------------------------------------- + float sortedMin = g0[0]; + float2 normMin = sortedMin / CB3_4.zw; // div by normScale0, normScale1 + + u0[3] = normMin.x; + u0[4] = median; // raw median (r0.y was preserved) + + // Last element of sorted array = maximum sample + float sortedMax = g0[totalTiles - 1]; + float2 normMax = sortedMax / CB3_4.zw; + + u0[5] = normMax.x; + u1[3] = normMin.y; + u1[4] = median; // same raw median, second buffer + u1[5] = normMax.y; + } +} + + + + + + +// // ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:44 2026 +// groupshared struct { float val[1]; } g0[256]; +// Texture2D t0 : register(t0); +// +// cbuffer cb3 : register(b3) +// { +// float4 cb3[5]; +// } +// +// +// +// +// // 3Dmigoto declarations +// #define cmp - +// +// +// void main) +// { +// // Needs manual fix for instruction: +// // unknown dcl_: dcl_uav_typed_buffer (float,float,float,float) u0 +// // Needs manual fix for instruction: +// // unknown dcl_: dcl_uav_typed_buffer (float,float,float,float) u1 +// float4 r0,r1,r2,r3; +// uint4 bitmask, uiDest; +// float4 fDest; +// +// // Needs manual fix for instruction: +// // unknown dcl_: dcl_thread_group 128, 1, 1 +// r0.x = cb3[0].x * cb3[0].y; +// r0.x = (uint)r0.x; +// r0.y = (uint)vThreadID.x << 1; +// r0.z = cmp((uint)r0.y < (uint)r0.x); +// if (r0.z != 0) { +// r0.z = (uint)r0.y; +// r0.w = r0.z / cb3[0].x; +// r0.w = floor(r0.w); +// r1.x = cb3[0].x * r0.z; +// r1.x = cmp(r1.x >= -r1.x); +// r1.x = r1.x ? cb3[0].x : -cb3[0].x; +// r1.y = 1 / r1.x; +// r0.z = r1.y * r0.z; +// r0.z = frac(r0.z); +// r0.z = r1.x * r0.z; +// r1.xy = (uint2)r0.zw; +// r1.zw = float2(0,0); +// r0.z = t0.Load(r1.xyz).x; +// } else { +// r0.z = 1000000; +// } +// g0[r0.y].val[0/4] = r0.z; +// r0.z = mad((int)vThreadID.x, 2, 1); +// r0.w = cmp((uint)r0.z < (uint)r0.x); +// if (r0.w != 0) { +// r0.w = (uint)r0.z; +// r1.x = r0.w / cb3[0].x; +// r1.x = floor(r1.x); +// r1.y = cb3[0].x * r0.w; +// r1.y = cmp(r1.y >= -r1.y); +// r1.y = r1.y ? cb3[0].x : -cb3[0].x; +// r1.z = 1 / r1.y; +// r0.w = r1.z * r0.w; +// r0.w = frac(r0.w); +// r0.w = r1.y * r0.w; +// r2.x = (uint)r0.w; +// r2.y = (uint)r1.x; +// r2.zw = float2(0,0); +// r0.w = t0.Load(r2.xyz).x; +// } else { +// r0.w = 1000000; +// } +// g0[r0.z].val[0/4] = r0.w; +// GroupMemoryBarrierWithGroupSync(); +// r1.y = g0[r0.y].val[0/4]; +// r1.x = g0[r0.z].val[0/4]; +// r0.w = cmp(r1.x < r1.y); +// r1.xy = r0.ww ? r1.xy : r1.yx; +// g0[r0.y].val[0/4] = r1.x; +// g0[r0.z].val[0/4] = r1.y; +// GroupMemoryBarrierWithGroupSync(); +// r0.y = 4; +// while (true) { +// r0.z = cmp(256 < (uint)r0.y); +// if (r0.z != 0) break; +// r0.z = (uint)r0.y >> 1; +// uiDest.x = (uint)vThreadID.x / (uint)r0.z; +// r2.x = (uint)vThreadID.x % (uint)r0.z; +// r1.x = uiDest.x; +// r0.w = mad((int)r1.x, (int)r0.y, (int)r2.x); +// r3.y = g0[r0.w].val[0/4]; +// r1.x = mad((int)r1.x, (int)r0.y, (int)r0.y); +// r1.x = (int)-r2.x + (int)r1.x; +// r1.x = (int)r1.x + -1; +// r3.x = g0[r1.x].val[0/4]; +// r1.y = cmp(r3.x < r3.y); +// r1.yz = r1.yy ? r3.xy : r3.yx; +// g0[r0.w].val[0/4] = r1.y; +// g0[r1.x].val[0/4] = r1.z; +// GroupMemoryBarrierWithGroupSync(); +// r0.w = r0.z; +// while (true) { +// r1.x = cmp((uint)r0.w < 2); +// if (r1.x != 0) break; +// r1.x = (uint)r0.w >> 1; +// uiDest.x = (uint)vThreadID.x / (uint)r1.x; +// r3.x = (uint)vThreadID.x % (uint)r1.x; +// r2.x = uiDest.x; +// r1.y = mad((int)r2.x, (int)r0.w, (int)r3.x); +// r2.y = g0[r1.y].val[0/4]; +// r1.z = (int)r1.x + (int)r1.y; +// r2.x = g0[r1.z].val[0/4]; +// r1.w = cmp(r2.x < r2.y); +// r2.xy = r1.ww ? r2.xy : r2.yx; +// g0[r1.y].val[0/4] = r2.x; +// g0[r1.z].val[0/4] = r2.y; +// GroupMemoryBarrierWithGroupSync(); +// r0.w = r1.x; +// } +// r0.y = (uint)r0.y << 1; +// } +// if (vThreadID.x == 0) { +// r0.y = (int)r0.x & 1; +// if (r0.y != 0) { +// r0.y = (uint)r0.x >> 1; +// r0.y = g0[r0.y].val[0/4]; +// } else { +// r0.z = (uint)r0.x >> 1; +// r0.w = g0[r0.z].val[0/4]; +// r0.z = (int)r0.z + 1; +// r0.z = g0[r0.z].val[0/4]; +// r0.z = r0.w + r0.z; +// r0.y = 0.5 * r0.z; +// } +// r0.y = max(9.99999975e-006, r0.y); +// // No code for instruction (needs manual fix): +// ld_uav_typed_indexable(buffer)(float,float,float,float) r0.z, l(0, 0, 0, 0), u0.yzxw +// r1.xy = r0.yy / cb3[4].zw; +// r1.xy = max(cb3[2].zw, r1.xy); +// r1.xy = min(cb3[3].xy, r1.xy); +// r0.z = max(cb3[2].z, r0.z); +// r0.z = min(cb3[3].x, r0.z); +// r0.w = r1.x / r0.z; +// r0.w = log2(r0.w); +// r1.x = cmp(cb3[1].x < abs(r0.w)); +// r1.z = cmp(0 < r0.w); +// r1.w = cmp(r0.w < 0); +// r1.z = (int)-r1.z + (int)r1.w; +// r1.z = (int)r1.z; +// r1.z = cb3[1].x * r1.z; +// r0.w = r1.x ? r1.z : r0.w; +// r0.w = exp2(r0.w); +// r0.z = r0.z * r0.w; +// r0.w = log2(r0.z); +// r0.w = cb3[1].y * r0.w; +// r0.w = exp2(r0.w); +// r1.xz = log2(cb3[2].xy); +// r1.xz = cb3[1].yz * r1.xz; +// r1.xz = exp2(r1.xz); +// r1.w = r1.x + -r0.w; +// r1.w = max(9.99999975e-006, r1.w); +// r2.xy = r1.xz / cb3[4].xy; +// r2.z = r0.w / cb3[3].z; +// r2.x = r2.x + -r2.z; +// r2.x = r2.x / r1.w; +// r0.w = r1.x * r0.w; +// r1.x = r0.w / cb3[3].z; +// r0.w = r0.w / cb3[4].x; +// r0.w = r1.x + -r0.w; +// r0.w = r0.w / r1.w; +// // No code for instruction (needs manual fix): +// ld_uav_typed_indexable(buffer)(float,float,float,float) r1.x, l(0, 0, 0, 0), u1.xyzw +// r1.x = max(cb3[2].w, r1.x); +// r1.x = min(cb3[3].y, r1.x); +// r1.y = r1.y / r1.x; +// r1.y = log2(r1.y); +// r1.w = cmp(cb3[1].x < abs(r1.y)); +// r2.z = cmp(0 < r1.y); +// r2.w = cmp(r1.y < 0); +// r2.z = (int)-r2.z + (int)r2.w; +// r2.z = (int)r2.z; +// r2.z = cb3[1].x * r2.z; +// r1.y = r1.w ? r2.z : r1.y; +// r1.y = exp2(r1.y); +// r1.x = r1.x * r1.y; +// r1.y = log2(r1.x); +// r1.y = cb3[1].z * r1.y; +// r1.y = exp2(r1.y); +// r1.w = r1.z + -r1.y; +// r1.w = max(9.99999975e-006, r1.w); +// r2.z = r1.y / cb3[3].w; +// r2.y = r2.y + -r2.z; +// r2.y = r2.y / r1.w; +// r1.y = r1.z * r1.y; +// r1.z = r1.y / cb3[3].w; +// r1.y = r1.y / cb3[4].y; +// r1.y = r1.z + -r1.y; +// r1.y = r1.y / r1.w; +// r1.z = (int)r0.z & 0x7f800000; +// r1.z = cmp((int)r1.z != 0x7f800000); +// if (r1.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(0,0,0,0), r0.zzzz +// } +// r0.z = (int)r2.x & 0x7f800000; +// r0.z = cmp((int)r0.z != 0x7f800000); +// if (r0.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(1,1,1,1), r2.xxxx +// } +// r0.z = (int)r0.w & 0x7f800000; +// r0.z = cmp((int)r0.z != 0x7f800000); +// if (r0.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(2,2,2,2), r0.wwww +// } +// r0.z = (int)r1.x & 0x7f800000; +// r0.z = cmp((int)r0.z != 0x7f800000); +// if (r0.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(0,0,0,0), r1.xxxx +// } +// r0.z = (int)r2.y & 0x7f800000; +// r0.z = cmp((int)r0.z != 0x7f800000); +// if (r0.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(1,1,1,1), r2.yyyy +// } +// r0.z = (int)r1.y & 0x7f800000; +// r0.z = cmp((int)r0.z != 0x7f800000); +// if (r0.z != 0) { +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(2,2,2,2), r1.yyyy +// } +// r0.z = g0[0].val[0/4]; +// r0.zw = r0.zz / cb3[4].zw; +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(3,3,3,3), r0.zzzz +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(4,4,4,4), r0.yyyy +// r0.x = (int)r0.x + -1; +// r0.x = g0[r0.x].val[0/4]; +// r0.xz = r0.xx / cb3[4].zw; +// // No code for instruction (needs manual fix): +// store_uav_typed u0.xyzw, l(5,5,5,5), r0.xxxx +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(3,3,3,3), r0.wwww +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(4,4,4,4), r0.yyyy +// // No code for instruction (needs manual fix): +// store_uav_typed u1.xyzw, l(5,5,5,5), r0.zzzz +// } +// return; +// } + + +// // +// // Generated by Microsoft (R) D3D Shader Disassembler +// // +// // +// // Input signature: +// // +// // Name Index Mask Register SysValue Format Used +// // -------------------- ----- ------ -------- -------- ------- ------ +// // no Input +// // +// // Output signature: +// // +// // Name Index Mask Register SysValue Format Used +// // -------------------- ----- ------ -------- -------- ------- ------ +// // no Output +// 0x00000000: cs_5_0 +// 0x00000008: dcl_globalFlags refactoringAllowed +// 0x0000000C: dcl_constantbuffer CB3[5], immediateIndexed +// 0x0000001C: dcl_resource_texture2d (float,float,float,float) t0 +// 0x0000002C: dcl_uav_typed_buffer (float,float,float,float) u0 +// 0x0000003C: dcl_uav_typed_buffer (float,float,float,float) u1 +// 0x0000004C: dcl_input vThreadID.x +// 0x00000054: dcl_temps 4 +// 0x0000005C: dcl_tgsm_structured g0, 4, 256 +// 0x00000070: dcl_thread_group 128, 1, 1 +// 0 0x00000080: mul r0.x, cb3[0].y, cb3[0].x +// 1 0x000000A4: ftou r0.x, r0.x +// 2 0x000000B8: ishl r0.y, vThreadID.x, l(1) +// 3 0x000000D0: ult r0.z, r0.y, r0.x +// 4 0x000000EC: if_nz r0.z +// 5 0x000000F8: utof r0.z, r0.y +// 6 0x0000010C: div r0.w, r0.z, cb3[0].x +// 7 0x0000012C: round_ni r0.w, r0.w +// 8 0x00000140: mul r1.x, r0.z, cb3[0].x +// 9 0x00000160: ge r1.x, r1.x, -r1.x +// 10 0x00000180: movc r1.x, r1.x, cb3[0].x, -cb3[0].x +// 11 0x000001B0: div r1.y, l(1.000000, 1.000000, 1.000000, 1.000000), r1.x +// 12 0x000001D8: mul r0.z, r0.z, r1.y +// 13 0x000001F4: frc r0.z, r0.z +// 14 0x00000208: mul r0.z, r0.z, r1.x +// 15 0x00000224: ftou r1.xy, r0.zwzz +// 16 0x00000238: mov r1.zw, l(0,0,0,0) +// 17 0x00000258: ld_indexable(texture2d)(float,float,float,float) r0.z, r1.xyzw, t0.yzxw +// 18 0x0000027C: else +// 19 0x00000280: mov r0.z, l(1000000.000000) +// 20 0x00000294: endif +// 21 0x00000298: store_structured g0.x, r0.y, l(0), r0.z +// 22 0x000002BC: imad r0.z, vThreadID.x, l(2), l(1) +// 23 0x000002DC: ult r0.w, r0.z, r0.x +// 24 0x000002F8: if_nz r0.w +// 25 0x00000304: utof r0.w, r0.z +// 26 0x00000318: div r1.x, r0.w, cb3[0].x +// 27 0x00000338: round_ni r1.x, r1.x +// 28 0x0000034C: mul r1.y, r0.w, cb3[0].x +// 29 0x0000036C: ge r1.y, r1.y, -r1.y +// 30 0x0000038C: movc r1.y, r1.y, cb3[0].x, -cb3[0].x +// 31 0x000003BC: div r1.z, l(1.000000, 1.000000, 1.000000, 1.000000), r1.y +// 32 0x000003E4: mul r0.w, r0.w, r1.z +// 33 0x00000400: frc r0.w, r0.w +// 34 0x00000414: mul r0.w, r0.w, r1.y +// 35 0x00000430: ftou r2.x, r0.w +// 36 0x00000444: ftou r2.y, r1.x +// 37 0x00000458: mov r2.zw, l(0,0,0,0) +// 38 0x00000478: ld_indexable(texture2d)(float,float,float,float) r0.w, r2.xyzw, t0.yzwx +// 39 0x0000049C: else +// 40 0x000004A0: mov r0.w, l(1000000.000000) +// 41 0x000004B4: endif +// 42 0x000004B8: store_structured g0.x, r0.z, l(0), r0.w +// 43 0x000004DC: sync_g_t +// 44 0x000004E0: ld_structured r1.y, r0.y, l(0), g0.xxxx +// 45 0x00000504: ld_structured r1.x, r0.z, l(0), g0.xxxx +// 46 0x00000528: lt r0.w, r1.x, r1.y +// 47 0x00000544: movc r1.xy, r0.wwww, r1.xyxx, r1.yxyy +// 48 0x00000568: store_structured g0.x, r0.y, l(0), r1.x +// 49 0x0000058C: store_structured g0.x, r0.z, l(0), r1.y +// 50 0x000005B0: sync_g_t +// 51 0x000005B4: mov r0.y, l(4) +// 52 0x000005C8: loop +// 53 0x000005CC: ult r0.z, l(256), r0.y +// 54 0x000005E8: breakc_nz r0.z +// 55 0x000005F4: ushr r0.z, r0.y, l(1) +// 56 0x00000610: udiv r1.x, r2.x, vThreadID.x, r0.z +// 57 0x00000630: imad r0.w, r1.x, r0.y, r2.x +// 58 0x00000654: ld_structured r3.y, r0.w, l(0), g0.xxxx +// 59 0x00000678: imad r1.x, r1.x, r0.y, r0.y +// 60 0x0000069C: iadd r1.x, -r2.x, r1.x +// 61 0x000006BC: iadd r1.x, r1.x, l(-1) +// 62 0x000006D8: ld_structured r3.x, r1.x, l(0), g0.xxxx +// 63 0x000006FC: lt r1.y, r3.x, r3.y +// 64 0x00000718: movc r1.yz, r1.yyyy, r3.xxyx, r3.yyxy +// 65 0x0000073C: store_structured g0.x, r0.w, l(0), r1.y +// 66 0x00000760: store_structured g0.x, r1.x, l(0), r1.z +// 67 0x00000784: sync_g_t +// 68 0x00000788: mov r0.w, r0.z +// 69 0x0000079C: loop +// 70 0x000007A0: ult r1.x, r0.w, l(2) +// 71 0x000007BC: breakc_nz r1.x +// 72 0x000007C8: ushr r1.x, r0.w, l(1) +// 73 0x000007E4: udiv r2.x, r3.x, vThreadID.x, r1.x +// 74 0x00000804: imad r1.y, r2.x, r0.w, r3.x +// 75 0x00000828: ld_structured r2.y, r1.y, l(0), g0.xxxx +// 76 0x0000084C: iadd r1.z, r1.x, r1.y +// 77 0x00000868: ld_structured r2.x, r1.z, l(0), g0.xxxx +// 78 0x0000088C: lt r1.w, r2.x, r2.y +// 79 0x000008A8: movc r2.xy, r1.wwww, r2.xyxx, r2.yxyy +// 80 0x000008CC: store_structured g0.x, r1.y, l(0), r2.x +// 81 0x000008F0: store_structured g0.x, r1.z, l(0), r2.y +// 82 0x00000914: sync_g_t +// 83 0x00000918: mov r0.w, r1.x +// 84 0x0000092C: endloop +// 85 0x00000930: ishl r0.y, r0.y, l(1) +// 86 0x0000094C: endloop +// 87 0x00000950: if_z vThreadID.x +// 88 0x00000958: and r0.y, r0.x, l(1) +// 89 0x00000974: if_nz r0.y +// 90 0x00000980: ushr r0.y, r0.x, l(1) +// 91 0x0000099C: ld_structured r0.y, r0.y, l(0), g0.xxxx +// 92 0x000009C0: else +// 93 0x000009C4: ushr r0.z, r0.x, l(1) +// 94 0x000009E0: ld_structured r0.w, r0.z, l(0), g0.xxxx +// 95 0x00000A04: iadd r0.z, r0.z, l(1) +// 96 0x00000A20: ld_structured r0.z, r0.z, l(0), g0.xxxx +// 97 0x00000A44: add r0.z, r0.z, r0.w +// 98 0x00000A60: mul r0.y, r0.z, l(0.500000) +// 99 0x00000A7C: endif +// 100 0x00000A80: max r0.y, r0.y, l(0.000010) +// 101 0x00000A9C: ld_uav_typed_indexable(buffer)(float,float,float,float) r0.z, l(0, 0, 0, 0), u0.yzxw +// 102 0x00000ACC: div r1.xy, r0.yyyy, cb3[4].zwzz +// 103 0x00000AEC: max r1.xy, r1.xyxx, cb3[2].zwzz +// 104 0x00000B0C: min r1.xy, r1.xyxx, cb3[3].xyxx +// 105 0x00000B2C: max r0.z, r0.z, cb3[2].z +// 106 0x00000B4C: min r0.z, r0.z, cb3[3].x +// 107 0x00000B6C: div r0.w, r1.x, r0.z +// 108 0x00000B88: log r0.w, r0.w +// 109 0x00000B9C: lt r1.x, cb3[1].x, |r0.w| +// 110 0x00000BC0: lt r1.z, l(0.000000), r0.w +// 111 0x00000BDC: lt r1.w, r0.w, l(0.000000) +// 112 0x00000BF8: iadd r1.z, -r1.z, r1.w +// 113 0x00000C18: itof r1.z, r1.z +// 114 0x00000C2C: mul r1.z, r1.z, cb3[1].x +// 115 0x00000C4C: movc r0.w, r1.x, r1.z, r0.w +// 116 0x00000C70: exp r0.w, r0.w +// 117 0x00000C84: mul r0.z, r0.w, r0.z +// 118 0x00000CA0: log r0.w, r0.z +// 119 0x00000CB4: mul r0.w, r0.w, cb3[1].y +// 120 0x00000CD4: exp r0.w, r0.w +// 121 0x00000CE8: log r1.xz, cb3[2].xxyx +// 122 0x00000D00: mul r1.xz, r1.xxzx, cb3[1].yyzy +// 123 0x00000D20: exp r1.xz, r1.xxzx +// 124 0x00000D34: add r1.w, -r0.w, r1.x +// 125 0x00000D54: max r1.w, r1.w, l(0.000010) +// 126 0x00000D70: div r2.xy, r1.xzxx, cb3[4].xyxx +// 127 0x00000D90: div r2.z, r0.w, cb3[3].z +// 128 0x00000DB0: add r2.x, -r2.z, r2.x +// 129 0x00000DD0: div r2.x, r2.x, r1.w +// 130 0x00000DEC: mul r0.w, r0.w, r1.x +// 131 0x00000E08: div r1.x, r0.w, cb3[3].z +// 132 0x00000E28: div r0.w, r0.w, cb3[4].x +// 133 0x00000E48: add r0.w, -r0.w, r1.x +// 134 0x00000E68: div r0.w, r0.w, r1.w +// 135 0x00000E84: ld_uav_typed_indexable(buffer)(float,float,float,float) r1.x, l(0, 0, 0, 0), u1.xyzw +// 136 0x00000EB4: max r1.x, r1.x, cb3[2].w +// 137 0x00000ED4: min r1.x, r1.x, cb3[3].y +// 138 0x00000EF4: div r1.y, r1.y, r1.x +// 139 0x00000F10: log r1.y, r1.y +// 140 0x00000F24: lt r1.w, cb3[1].x, |r1.y| +// 141 0x00000F48: lt r2.z, l(0.000000), r1.y +// 142 0x00000F64: lt r2.w, r1.y, l(0.000000) +// 143 0x00000F80: iadd r2.z, -r2.z, r2.w +// 144 0x00000FA0: itof r2.z, r2.z +// 145 0x00000FB4: mul r2.z, r2.z, cb3[1].x +// 146 0x00000FD4: movc r1.y, r1.w, r2.z, r1.y +// 147 0x00000FF8: exp r1.y, r1.y +// 148 0x0000100C: mul r1.x, r1.y, r1.x +// 149 0x00001028: log r1.y, r1.x +// 150 0x0000103C: mul r1.y, r1.y, cb3[1].z +// 151 0x0000105C: exp r1.y, r1.y +// 152 0x00001070: add r1.w, -r1.y, r1.z +// 153 0x00001090: max r1.w, r1.w, l(0.000010) +// 154 0x000010AC: div r2.z, r1.y, cb3[3].w +// 155 0x000010CC: add r2.y, -r2.z, r2.y +// 156 0x000010EC: div r2.y, r2.y, r1.w +// 157 0x00001108: mul r1.y, r1.y, r1.z +// 158 0x00001124: div r1.z, r1.y, cb3[3].w +// 159 0x00001144: div r1.y, r1.y, cb3[4].y +// 160 0x00001164: add r1.y, -r1.y, r1.z +// 161 0x00001184: div r1.y, r1.y, r1.w +// 162 0x000011A0: and r1.z, r0.z, l(0x7f800000) +// 163 0x000011BC: ine r1.z, r1.z, l(0x7f800000) +// 164 0x000011D8: if_nz r1.z +// 165 0x000011E4: store_uav_typed u0.xyzw, l(0,0,0,0), r0.zzzz +// 166 0x0000120C: endif +// 167 0x00001210: and r0.z, r2.x, l(0x7f800000) +// 168 0x0000122C: ine r0.z, r0.z, l(0x7f800000) +// 169 0x00001248: if_nz r0.z +// 170 0x00001254: store_uav_typed u0.xyzw, l(1,1,1,1), r2.xxxx +// 171 0x0000127C: endif +// 172 0x00001280: and r0.z, r0.w, l(0x7f800000) +// 173 0x0000129C: ine r0.z, r0.z, l(0x7f800000) +// 174 0x000012B8: if_nz r0.z +// 175 0x000012C4: store_uav_typed u0.xyzw, l(2,2,2,2), r0.wwww +// 176 0x000012EC: endif +// 177 0x000012F0: and r0.z, r1.x, l(0x7f800000) +// 178 0x0000130C: ine r0.z, r0.z, l(0x7f800000) +// 179 0x00001328: if_nz r0.z +// 180 0x00001334: store_uav_typed u1.xyzw, l(0,0,0,0), r1.xxxx +// 181 0x0000135C: endif +// 182 0x00001360: and r0.z, r2.y, l(0x7f800000) +// 183 0x0000137C: ine r0.z, r0.z, l(0x7f800000) +// 184 0x00001398: if_nz r0.z +// 185 0x000013A4: store_uav_typed u1.xyzw, l(1,1,1,1), r2.yyyy +// 186 0x000013CC: endif +// 187 0x000013D0: and r0.z, r1.y, l(0x7f800000) +// 188 0x000013EC: ine r0.z, r0.z, l(0x7f800000) +// 189 0x00001408: if_nz r0.z +// 190 0x00001414: store_uav_typed u1.xyzw, l(2,2,2,2), r1.yyyy +// 191 0x0000143C: endif +// 192 0x00001440: ld_structured r0.z, l(0), l(0), g0.xxxx +// 193 0x00001464: div r0.zw, r0.zzzz, cb3[4].zzzw +// 194 0x00001484: store_uav_typed u0.xyzw, l(3,3,3,3), r0.zzzz +// 195 0x000014AC: store_uav_typed u0.xyzw, l(4,4,4,4), r0.yyyy +// 196 0x000014D4: iadd r0.x, r0.x, l(-1) +// 197 0x000014F0: ld_structured r0.x, r0.x, l(0), g0.xxxx +// 198 0x00001514: div r0.xz, r0.xxxx, cb3[4].zzwz +// 199 0x00001534: store_uav_typed u0.xyzw, l(5,5,5,5), r0.xxxx +// 200 0x0000155C: store_uav_typed u1.xyzw, l(3,3,3,3), r0.wwww +// 201 0x00001584: store_uav_typed u1.xyzw, l(4,4,4,4), r0.yyyy +// 202 0x000015AC: store_uav_typed u1.xyzw, l(5,5,5,5), r0.zzzz +// 203 0x000015D4: endif +// 204 0x000015D8: ret +// // Approximately 0 instruction slots used diff --git a/Shaders/Middle-earth Shadow of War/fire00_0x784E89AD.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire00_0x784E89AD.ps_5_0.hlsl new file mode 100644 index 00000000..caafc37c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire00_0x784E89AD.ps_5_0.hlsl @@ -0,0 +1,155 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:30 2026 +Texture2DArray t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[10]; +} + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = v3.xy / v3.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.x = t1.Sample(s2_s, r0.xy).x; + r0.x = v3.w + -r0.x; + r0.x = saturate(abs(r0.x) / cb3[7].w); + r0.x = 1 + -r0.x; + r0.x = log2(r0.x); + r0.x = cb3[8].x * r0.x; + r0.x = exp2(r0.x); + r0.x = 1 + -r0.x; + r0.x = max(0, r0.x); + r1.xyzw = t0.Sample(s1_s, v1.xyz).xyzw; + r0.yz = cb3[2].xy * r1.xy; + r0.y = r0.y + r0.z; + r0.y = cb3[2].z * r1.z + r0.y; + r0.y = cb3[2].w * r1.w + r0.y; + r0.y = v4.w * r0.y; + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[8].y + cb3[1].x; + r0.x = log2(r0.x); + r0.x = cb3[9].x * r0.x; + o0.w = exp2(r0.x); + r0.x = cb3[8].z + v4.x; + r0.x = cmp(r0.x < 0.5); + r1.z = r0.x ? cb3[8].w : 2; //bow aim turns blue + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.xyz = t2.SampleLevel(s0_s, r1.xyz, 0).xyz; + r0.xyz *= FIRE_BOOST; + r0.xyz = cb3[0].yzw * r0.xyz; + r0.w = !cb3[0].x ? cb2[24].w : 1; //TODO: these selects are not decompiled right? + r0.xyz = r0.www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + o0.xyz = !cb3[0].xxx ? r1.xyz : r0.xyz; //TODO: these selects are not decompiled right? + // o0.xyz *= 8; + return; +} + +/* +// +// Generated by Microsoft (R) D3D Shader Disassembler +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xyz 1 NONE float xyz +// TEXCOORD 2 xyzw 2 NONE float +// TEXCOORD 1 xyzw 3 NONE float xy w +// COLOR 0 xyzw 4 NONE float x w +// SV_IsFrontFace 0 x 5 FFACE uint +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// + 0x00000000: ps_5_0 + 0x00000008: dcl_globalFlags refactoringAllowed + 0x0000000C: dcl_constantbuffer CB3[10], immediateIndexed + 0x0000001C: dcl_constantbuffer CB2[53], immediateIndexed + 0x0000002C: dcl_sampler s0, mode_default + 0x00000038: dcl_sampler s1, mode_default + 0x00000044: dcl_sampler s2, mode_default + 0x00000050: dcl_resource_texture2darray (float,float,float,float) t0 + 0x00000060: dcl_resource_texture2d (float,float,float,float) t1 + 0x00000070: dcl_resource_texture2darray (float,float,float,float) t2 + 0x00000080: dcl_input_ps linear v1.xyz + 0x0000008C: dcl_input_ps linear v3.xyw + 0x00000098: dcl_input_ps linear v4.xw + 0x000000A4: dcl_output o0.xyzw + 0x000000B0: dcl_temps 2 + 0 0x000000B8: div r0.xy, v3.xyxx, v3.wwww + 1 0x000000D4: min r0.xy, r0.xyxx, cb2[22].zwzz + 2 0x000000F4: sample_indexable(texture2d)(float,float,float,float) r0.x, r0.xyxx, t1.xyzw, s2 + 3 0x00000120: add r0.x, -r0.x, v3.w + 4 0x00000140: div_sat r0.x, |r0.x|, cb3[7].w + 5 0x00000164: add r0.x, -r0.x, l(1.000000) + 6 0x00000184: log r0.x, r0.x + 7 0x00000198: mul r0.x, r0.x, cb3[8].x + 8 0x000001B8: exp r0.x, r0.x + 9 0x000001CC: add r0.x, -r0.x, l(1.000000) + 10 0x000001EC: max r0.x, r0.x, l(0.000000) + 11 0x00000208: sample_indexable(texture2darray)(float,float,float,float) r1.xyzw, v1.xyzx, t0.xyzw, s1 + 12 0x00000234: mul r0.yz, r1.xxyx, cb3[2].xxyx + 13 0x00000254: add r0.y, r0.z, r0.y + 14 0x00000270: mad r0.y, cb3[2].z, r1.z, r0.y + 15 0x00000298: mad r0.y, cb3[2].w, r1.w, r0.y + 16 0x000002C0: mul r0.y, r0.y, v4.w + 17 0x000002DC: mul r0.x, r0.x, r0.y + 18 0x000002F8: mad r1.x, r0.x, cb3[8].y, cb3[1].x + 19 0x00000324: log r0.x, r0.x + 20 0x00000338: mul r0.x, r0.x, cb3[9].x + 21 0x00000358: exp o0.w, r0.x + 22 0x0000036C: add r0.x, v4.x, cb3[8].z + 23 0x0000038C: lt r0.x, r0.x, l(0.500000) + 24 0x000003A8: movc r1.z, r0.x, cb3[8].w, l(2.000000) + 25 0x000003D0: mov r1.y, l(0) + 26 0x000003E4: sample_l_indexable(texture2darray)(float,float,float,float) r0.xyz, r1.xyzx, t2.xyzw, s0, l(0.000000) + 27 0x00000418: mul r0.xyz, r0.xyzx, cb3[0].yzwy + 28 0x00000438: movc r0.w, cb3[0].x, cb2[24].w, l(1.000000) + 29 0x00000464: mul r0.xyz, r0.xyzx, r0.wwww + 30 0x00000480: mul r1.xyz, r0.xyzx, cb2[26].wwww + 31 0x000004A0: movc o0.xyz, cb3[0].xxxx, r1.xyzx, r0.xyzx + 32 0x000004C8: ret +// Approximately 0 instruction slots used + +*/ \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire01_0xFEB3373E.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire01_0xFEB3373E.ps_5_0.hlsl new file mode 100644 index 00000000..3090d7e8 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire01_0xFEB3373E.ps_5_0.hlsl @@ -0,0 +1,84 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:52 2026 +Texture2DArray t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[6]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + float4 v3 : COLOR0, + float4 v4 : TEXCOORD2, + float4 v5 : TEXCOORD3, + float4 v6 : TEXCOORD4, + float4 v7 : TEXCOORD5, + float3 v8 : TEXCOORD6, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = 0.00333333341 * cb1[1].x; + r0.y = cmp(r0.x >= -r0.x); + r0.x = frac(abs(r0.x)); + r0.x = r0.y ? r0.x : -r0.x; + r0.x = cb3[4].y * r0.x; + r0.x = 300 * r0.x; + r0.x = r0.x / cb3[4].z; + r0.y = cmp(r0.x >= -r0.x); + r0.x = frac(abs(r0.x)); + r0.x = r0.y ? r0.x : -r0.x; + r0.x = cb3[4].z * r0.x; + r0.z = floor(r0.x); + r0.xy = v1.zw; + r0.xyzw = t0.Sample(s0_s, r0.xyz).xyzw; + r0.xy = cb3[2].xy * r0.xy; + r0.x = r0.x + r0.y; + r0.x = cb3[2].z * r0.z + r0.x; + r0.x = cb3[2].w * r0.w + r0.x; + r0.x = v3.w * r0.x; + r1.x = r0.x * cb3[4].w + cb3[1].x; + r0.x = log2(r0.x); + r0.x = cb3[5].z * r0.x; + o0.w = exp2(r0.x); + r0.x = cb3[5].x + v3.x; + r0.x = cmp(r0.x < 0.5); + r1.z = r0.x ? cb3[5].y : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.xyz = t1.SampleLevel(s1_s, r1.xyz, 0).xyz; + r0.xyz *= FIRE_BOOST; + r0.xyz = cb3[0].yzw * r0.xyz; + r0.w = !cb3[0].x ? cb2[24].w : 1; + r0.xyz = r0.www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + o0.xyz = !cb3[0].xxx ? r1.xyz : r0.xyz; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire02_explosionflame0_0xEC01FC57.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire02_explosionflame0_0xEC01FC57.ps_5_0.hlsl new file mode 100644 index 00000000..f8a8b8af --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire02_explosionflame0_0xEC01FC57.ps_5_0.hlsl @@ -0,0 +1,73 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:48 2026 +Texture2DArray t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[4]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.z = cb3[1].w * v4.x; + r0.xy = v1.xy; + r0.xyz = t0.Sample(s0_s, r0.xyz).xyz; + r0.xy = cb3[1].xy * r0.xy; + r0.x = r0.x + r0.y; + r0.x = cb3[1].z * r0.z + r0.x; + r0.y = -cb3[2].x + r0.x; + r0.x = v4.w * r0.x; + r0.z = cb3[2].y + -cb3[2].x; + r0.y = saturate(r0.y / r0.z); + r0.x = r0.x * r0.y; + r1.x = r0.x * cb3[2].z + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[3].y * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[2].w < 0.5); + r1.z = r0.y ? cb3[3].x : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t1.SampleLevel(s1_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[3].z ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[3].www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[3].zzz ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire04_mega_0xFC3E803B.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire04_mega_0xFC3E803B.ps_5_0.hlsl new file mode 100644 index 00000000..36200942 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire04_mega_0xFC3E803B.ps_5_0.hlsl @@ -0,0 +1,109 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:51 2026 +Texture2D t3 : register(t3); + +Texture2DArray t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[15]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + float4 v3 : COLOR0, + float4 v4 : TEXCOORD2, + nointerpolation int v5 : TEXCOORD3, + uint v6 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2,r3; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = !cb3[0].x ? cb2[24].w : 1; + r0.y = cmp((int)v5.x >= 6); + r0.zw = cb3[13].xy * cb1[1].xx; + r0.zw = v1.xy * cb3[13].zw + r0.zw; + r0.zw = t1.Sample(s2_s, r0.zw).yw; + r0.zw = r0.zw * float2(2,2) + float2(-1,-1); + r1.x = r0.y ? cb3[14].y : cb3[14].x; + r1.xy = saturate(r0.zw * r1.xx + v1.xy); + r1.z = v1.z; + r1.xyzw = t0.Sample(s1_s, r1.xyz).xyzw; + if (r0.y == 0) { + r2.xyzw = cmp((int4)v5.xxxx == int4(1,3,5,7)); + r0.y = (int)r2.y | (int)r2.x; + r0.y = (int)r2.z | (int)r0.y; + r0.y = (int)r2.w | (int)r0.y; + r0.z = cmp((int)v5.x == 9); + r0.y = (int)r0.z | (int)r0.y; + r0.zw = cmp((int2)v5.xx >= int2(0,3)); + r2.xy = cmp((int2)v5.xx < int2(3,5)); + r0.zw = r0.zw ? r2.xy : 0; + r0.w = r0.w ? r1.y : r1.x; + r0.z = r0.z ? r1.z : r0.w; + r2.w = v3.w * r0.z; + r0.zw = r2.ww * float2(0.5,0.699999988) + float2(0.550000012,0.449999988); + r1.x = r0.y ? r0.w : r0.z; + r1.z = r0.y ? 2.000000 : 0; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r2.xyz = t2.SampleLevel(s0_s, r1.xyz, 0).xyz; + r2.xyz *= FIRE_BOOST; + } else { + r0.y = saturate(r1.w); + r3.w = r0.y * r0.y; + r3.xyz = r1.www; + r2.xyzw = v3.xyzw * r3.xyzw; + } + r0.xyz = r2.xyz * r0.xxx; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[0].xxx ? r1.xyz : r0.xyz; + o0.xyz = r0.xyz * v4.www + v4.xyz; + r0.xy = v2.xy / v2.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.x = t3.Sample(s3_s, r0.xy).x; + r0.x = v2.w + -r0.x; + r0.x = saturate(abs(r0.x) / cb3[14].z); + r0.x = 1 + -r0.x; + r0.x = log2(r0.x); + r0.x = cb3[14].w * r0.x; + r0.x = exp2(r0.x); + r0.x = 1 + -r0.x; + o0.w = saturate(r2.w * r0.x); + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire05_addsoftdistlutsmoothstep_0x922EBCCE.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire05_addsoftdistlutsmoothstep_0x922EBCCE.ps_5_0.hlsl new file mode 100644 index 00000000..15c64f44 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire05_addsoftdistlutsmoothstep_0x922EBCCE.ps_5_0.hlsl @@ -0,0 +1,108 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:34 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2DArray t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[8]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = cb3[4].w * v1.x; + r0.y = cb3[5].x * v1.y; + r0.xy = cb1[1].xx * cb3[5].yz + r0.xy; + r0.xy = t0.Sample(s1_s, r0.xy).yw; + r0.xy = r0.xy * float2(2,2) + float2(-1,-1); + r0.z = -r0.y; + r0.xy = r0.xz * cb3[5].ww + v1.xy; + r0.z = v1.z; + r0.x = t1.Sample(s2_s, r0.xyz).x; + r0.y = 1 + cb3[6].x; + r0.y = v4.w * r0.y + r0.x; + r0.y = -1 + r0.y; + r0.z = 1 / cb3[6].x; + r0.y = saturate(r0.y * r0.z); + r0.z = r0.y * -2 + 3; + r0.y = r0.y * r0.y; + r0.y = r0.z * r0.y; + r0.z = -0.00499999989 + r0.x; + r0.x = v4.x * r0.x; + r0.z = saturate(ceil(r0.z)); + r0.y = r0.z * r0.y; + r0.x = r0.x * r0.y; + r0.x = v4.w * r0.x; + r0.yz = v3.xy / v3.ww; + r0.yz = min(cb2[22].zw, r0.yz); + r0.y = t2.Sample(s3_s, r0.yz).x; + r0.y = v3.w + -r0.y; + r0.y = saturate(abs(r0.y) / cb3[6].y); + r0.y = 1 + -r0.y; + r0.y = log2(r0.y); + r0.y = cb3[6].z * r0.y; + r0.y = exp2(r0.y); + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r0.x = r0.x * r0.y; + r1.x = r0.x * cb3[6].w + cb3[0].x; + r0.x = log2(r0.x); + r0.x = cb3[7].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[7].x < 0.5); + r1.z = r0.y ? cb3[7].y : 15; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK);; + r0.yzw = t3.SampleLevel(s0_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[1].x ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[1].xxx ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire06_lutrandom_0x708498E1.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire06_lutrandom_0x708498E1.ps_5_0.hlsl new file mode 100644 index 00000000..58171825 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire06_lutrandom_0x708498E1.ps_5_0.hlsl @@ -0,0 +1,73 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:29 2026 +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[9]; +} + + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = v3.xy / v3.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.x = t2.Sample(s2_s, r0.xy).x; + r0.x = v3.w + -r0.x; + r0.x = saturate(abs(r0.x) / cb3[7].w); + r0.x = 1 + -r0.x; + r0.x = log2(r0.x); + r0.x = cb3[8].x * r0.x; + r0.x = exp2(r0.x); + r0.x = 1 + -r0.x; + r0.yz = t0.Sample(s1_s, v1.xyz).xw; + r0.x = saturate(r0.z * r0.x); + r0.y = v4.x * r0.y; + r1.x = r0.y * cb3[7].z + cb3[0].y; + o0.w = v4.w * r0.x; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK * 1.32); + r0.xyz = t1.SampleLevel(s0_s, r1.xy, 0).xyz; + r0.xyz *= FIRE_BOOST; + r0.w = !cb3[0].x ? cb2[24].w : 1; + r0.xyz = r0.www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[0].xxx ? r1.xyz : r0.xyz; + o0.xyz = r0.xyz * v2.www + v2.xyz; + + + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire07_lut4checkmasksmoothstep_0x23FDC1DE.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire07_lut4checkmasksmoothstep_0x23FDC1DE.ps_5_0.hlsl new file mode 100644 index 00000000..48c54f0c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire07_lut4checkmasksmoothstep_0x23FDC1DE.ps_5_0.hlsl @@ -0,0 +1,98 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:17 2026 +Texture2DArray t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[9]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xyzw = t0.Sample(s1_s, v1.xyz).xyzw; + r0.xy = cb3[1].xy * r0.xy; + r0.x = r0.x + r0.y; + r0.x = cb3[1].z * r0.z + r0.x; + r0.x = cb3[1].w * r0.w + r0.x; + r0.y = 1 + cb3[6].w; + r0.y = v4.w * r0.y + r0.x; + r0.y = -1 + r0.y; + r0.z = 1 / cb3[6].w; + r0.y = saturate(r0.y * r0.z); + r0.z = r0.y * -2 + 3; + r0.y = r0.y * r0.y; + r0.y = r0.z * r0.y; + r0.z = -0.00499999989 + r0.x; + r0.z = saturate(ceil(r0.z)); + r0.y = r0.z * r0.y; + r0.z = saturate(cb3[7].x); + r0.y = r0.y * r0.z; + r0.x = r0.x * r0.y; + r0.x = v4.w * r0.x; + r0.zw = v3.xy / v3.ww; + r0.zw = min(cb2[22].zw, r0.zw); + r0.z = t1.Sample(s2_s, r0.zw).x; + r0.z = v3.w + -r0.z; + r0.z = saturate(abs(r0.z) / cb3[7].y); + r0.z = 1 + -r0.z; + r0.z = log2(r0.z); + r0.z = cb3[7].z * r0.z; + r0.z = exp2(r0.z); + r0.z = 1 + -r0.z; + r0.y = saturate(r0.y * r0.z); + r0.x = r0.x * r0.y; + r1.x = r0.x * cb3[7].w + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[8].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cb3[8].x + v4.x; + r0.y = cmp(r0.y < 0.5); + r1.z = r0.y ? cb3[8].y : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t2.SampleLevel(s0_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.yzw = r0.yzw * r0.xxx; + o0.w = r0.x; + r0.x = !cb3[2].w ? cb2[24].w : 1; + r0.xyz = r0.yzw * r0.xxx; + r0.xyz = cb3[8].www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + o0.xyz = !cb3[2].www ? r1.xyz : r0.xyz; + + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire08_trailswordflamefallofflut_0x9E6060A0.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire08_trailswordflamefallofflut_0x9E6060A0.ps_5_0.hlsl new file mode 100644 index 00000000..5741a58c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire08_trailswordflamefallofflut_0x9E6060A0.ps_5_0.hlsl @@ -0,0 +1,125 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 22:37:59 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[7]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + float4 v3 : COLOR0, + float4 v4 : TEXCOORD2, + float4 v5 : TEXCOORD3, + float4 v6 : TEXCOORD4, + float4 v7 : TEXCOORD5, + float3 v8 : TEXCOORD6, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = v5.z; + r0.y = v6.z; + r0.z = v7.z; + r0.w = dot(r0.xyz, r0.xyz); + r0.w = rsqrt(r0.w); + r0.xyz = r0.xyz * r0.www; + r0.w = dot(v8.xyz, v8.xyz); + r0.w = rsqrt(r0.w); + r1.xyz = v8.xyz * r0.www; + r0.x = dot(r0.xyz, r1.xyz); + r0.x = cb3[4].y * abs(r0.x); + r0.x = log2(r0.x); + r0.x = cb3[4].z * r0.x; + r0.x = exp2(r0.x); + r1.xyz = cb3[3].xyw * cb1[1].xxx; + r0.yz = v1.xy * cb3[2].zw + r1.xy; + r0.yz = t0.Sample(s0_s, r0.yz).yw; + r2.xy = r0.yz * float2(2,2) + float2(-1,-1); + r2.z = -r2.y; + r0.yz = r2.xz * cb3[3].zz + v1.xy; + r1.w = cb3[4].x * cb1[1].x; + r0.yz = r1.zw + r0.yz; + r0.yz = t1.Sample(s1_s, r0.yz).xw; + r0.w = v3.w * 1.20000005 + r0.z; + r0.zw = float2(-0.00499999989,-1) + r0.zw; + r0.w = saturate(4.99999905 * r0.w); + r1.x = r0.w * -2 + 3; + r0.w = r0.w * r0.w; + r0.w = r1.x * r0.w; + r0.y = v3.w * r0.y; + r0.z = saturate(ceil(r0.z)); + r0.z = r0.z * r0.w; + r0.x = r0.z * r0.x; + r0.zw = v2.xy / v2.ww; + r0.zw = min(cb2[22].zw, r0.zw); + r0.z = t2.Sample(s2_s, r0.zw).x; + r0.z = v2.w + -r0.z; + r0.z = saturate(abs(r0.z) / cb3[4].w); + r0.z = 1 + -r0.z; + r0.z = log2(r0.z); + r0.z = cb3[5].x * r0.z; + r0.z = exp2(r0.z); + r0.z = 1 + -r0.z; + r0.x = saturate(r0.x * r0.z); + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[5].y + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[6].x * r0.x; + r0.x = exp2(r0.x); + r0.y = cb3[5].z + v3.x; + r0.y = cmp(r0.y < 0.5); + r1.z = r0.y ? cb3[5].w : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK);; + r0.yzw = t3.SampleLevel(s3_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[1].z ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[6].yyy * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[1].zzz ? r1.xyz : r0.xyz; + o0.xyz = v4.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire09_3dnoisedepthreveal_0xFAF088FD.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire09_3dnoisedepthreveal_0xFAF088FD.ps_5_0.hlsl new file mode 100644 index 00000000..3ddea579 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire09_3dnoisedepthreveal_0xFAF088FD.ps_5_0.hlsl @@ -0,0 +1,125 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:51 2026 +Texture2DArray t5 : register(t5); + +Texture2D t4 : register(t4); + +Texture3D t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[12]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xyz = cb3[7].xyz * v4.xyz; + r0.xyzw = t3.Sample(s2_s, r0.xyz).xyzw; + r0.x = saturate(dot(cb3[6].xyzw, r0.xyzw)); + r0.y = 1 + -cb3[7].w; + r0.zw = float2(1,1) + cb3[8].xz; + r0.y = r0.y * r0.z + r0.x; + r0.x = -0.00499999989 + r0.x; + r0.x = ceil(r0.x); + r0.y = -1 + r0.y; + r1.xy = float2(1,1) / cb3[8].xz; + r0.y = saturate(r1.x * r0.y); + r0.z = r0.y * -2 + 3; + r0.y = r0.y * r0.y; + r0.y = r0.z * r0.y; + r0.x = r0.x * r0.y; + r0.x = saturate(cb3[8].y * r0.x); + r0.yz = cb3[4].xy * cb1[1].xx; + r0.yz = v1.xy * cb3[3].zw + r0.yz; + r0.yz = t0.Sample(s0_s, r0.yz).yw; + r2.xy = r0.yz * float2(2,2) + float2(-1,-1); + r2.z = -r2.y; + r0.yz = r2.xz * cb3[4].zz + v1.xy; + r2.xyzw = t1.Sample(s0_s, r0.yz).xyzw; + r1.x = cb3[5].w * r2.w; + r0.x = r1.x * r0.x; + r1.x = t4.SampleLevel(s3_s, v4.xy, 0).x; + r1.x = saturate(cb3[9].x * r1.x); + r0.w = r0.w * cb3[8].w + r1.x; + r0.w = -1 + r0.w; + r0.w = saturate(r0.w * r1.y); + r1.x = r0.w * -2 + 3; + r0.w = r0.w * r0.w; + r0.w = r1.x * r0.w; + r0.w = min(1, r0.w); + r0.w = saturate(cb3[10].x * r0.w); + r0.x = r0.x * r0.w; + r1.x = cb3[4].w * r0.y; + r1.y = cb3[5].x * r0.z; + r0.yz = cb1[1].xx * cb3[5].yz + r1.xy; + r1.xyzw = t2.Sample(s1_s, r0.yz).xyzw; + r0.x = r1.w * r0.x; + r0.yzw = r2.xyz * r1.xyz; + r0.yz = cb3[0].yz * r0.yz; + r0.y = r0.y + r0.z; + r0.y = cb3[0].w * r0.w + r0.y; + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[10].y + cb3[0].x; + r0.x = log2(r0.x); + r0.x = cb3[11].x * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[10].z < 0.5); + r1.z = r0.y ? cb3[10].w : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK * 1.3); + r0.yzw = t5.SampleLevel(s3_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[3].y ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[11].yyy * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[3].yyy ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire10_adddistortsmoothsteplut_0xDD3A25B7.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire10_adddistortsmoothsteplut_0xDD3A25B7.ps_5_0.hlsl new file mode 100644 index 00000000..ef571931 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire10_adddistortsmoothsteplut_0xDD3A25B7.ps_5_0.hlsl @@ -0,0 +1,116 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:46 2026 +Texture2DArray t4 : register(t4); + +Texture2D t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[7]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = cb3[1].w * v1.x; + r0.y = cb3[2].x * v1.y; + r0.xy = cb3[2].yz + r0.xy; + r1.x = cb3[2].w * cb1[1].x; + r1.y = cb3[3].x * cb1[1].x; + r0.xy = r1.xy + r0.xy; + r0.xy = t0.Sample(s0_s, r0.xy).yw; + r0.xy = r0.xy * float2(2,2) + float2(-1,-1); + r0.z = -r0.y; + r0.xy = r0.xz * cb3[3].yy + v1.xy; + r0.zw = t2.Sample(s1_s, r0.xy).xw; + r1.xyz = t1.Sample(s1_s, r0.xy).xyz; + r0.x = -1 + r0.w; + r2.x = max(0.00999999978, r0.z); + r2.y = max(0.00999999978, cb3[3].z); + r0.yz = float2(1,1) / r2.xy; + r0.x = r0.y * r0.x; + r0.y = -1 + r0.z; + r0.z = 1 + -v4.w; + r0.w = cb3[4].x + -cb3[3].w; + r0.z = r0.z * r0.w + cb3[3].w; + r0.z = r0.z / r2.y; + r0.x = saturate(r0.x * r0.y + r0.z); + r0.yz = v3.xy / v3.ww; + r0.yz = min(cb2[22].zw, r0.yz); + r0.y = t3.Sample(s2_s, r0.yz).x; + r0.y = v3.w + -r0.y; + r0.y = saturate(abs(r0.y) / cb3[4].y); + r0.y = 1 + -r0.y; + r0.y = log2(r0.y); + r0.y = cb3[4].z * r0.y; + r0.y = exp2(r0.y); + r0.y = 1 + -r0.y; + r0.x = r0.x * r0.y; + r0.x = max(0, r0.x); + r0.yz = cb3[1].xy * r1.xy; + r0.y = r0.y + r0.z; + r0.y = cb3[1].z * r1.z + r0.y; + r0.y = v4.w * r0.y; + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[4].w + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[5].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[5].x < 0.5); + r1.z = r0.y ? cb3[5].y : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK);; + r0.yzw = t4.SampleLevel(s3_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[5].w ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[6].xxx * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[5].www ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire11_adddistortpantwo_0xBEF04EDB.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire11_adddistortpantwo_0xBEF04EDB.ps_5_0.hlsl new file mode 100644 index 00000000..2d2d5bd8 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire11_adddistortpantwo_0xBEF04EDB.ps_5_0.hlsl @@ -0,0 +1,172 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:41 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[6]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = cb3[3].xy * cb1[1].xx; + r0.xy = v1.xy * cb3[2].zw + r0.xy; + r0.xy = t0.Sample(s0_s, r0.xy).yw; + + r0.xy = r0.xy * float2(2,2) + float2(-1,-1); + r0.z = -r0.y; + r0.xy = r0.xz * cb3[3].zz + v1.xy; + r1.x = cb3[3].w * r0.x; + r1.y = cb3[4].x * r0.y; + r0.xyzw = t1.Sample(s1_s, r0.xy).xyzw; //controls color + + r1.xy = cb1[1].xx * cb3[4].yz + r1.xy; //cb1[1].xxxx, cb3[4].yzyy, r1.xyxx + r1.xyzw = t2.Sample(s1_s, r1.xy).xyzw; + + r0.xyzw = r1.xyzw * r0.xyzw; + r0.xy = cb3[1].xy * r0.xy; + r0.x = r0.x + r0.y; + r0.x = cb3[1].z * r0.z + r0.x; + r0.x = v4.w * r0.x; + r0.x = r0.x * r0.w; + r1.x = r0.x * cb3[4].w + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[5].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[5].x < 0.5); + r1.z = r0.y ? cb3[5].y : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK, 0.90); + r0.yzw = t3.SampleLevel(s2_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST * 0.67; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[2].y ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[5].www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[2].yyy ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} + +/* +// +// Generated by Microsoft (R) D3D Shader Disassembler +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// TEXCOORD 2 xyzw 2 NONE float w +// TEXCOORD 1 xyzw 3 NONE float +// COLOR 0 xyzw 4 NONE float w +// SV_IsFrontFace 0 x 5 FFACE uint +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// + 0x00000000: ps_5_0 + 0x00000008: dcl_globalFlags refactoringAllowed + 0x0000000C: dcl_constantbuffer CB1[2], immediateIndexed + 0x0000001C: dcl_constantbuffer CB3[6], immediateIndexed + 0x0000002C: dcl_constantbuffer CB2[53], immediateIndexed + 0x0000003C: dcl_sampler s0, mode_default + 0x00000048: dcl_sampler s1, mode_default + 0x00000054: dcl_sampler s2, mode_default + 0x00000060: dcl_resource_texture2d (float,float,float,float) t0 + 0x00000070: dcl_resource_texture2d (float,float,float,float) t1 + 0x00000080: dcl_resource_texture2d (float,float,float,float) t2 + 0x00000090: dcl_resource_texture2darray (float,float,float,float) t3 + 0x000000A0: dcl_input_ps linear v1.xy + 0x000000AC: dcl_input_ps linear v2.w + 0x000000B8: dcl_input_ps linear v4.w + 0x000000C4: dcl_output o0.xyzw + 0x000000D0: dcl_temps 2 + 0 0x000000D8: mul r0.xy, cb1[1].xxxx, cb3[3].xyxx + 1 0x000000FC: mad r0.xy, v1.xyxx, cb3[2].zwzz, r0.xyxx + 2 0x00000124: sample_indexable(texture2d)(float,float,float,float) r0.xy, r0.xyxx, t0.ywxz, s0 + 3 0x00000150: mad r0.xy, r0.xyxx, l(2.000000, 2.000000, 0.000000, 0.000000), l(-1.000000, -1.000000, 0.000000, 0.000000) + 4 0x0000018C: mov r0.z, -r0.y + 5 0x000001A4: mad r0.xy, r0.xzxx, cb3[3].zzzz, v1.xyxx + 6 0x000001CC: mul r1.x, r0.x, cb3[3].w + 7 0x000001EC: mul r1.y, r0.y, cb3[4].x + 8 0x0000020C: sample_indexable(texture2d)(float,float,float,float) r0.xyzw, r0.xyxx, t1.xyzw, s1 + 9 0x00000238: mad r1.xy, cb1[1].xxxx, cb3[4].yzyy, r1.xyxx + 10 0x00000264: sample_indexable(texture2d)(float,float,float,float) r1.xyzw, r1.xyxx, t2.xyzw, s1 + 11 0x00000290: mul r0.xyzw, r0.xyzw, r1.xyzw + 12 0x000002AC: mul r0.xy, r0.xyxx, cb3[1].xyxx + 13 0x000002CC: add r0.x, r0.y, r0.x + 14 0x000002E8: mad r0.x, cb3[1].z, r0.z, r0.x + 15 0x00000310: mul r0.x, r0.x, v4.w + 16 0x0000032C: mul r0.x, r0.w, r0.x + 17 0x00000348: mad r1.x, r0.x, cb3[4].w, cb3[0].w + 18 0x00000374: log r0.x, r0.x + 19 0x00000388: mul r0.x, r0.x, cb3[5].z + 20 0x000003A8: exp r0.x, r0.x + 21 0x000003BC: lt r0.y, cb3[5].x, l(0.500000) + 22 0x000003DC: movc r1.z, r0.y, cb3[5].y, l(2.000000) + 23 0x00000404: mov r1.y, l(0) + 24 0x00000418: sample_l_indexable(texture2darray)(float,float,float,float) r0.yzw, r1.xyzx, t3.wxyz, s2, l(0.000000) + 25 0x0000044C: mul r0.yzw, r0.yyzw, cb3[0].xxyz + 26 0x0000046C: mul r0.xyz, r0.xxxx, r0.yzwy + 27 0x00000488: movc r0.w, cb3[2].y, cb2[24].w, l(1.000000) + 28 0x000004B4: mul r0.xyz, r0.wwww, r0.xyzx + 29 0x000004D0: mul r0.xyz, r0.xyzx, cb3[5].wwww + 30 0x000004F0: mul r1.xyz, r0.xyzx, cb2[26].wwww + 31 0x00000510: movc r0.xyz, cb3[2].yyyy, r1.xyzx, r0.xyzx + 32 0x00000538: mul o0.xyz, r0.xyzx, v2.wwww + 33 0x00000554: mov o0.w, l(0) + 34 0x00000568: ret +// Approximately 0 instruction slots used + +*/ \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl new file mode 100644 index 00000000..71aba26d --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl @@ -0,0 +1,106 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:34 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2DArray t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[8]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = cb3[4].w * v1.x; + r0.y = cb3[5].x * v1.y; + r0.xy = cb1[1].xx * cb3[5].yz + r0.xy; + r0.xy = t0.Sample(s1_s, r0.xy).yw; + r0.xy = r0.xy * float2(2,2) + float2(-1,-1); + r0.z = -r0.y; + r0.xy = r0.xz * cb3[5].ww + v1.xy; + r0.z = v1.z; + r0.x = t1.Sample(s2_s, r0.xyz).x; + r0.y = 1 + cb3[6].x; + r0.y = v4.w * r0.y + r0.x; + r0.y = -1 + r0.y; + r0.z = 1 / cb3[6].x; + r0.y = saturate(r0.y * r0.z); + r0.z = r0.y * -2 + 3; + r0.y = r0.y * r0.y; + r0.y = r0.z * r0.y; + r0.z = -0.00499999989 + r0.x; + r0.x = v4.x * r0.x; + r0.z = saturate(ceil(r0.z)); + r0.y = r0.z * r0.y; + r0.x = r0.x * r0.y; + r0.x = v4.w * r0.x; + r0.yz = v3.xy / v3.ww; + r0.yz = min(cb2[22].zw, r0.yz); + r0.y = t2.Sample(s3_s, r0.yz).x; + r0.y = v3.w + -r0.y; + r0.y = saturate(abs(r0.y) / cb3[6].y); + r0.y = 1 + -r0.y; + r0.y = log2(r0.y); + r0.y = cb3[6].z * r0.y; + r0.y = exp2(r0.y); + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r0.x = r0.x * r0.y; + r1.x = r0.x * cb3[6].w + cb3[0].x; + r0.x = log2(r0.x); + r0.x = cb3[7].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[7].x < 0.5); + r1.z = r0.y ? cb3[7].y : 15; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t3.SampleLevel(s0_s, r1.xyz * 0.86, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[1].x ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[1].xxx ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire13_transsoftdistortlut_0x4A2FFA30.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire13_transsoftdistortlut_0x4A2FFA30.ps_5_0.hlsl new file mode 100644 index 00000000..4bd170d1 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire13_transsoftdistortlut_0x4A2FFA30.ps_5_0.hlsl @@ -0,0 +1,100 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:23 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[6]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = v3.xy / v3.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.x = t2.Sample(s2_s, r0.xy).x; + r0.x = v3.w + -r0.x; + r0.x = saturate(abs(r0.x) / cb3[4].y); + r0.x = 1 + -r0.x; + r0.x = log2(r0.x); + r0.x = cb3[4].z * r0.x; + r0.x = exp2(r0.x); + r0.x = 1 + -r0.x; + r0.yz = v1.xy * cb3[2].zw + cb3[3].xy; + r0.yz = cb1[1].xx * cb3[3].zw + r0.yz; + r0.yz = t0.Sample(s0_s, r0.yz).yw; + r1.xy = r0.yz * float2(2,2) + float2(-1,-1); + r1.z = -r1.y; + r0.yz = r1.xz * cb3[4].xx + v1.xy; + r1.xyzw = t1.Sample(s1_s, r0.yz).xyzw; + r0.x = saturate(r1.w * r0.x); + r0.yz = cb3[1].xy * r1.xy; + r0.y = r0.y + r0.z; + r0.y = cb3[1].z * r1.z + r0.y; + r0.y = v4.w * r0.y; + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[4].w + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[5].z * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[5].x < 0.5); + r1.z = r0.y ? cb3[5].y : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t3.SampleLevel(s3_s, r1.xyz, 0).xyz; + r0.xyz *= FIRE_BOOST * 0.6; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.yzw = r0.yzw * r0.xxx; + o0.w = r0.x; + r0.x = !cb3[2].y ? cb2[24].w : 1; + r0.xyz = r0.yzw * r0.xxx; + r0.xyz = cb3[5].www * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[2].yyy ? r1.xyz : r0.xyz; + o0.xyz = r0.xyz * v2.www + v2.xyz; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire14_explosionflame1_0x9DE77962.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire14_explosionflame1_0x9DE77962.ps_5_0.hlsl new file mode 100644 index 00000000..45fd24bf --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire14_explosionflame1_0x9DE77962.ps_5_0.hlsl @@ -0,0 +1,65 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:36 2026 +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[3]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.z = cb3[0].x * v4.x; + r0.xy = v1.xy; + r0.xyz = t0.Sample(s0_s, r0.xyz).xyz; + r0.x = dot(r0.xyz, cb3[0].yzw); + r0.z = -cb3[1].y + r0.x; + r0.w = cb3[1].z + -cb3[1].y; + r0.z = saturate(r0.z / r0.w); + r0.z = v4.w * r0.z; + r0.y = cb3[1].x; + r0.xyw = t1.Sample(s1_s, r0.xy).xyz; + // r0.xyw = FireTonemap(r0.xyw, FIRE_PEAK); + // r0.xyz *= FIRE_BOOST; + + r0.xyz = r0.xyw * r0.zzz; + r0.w = !cb3[1].w ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[2].xxx * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[1].www ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire15_addsoftdistortlut_0xC033CA59.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire15_addsoftdistortlut_0xC033CA59.ps_5_0.hlsl new file mode 100644 index 00000000..2cf53fc3 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire15_addsoftdistortlut_0xC033CA59.ps_5_0.hlsl @@ -0,0 +1,103 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:41 2026 +Texture2DArray t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[6]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD1, + float4 v4 : COLOR0, + uint v5 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = cb3[1].w * v1.x; + r0.y = cb3[2].x * v1.y; + r0.xy = cb3[2].yz + r0.xy; + r1.x = cb3[2].w * cb1[1].x; + r1.y = cb3[3].x * cb1[1].x; + r0.xy = r1.xy + r0.xy; + r0.xy = t0.Sample(s0_s, r0.xy).yw; + r0.xy = r0.xy * float2(2,2) + float2(-1,-1); + r0.z = -r0.y; + r0.xy = r0.xz * cb3[3].yy + v1.xy; + r0.xyzw = t1.Sample(s1_s, r0.xy).xyzw; + r0.xy = cb3[1].xy * r0.xy; + r0.x = r0.x + r0.y; + r0.x = cb3[1].z * r0.z + r0.x; + r0.x = v4.w * r0.x; + r0.yz = v3.xy / v3.ww; + r0.yz = min(cb2[22].zw, r0.yz); + r0.y = t2.Sample(s2_s, r0.yz).x; + r0.y = v3.w + -r0.y; + r0.y = saturate(abs(r0.y) / cb3[3].z); + r0.y = 1 + -r0.y; + r0.y = log2(r0.y); + r0.y = cb3[3].w * r0.y; + r0.y = exp2(r0.y); + r0.y = 1 + -r0.y; + r0.y = saturate(r0.w * r0.y); + r0.x = r0.x * r0.y; + r1.x = r0.x * cb3[4].x + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[4].w * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[4].y < 0.5); + r1.z = r0.y ? cb3[4].z : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t3.SampleLevel(s3_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[5].x ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[5].xxx ? r1.xyz : r0.xyz; + o0.xyz = v2.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/fire16_tesselateanimcurvelut_0x32AD961A.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire16_tesselateanimcurvelut_0x32AD961A.ps_5_0.hlsl new file mode 100644 index 00000000..a2356373 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/fire16_tesselateanimcurvelut_0x32AD961A.ps_5_0.hlsl @@ -0,0 +1,94 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:19 2026 +Texture2DArray t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2DArray t0 : register(t0); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[6]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + float4 v3 : COLOR0, + float4 v4 : TEXCOORD2, + float4 v5 : TEXCOORD3, + float4 v6 : TEXCOORD4, + float4 v7 : TEXCOORD5, + float3 v8 : TEXCOORD6, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = v2.xy / v2.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.x = t1.Sample(s1_s, r0.xy).x; + r0.x = v2.w + -r0.x; + r0.x = saturate(abs(r0.x) / cb3[3].w); + r0.x = 1 + -r0.x; + r0.x = log2(r0.x); + r0.x = cb3[4].x * r0.x; + r0.x = exp2(r0.x); + r0.x = 1 + -r0.x; + r0.y = cb3[3].y / cb3[3].z; + r0.z = cmp(r0.y >= -r0.y); + r0.y = frac(abs(r0.y)); + r0.y = r0.z ? r0.y : -r0.y; + r0.y = cb3[3].z * r0.y; + r1.z = floor(r0.y); + r1.xy = v1.xy; + r1.xyzw = t0.Sample(s0_s, r1.xyz).xyzw; + r0.x = saturate(r1.w * r0.x); + r0.yz = cb3[1].xy * r1.xy; + r0.y = r0.y + r0.z; + r0.y = cb3[1].z * r1.z + r0.y; + r0.y = v3.w * r0.y; + r0.x = r0.y * r0.x; + r1.x = r0.x * cb3[4].y + cb3[0].w; + r0.x = log2(r0.x); + r0.x = cb3[5].x * r0.x; + r0.x = exp2(r0.x); + r0.y = cmp(cb3[4].z < 0.5); + r1.z = r0.y ? cb3[4].w : 2; + r1.y = 0; + r1.x = FireTonemap(r1.x, FIRE_PEAK); + r0.yzw = t2.SampleLevel(s2_s, r1.xyz, 0).xyz; + r0.yzw *= FIRE_BOOST; + r0.yzw = cb3[0].xyz * r0.yzw; + r0.xyz = r0.yzw * r0.xxx; + r0.w = !cb3[2].y ? cb2[24].w : 1; + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb3[5].yyy * r0.xyz; + r1.xyz = cb2[26].www * r0.xyz; + r0.xyz = !cb3[2].yyy ? r1.xyz : r0.xyz; + o0.xyz = v4.www * r0.xyz; + o0.w = 0; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 new file mode 100644 index 00000000..812432f2 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 @@ -0,0 +1,621 @@ +// ---- Created with 3Dmigoto v1.3.16 on Wed Jul 15 16:25:24 2026 +Texture2D t4 : register(t4); + +Texture2D t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb4 : register(b4) +{ + float4 cb4[2]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[1]; +} + + + + +// 3Dmigoto declarations +#define cmp - + + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + float2 w1 : TEXCOORD1, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = t0.Sample(s0_s, w1.xy).xy; + r1.xyzw = t3.Sample(s0_s, w1.xy).xyzw; + o0 = r1; return;// debug + + r0.z = dot(r0.xy, r0.xy); + r0.z = sqrt(r0.z); + r0.z = cmp(r0.z >= 0.5); + if (r0.z != 0) { + r0.z = t4.Sample(s0_s, w1.xy).x; + r2.xy = t1.Sample(s0_s, w1.xy).xy; + r2.xy = cb4[0].xy * r2.xy; + r0.w = 0.5 * cb2[48].x; + r2.xy = r0.ww * r2.xy; + r2.z = dot(r2.xy, r2.xy); + r2.w = sqrt(r2.z); + r3.x = cmp(0 < r2.w); + r2.z = rsqrt(r2.z); + r2.xy = r2.xy * r2.zz; + r2.z = min(16, r2.w); + r2.xy = r2.xy * r2.zz; + r2.xy = r3.xx ? r2.xy : 0; + r2.x = dot(r2.xy, r2.xy); + r2.x = sqrt(r2.x); + r2.y = max(0.200000003, r2.x); + r2.z = 1 / r2.y; + r3.xyzw = cb3[0].xyxy * w1.xyxy; + r4.xyzw = float4(0.015625,0.015625,0.5,0.5) * r3.xyzw; + r3.xy = frac(r4.xy); + r2.w = t2.Sample(s1_s, r3.xy).x; + r2.w = -0.5 + r2.w; + r5.xyzw = cb3[0].zwzw * r0.xyxy; + r5.xyzw = cb2[22].xyxy * r5.xyzw; + r5.xyzw = r5.xyzw + r5.xyzw; + r6.xyzw = r2.wwww * float4(0.166666672,0.166666672,0.166666672,0.166666672) + float4(-0.833333313,-0.666666687,-0.5,-0.333333343); + r7.xyzw = r5.zwzw * r6.xxyy + w1.xyxy; + r7.xyzw = min(cb2[22].zwzw, r7.xyzw); + r0.xy = t1.Sample(s0_s, r7.xy).xy; + r3.x = t4.Sample(s0_s, r7.xy).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.x = sqrt(r3.y); + r4.y = cmp(0 < r4.x); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.x); + r0.xy = r3.yy * r0.xy; + r0.xy = r4.yy ? r0.xy : 0; + r8.xyz = t3.Sample(s0_s, r7.xy).xyz; + r9.xyzw = cb3[0].xyxy * r7.xyzw; + r10.xyzw = float4(0.5,0.5,0.5,0.5) * r9.xyzw; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r9.xyzw = r9.xyzw * float4(0.5,0.5,0.5,0.5) + -r4.zwzw; + r4.x = dot(r9.xy, r9.xy); + r4.x = sqrt(r4.x); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.x / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r10.xyzw = r3.zwzw * float4(0.5,0.5,0.5,0.5) + -r10.xyzw; + r4.y = dot(r10.xy, r10.xy); + r4.y = sqrt(r4.y); + r6.x = r4.y / r2.y; + r6.x = 1 + -r6.x; + r6.x = max(0, r6.x); + r6.y = r6.x * r3.x; + r7.x = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.x; + r4.x = 1 / r7.x; + r0.x = saturate(r4.x * r0.x); + r4.x = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.x * r0.x + 1; + r4.x = 0.0999999642 * r2.x; + r4.y = -r2.x * 0.949999988 + r4.y; + r4.x = 1 / r4.x; + r4.y = saturate(r4.y * r4.x); + r7.x = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r7.x * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r4.y = r0.y * r3.y + r2.z; + r3.x = r6.x * r3.x + r4.y; + r3.x = r3.x + r0.x; + r0.y = r0.y * r3.y + r6.y; + r0.x = r0.y + r0.x; + r8.xyz = r8.xyz * r0.xxx; + r8.xyz = r1.xyz * r2.zzz + r8.xyz; + r0.xy = t1.Sample(s0_s, r7.zw).xy; + r2.z = t4.Sample(s0_s, r7.zw).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.x = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.xx ? r0.xy : 0; + r7.xyz = t3.Sample(s0_s, r7.zw).xyz; + r3.y = r2.z + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r2.z = -r2.z + r0.z; + r2.z = saturate(-r2.z * cb2[48].y + 1); + r4.y = dot(r9.zw, r9.zw); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r6.x = dot(r10.zw, r10.zw); + r6.x = sqrt(r6.x); + r6.y = r6.x / r2.y; + r6.y = 1 + -r6.y; + r6.y = max(0, r6.y); + r7.w = r6.y * r2.z; + r8.w = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.w; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.x; + r4.y = saturate(r4.y * r4.x); + r6.x = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.x * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r3.x = r0.y * r3.y + r3.x; + r2.z = r6.y * r2.z + r3.x; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r7.w; + r0.x = r0.y + r0.x; + r7.xyz = r7.xyz * r0.xxx + r8.xyz; + r6.xyzw = r5.zwzw * r6.zzww + w1.xyxy; + r6.xyzw = min(cb2[22].zwzw, r6.xyzw); + r0.xy = t1.Sample(s0_s, r6.xy).xy; + r3.x = t4.Sample(s0_s, r6.xy).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r7.w = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r7.ww ? r0.xy : 0; + r8.xyz = t3.Sample(s0_s, r6.xy).xyz; + r9.xyzw = cb3[0].xyxy * r6.xyzw; + r10.xyzw = float4(0.5,0.5,0.5,0.5) * r9.xyzw; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r9.xyzw = r9.xyzw * float4(0.5,0.5,0.5,0.5) + -r4.zwzw; + r4.y = dot(r9.xy, r9.xy); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r10.xyzw = r3.zwzw * float4(0.5,0.5,0.5,0.5) + -r10.xyzw; + r6.x = dot(r10.xy, r10.xy); + r6.x = sqrt(r6.x); + r6.y = r6.x / r2.y; + r6.y = 1 + -r6.y; + r6.y = max(0, r6.y); + r7.w = r6.y * r3.x; + r8.w = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.w; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.x; + r4.y = saturate(r4.y * r4.x); + r6.x = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.x * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r6.y * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r7.w; + r0.x = r0.y + r0.x; + r7.xyz = r8.xyz * r0.xxx + r7.xyz; + r0.xy = t1.Sample(s0_s, r6.zw).xy; + r3.x = t4.Sample(s0_s, r6.zw).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.x = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.xx ? r0.xy : 0; + r6.xyz = t3.Sample(s0_s, r6.zw).xyz; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r4.y = dot(r9.zw, r9.zw); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r6.w = dot(r10.zw, r10.zw); + r6.w = sqrt(r6.w); + r7.w = r6.w / r2.y; + r7.w = 1 + -r7.w; + r7.w = max(0, r7.w); + r8.x = r7.w * r3.x; + r8.y = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.y; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.w; + r4.y = saturate(r4.y * r4.x); + r6.w = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.w * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r7.w * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r8.x; + r0.x = r0.y + r0.x; + r6.xyz = r6.xyz * r0.xxx + r7.xyz; + r7.xyzw = r2.wwww * float4(0.166666672,0.166666672,0.166666672,0.166666672) + float4(-0.166666672,0.166666672,0.333333343,0.5); + r8.xyzw = r5.zwzw * r7.xxyy + w1.xyxy; + r8.xyzw = min(cb2[22].zwzw, r8.xyzw); + r0.xy = t1.Sample(s0_s, r8.xy).xy; + r3.x = t4.Sample(s0_s, r8.xy).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.w = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.ww ? r0.xy : 0; + r9.xyz = t3.Sample(s0_s, r8.xy).xyz; + r10.xyzw = cb3[0].xyxy * r8.xyzw; + r11.xyzw = float4(0.5,0.5,0.5,0.5) * r10.xyzw; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r10.xyzw = r10.xyzw * float4(0.5,0.5,0.5,0.5) + -r4.zwzw; + r4.y = dot(r10.xy, r10.xy); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r11.xyzw = r3.zwzw * float4(0.5,0.5,0.5,0.5) + -r11.xyzw; + r6.w = dot(r11.xy, r11.xy); + r6.w = sqrt(r6.w); + r7.x = r6.w / r2.y; + r7.x = 1 + -r7.x; + r7.x = max(0, r7.x); + r7.y = r7.x * r3.x; + r8.x = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.x; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.w; + r4.y = saturate(r4.y * r4.x); + r6.w = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.w * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r7.x * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r7.y; + r0.x = r0.y + r0.x; + r6.xyz = r9.xyz * r0.xxx + r6.xyz; + r0.xy = t1.Sample(s0_s, r8.zw).xy; + r3.x = t4.Sample(s0_s, r8.zw).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.w = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.ww ? r0.xy : 0; + r8.xyz = t3.Sample(s0_s, r8.zw).xyz; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r4.y = dot(r10.zw, r10.zw); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r6.w = dot(r11.zw, r11.zw); + r6.w = sqrt(r6.w); + r7.x = r6.w / r2.y; + r7.x = 1 + -r7.x; + r7.x = max(0, r7.x); + r7.y = r7.x * r3.x; + r8.w = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.w; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.w; + r4.y = saturate(r4.y * r4.x); + r6.w = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.w * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r7.x * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r7.y; + r0.x = r0.y + r0.x; + r6.xyz = r8.xyz * r0.xxx + r6.xyz; + r7.xyzw = r5.zwzw * r7.zzww + w1.xyxy; + r7.xyzw = min(cb2[22].zwzw, r7.xyzw); + r0.xy = t1.Sample(s0_s, r7.xy).xy; + r3.x = t4.Sample(s0_s, r7.xy).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.w = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.ww ? r0.xy : 0; + r8.xyz = t3.Sample(s0_s, r7.xy).xyz; + r9.xyzw = cb3[0].xyxy * r7.xyzw; + r10.xyzw = float4(0.5,0.5,0.5,0.5) * r9.xyzw; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r9.xyzw = r9.xyzw * float4(0.5,0.5,0.5,0.5) + -r4.zwzw; + r4.y = dot(r9.xy, r9.xy); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r10.xyzw = r3.zwzw * float4(0.5,0.5,0.5,0.5) + -r10.xyzw; + r6.w = dot(r10.xy, r10.xy); + r6.w = sqrt(r6.w); + r7.x = r6.w / r2.y; + r7.x = 1 + -r7.x; + r7.x = max(0, r7.x); + r7.y = r7.x * r3.x; + r8.w = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.w; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.w; + r4.y = saturate(r4.y * r4.x); + r6.w = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.w * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r7.x * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r7.y; + r0.x = r0.y + r0.x; + r6.xyz = r8.xyz * r0.xxx + r6.xyz; + r0.xy = t1.Sample(s0_s, r7.zw).xy; + r3.x = t4.Sample(s0_s, r7.zw).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.y = dot(r0.xy, r0.xy); + r4.y = sqrt(r3.y); + r6.w = cmp(0 < r4.y); + r3.y = rsqrt(r3.y); + r0.xy = r3.yy * r0.xy; + r3.y = min(16, r4.y); + r0.xy = r3.yy * r0.xy; + r0.xy = r6.ww ? r0.xy : 0; + r7.xyz = t3.Sample(s0_s, r7.zw).xyz; + r3.y = r3.x + -r0.z; + r3.y = saturate(-r3.y * cb2[48].y + 1); + r3.x = -r3.x + r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r4.y = dot(r9.zw, r9.zw); + r4.y = sqrt(r4.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r4.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r6.w = dot(r10.zw, r10.zw); + r6.w = sqrt(r6.w); + r7.w = r6.w / r2.y; + r7.w = 1 + -r7.w; + r7.w = max(0, r7.w); + r8.x = r7.w * r3.x; + r8.y = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r4.y; + r4.y = 1 / r8.y; + r0.x = saturate(r4.y * r0.x); + r4.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r4.y * r0.x + 1; + r4.y = -r2.x * 0.949999988 + r6.w; + r4.y = saturate(r4.y * r4.x); + r6.w = r4.y * -2 + 3; + r4.y = r4.y * r4.y; + r4.y = -r6.w * r4.y + 1; + r0.x = dot(r4.yy, r0.xx); + r2.z = r0.y * r3.y + r2.z; + r2.z = r7.w * r3.x + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.y + r8.x; + r0.x = r0.y + r0.x; + r6.xyz = r7.xyz * r0.xxx + r6.xyz; + r7.xyzw = r2.wwww * float4(0.166666672,0.166666672,0.166666672,0.166666672) + float4(0.666666687,0.666666687,0.833333313,0.833333313); + r5.xyzw = r5.xyzw * r7.xyzw + w1.xyxy; + r5.xyzw = min(cb2[22].zwzw, r5.xyzw); + r0.xy = t1.Sample(s0_s, r5.xy).xy; + r2.w = t4.Sample(s0_s, r5.xy).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r3.x = dot(r0.xy, r0.xy); + r3.y = sqrt(r3.x); + r4.y = cmp(0 < r3.y); + r3.x = rsqrt(r3.x); + r0.xy = r3.xx * r0.xy; + r3.x = min(16, r3.y); + r0.xy = r3.xx * r0.xy; + r0.xy = r4.yy ? r0.xy : 0; + r7.xyz = t3.Sample(s0_s, r5.xy).xyz; + r8.xyzw = cb3[0].xyxy * r5.xyzw; + r9.xyzw = float4(0.5,0.5,0.5,0.5) * r8.xyzw; + r3.x = r2.w + -r0.z; + r3.x = saturate(-r3.x * cb2[48].y + 1); + r2.w = -r2.w + r0.z; + r2.w = saturate(-r2.w * cb2[48].y + 1); + r8.xyzw = r8.xyzw * float4(0.5,0.5,0.5,0.5) + -r4.zwzw; + r3.y = dot(r8.xy, r8.xy); + r3.y = sqrt(r3.y); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r3.y / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r9.xyzw = r3.zwzw * float4(0.5,0.5,0.5,0.5) + -r9.xyzw; + r3.z = dot(r9.xy, r9.xy); + r3.z = sqrt(r3.z); + r3.w = r3.z / r2.y; + r3.w = 1 + -r3.w; + r3.w = max(0, r3.w); + r4.y = r3.w * r2.w; + r4.z = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r3.y; + r3.y = 1 / r4.z; + r0.x = saturate(r3.y * r0.x); + r3.y = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r3.y * r0.x + 1; + r3.y = -r2.x * 0.949999988 + r3.z; + r3.y = saturate(r3.y * r4.x); + r3.z = r3.y * -2 + 3; + r3.y = r3.y * r3.y; + r3.y = -r3.z * r3.y + 1; + r0.x = dot(r3.yy, r0.xx); + r2.z = r0.y * r3.x + r2.z; + r2.z = r3.w * r2.w + r2.z; + r2.z = r2.z + r0.x; + r0.y = r0.y * r3.x + r4.y; + r0.x = r0.y + r0.x; + r3.xyz = r7.xyz * r0.xxx + r6.xyz; + r0.xy = t1.Sample(s0_s, r5.zw).xy; + r2.w = t4.Sample(s0_s, r5.zw).x; + r0.xy = cb4[0].xy * r0.xy; + r0.xy = r0.ww * r0.xy; + r0.w = dot(r0.xy, r0.xy); + r3.w = sqrt(r0.w); + r4.y = cmp(0 < r3.w); + r0.w = rsqrt(r0.w); + r0.xy = r0.xy * r0.ww; + r0.w = min(16, r3.w); + r0.xy = r0.xy * r0.ww; + r0.xy = r4.yy ? r0.xy : 0; + r4.yzw = t3.Sample(s0_s, r5.zw).xyz; + r0.w = r2.w + -r0.z; + r0.w = saturate(-r0.w * cb2[48].y + 1); + r0.z = -r2.w + r0.z; + r0.z = saturate(-r0.z * cb2[48].y + 1); + r2.w = dot(r8.zw, r8.zw); + r2.w = sqrt(r2.w); + r0.x = dot(r0.xy, r0.xy); + r0.x = sqrt(r0.x); + r0.y = max(0.200000003, r0.x); + r0.y = r2.w / r0.y; + r0.y = 1 + -r0.y; + r0.y = max(0, r0.y); + r3.w = dot(r9.zw, r9.zw); + r3.w = sqrt(r3.w); + r2.y = r3.w / r2.y; + r2.y = 1 + -r2.y; + r2.y = max(0, r2.y); + r5.x = r2.y * r0.z; + r5.y = 0.0999999642 * r0.x; + r0.x = -r0.x * 0.949999988 + r2.w; + r2.w = 1 / r5.y; + r0.x = saturate(r2.w * r0.x); + r2.w = r0.x * -2 + 3; + r0.x = r0.x * r0.x; + r0.x = -r2.w * r0.x + 1; + r2.x = -r2.x * 0.949999988 + r3.w; + r2.x = saturate(r2.x * r4.x); + r2.w = r2.x * -2 + 3; + r2.x = r2.x * r2.x; + r2.x = -r2.w * r2.x + 1; + r0.x = dot(r2.xx, r0.xx); + r2.x = r0.y * r0.w + r2.z; + r0.z = r2.y * r0.z + r2.x; + r0.z = r0.z + r0.x; + r0.y = r0.y * r0.w + r5.x; + r0.x = r0.y + r0.x; + r0.xyw = r4.yzw * r0.xxx + r3.xyz; + r1.xyz = r0.xyw / r0.zzz; + } + o0.xyzw = r1.xyzw; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl new file mode 100644 index 00000000..c9da4e05 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl @@ -0,0 +1,53 @@ +// ---- Created with 3Dmigoto v1.3.16 on Wed Jul 15 00:19:25 2026 +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb0 : register(b0) +{ + float4 cb0[10]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : COLOR0, + float2 v2 : TEXCOORD0, + float2 w2 : TEXCOORD1, + uint v3 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = t1.Sample(s0_s, w2.xy).x; + r0.xyz = cb0[5].xyz * r0.xxx; + r0.w = t0.Sample(s0_s, v2.xy).x; + r0.xyz = r0.www * cb0[8].xyz + r0.xyz; + r0.w = t2.Sample(s0_s, w2.xy).x; + r0.xyz = r0.www * cb0[6].xyz + r0.xyz; + r0.xyz = saturate(cb0[7].xyz + r0.xyz); + o0.xyz = v1.xyz * r0.xyz; + o0.w = v1.w; + + // Scale to scene paper white + if (HDR_ENABLED) { + o0.xyz = saturate(o0.xyz); // original unorm clamp + o0.xyz = sRGB_Decode(o0.xyz); + // o0.xyz = pow(o0.xyz, 2.2); + o0.xyz *= HDR_INTSCALING; + o0.xyz = sRGB_Encode(o0.xyz); + } + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/photomode_contrast_0xC2665219.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/photomode_contrast_0xC2665219.ps_5_0.hlsl new file mode 100644 index 00000000..dd2d1af2 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/photomode_contrast_0xC2665219.ps_5_0.hlsl @@ -0,0 +1,74 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:42 2026 +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[1]; +} + +cbuffer cb0 : register(b0) +{ + float4 cb0[26]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#include "../../Includes/Math.hlsl" + +float3 RenoDX_Contrast(float3 x, float contrast, float mid_gray = 0.18f) { + return pow(max(0, x / mid_gray), contrast) * mid_gray; +} + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + uint v3 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + o0.w = 1; + + // r0.x = 1.5 + -cb3[0].x; + // r0.x = 1 / r0.x; + // r0.y = cmp(0.5 >= cb3[0].x); + // r0.z = 0.5 + cb3[0].x; + // r0.x = r0.y ? r0.z : r0.x; + + r0.yz = min(cb2[22].zw, v1.zw); + r0.yzw = t0.Sample(s0_s, r0.yz).xyz; + +// r0.yzw = saturate(r0.yzw / cb0[25].xxx); //establishes threshold, default 6.25 +// r1.xyz = -r0.yzw * float3(2,2,2) + float3(2,2,2); +// +// r1.xyz = pow(r1.xyz, r0.x); +// +// r1.xyz = float3(2,2,2) + -r1.xyz; +// r1.xyz = float3(0.5,0.5,0.5) * r1.xyz; +// r2.xyz = r0.yzw + r0.yzw; +// r0.y = dot(r0.yzw, float3(0.300000012,0.589999974,0.109999999)); +// r0.y = cmp(r0.y < 0.5); +// r0.xzw = r2.xyz * r0.xxx; +// r0.xzw = 0.5 * r0.xzw; +// r0.xyz = saturate(r0.yyy ? r0.xzw : r1.xyz); +// r0.xyz = cb0[25].xxx * r0.xyz; + + r0.xyz = r0.yzw; + r0.xyz = RenoDX_Contrast(r0.xyz, cb3[0].x * 2, 0.1); + + o0.xyz = r0.xyz; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl new file mode 100644 index 00000000..634d0b4c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl @@ -0,0 +1,52 @@ +// ---- Created with 3Dmigoto v1.3.16 on Wed Jul 15 00:22:42 2026 +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[1]; +} + +cbuffer cb0 : register(b0) +{ + float4 cb0[26]; +} + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD1, + uint v3 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0; + uint4 bitmask, uiDest; + float4 fDest; + o0.w = 1; + + r0.xy = min(cb2[22].zw, v1.zw); + r0.xyz = t0.Sample(s0_s, r0.xy).xyz; + + // some EV thing + r0.xyz = r0.xyz / cb0[25].xxx; + r0.w = -0.5 + cb3[0].x; + r0.w = 4 * r0.w; + r0.w = exp2(r0.w); + r0.xyz = r0.xyz * r0.www; + r0.xyz = cb0[25].xxx * r0.xyz; + + // if (HDR_ENABLED) r0.xyz = HDRTonemap(r0.xyz, HDR_PEAK); + + o0.xyz = r0.xyz; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 new file mode 100644 index 00000000..ecca9a57 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 @@ -0,0 +1,144 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:23 2026 +Texture2D t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[4]; +} + +cbuffer cb1 : register(b1) +{ + float4 cb1[2]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#if FIRE_RETUNED == 0 +LET_THIS_BREAK +#endif + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float4 v2 : TEXCOORD2, + float4 v3 : TEXCOORD3, + float3 v4 : TEXCOORD4, + float4 v5 : COLOR0, + out float4 o0 : SV_Target0, + out float4 o1 : SV_Target1, + out float4 o2 : SV_Target2, + out float4 o3 : SV_Target3) +{ + float4 r0,r1,r2,r3,r4,r5,r6,r7,r8; + uint4 bitmask, uiDest; + float4 fDest; + + r0.x = 1 + -v5.w; + r1.x = v1.x * cb3[0].x + cb3[0].w; + r1.y = v1.y * cb3[0].y + cb3[1].x; + r0.yz = cb1[1].xx * cb3[1].yz + r1.xy; + r0.yz = t0.Sample(s0_s, r0.yz).yw; //distort + r1.xy = r0.yz * float2(2,2) + float2(-1,-1); + r1.z = -r1.y; + r0.yz = r1.xz * cb3[2].xy + v1.xy; + r1.xyzw = t1.Sample(s0_s, r0.yz).xyzw; + + r0.x = r1.w + -r0.x; + r0.x = cmp(r0.x < 0); + if (r0.x != 0) discard; + + r0.x = abs(v3.z) + abs(v2.z); + r0.x = abs(v4.z) + r0.x; + r0.x = 1 / r0.x; + r2.x = v2.z; + r2.y = v3.z; + r0.xw = r2.xy * r0.xx; + r2.xy = cmp(r0.xw >= float2(0,0)); + r2.xy = r2.xy ? float2(1,1) : float2(-1,-1); + r2.zw = float2(1,1) + -abs(r0.wx); + r2.xy = r2.zw * r2.xy; + r2.z = cmp(0 >= v4.z); + r0.xw = r2.zz ? r2.xy : r0.xw; + r0.xw = max(float2(-1,-1), r0.xw); + r0.xw = min(float2(1,1), r0.xw); + r0.xw = r0.xw * float2(511.5,511.5) + float2(511.5,511.5); + r2.xy = round(r0.xw); + r0.xw = r2.yx * float2(0.00195503421,0.00195503421) + float2(-1,-1); + r3.xy = cmp(r0.xw >= float2(0,0)); + r3.xy = r3.xy ? float2(1,1) : float2(-1,-1); + r4.xyz = float3(1,1,1) + -abs(r0.wxw); + r3.xy = r4.zy * r3.xy; + r4.y = r4.x + -abs(r0.x); + r3.z = cmp(r4.y < 0); + r4.xz = r3.zz ? r3.xy : r0.xw; + r3.z = cb2[5].x; + r3.x = cb2[6].x; + r3.y = cb2[4].x; + r5.xyz = r3.xyz * r4.xyz; + r3.xyz = r3.zxy * r4.yzx + -r5.xyz; + r0.x = dot(r3.xyz, r3.xyz); + r0.x = max(1.17549435e-038, r0.x); + r0.x = sqrt(r0.x); + r3.xyz = r3.xyz / r0.xxx; + r5.xyz = r3.zxy * r4.xyz; + r5.xyz = r3.yzx * r4.yzx + -r5.xyz; + r6.xyzw = t2.Sample(s1_s, r0.yz).xyzw; + r0.xyzw = t3.Sample(s1_s, r0.yz).xyzw; + r7.xy = r6.yw * float2(2,2) + float2(-1,-1); + r3.w = -r7.x * r7.x + 1; + r3.w = -r7.y * r7.y + r3.w; + r3.w = max(0, r3.w); + r7.z = sqrt(r3.w); + r8.x = dot(v2.xyz, r7.xyz); + r8.y = dot(v3.xyz, r7.xyz); + r8.z = dot(v4.xyz, r7.xyz); + r3.w = dot(r8.xyz, r8.xyz); + r3.w = rsqrt(r3.w); + r7.xyz = r8.xyz * r3.www; + r3.w = dot(r4.zxy, r7.xyz); + r4.xyz = -r4.zxy * r3.www + r7.xyz; + r5.y = dot(r4.xyz, r5.xyz); + r5.x = dot(r4.xyz, r3.xyz); + r3.xy = cmp(float2(0,0) < r5.xy); + r3.zw = cmp(r5.xy < float2(0,0)); + r4.xy = sqrt(abs(r5.xy)); + r3.xy = (int2)-r3.xy + (int2)r3.zw; + r3.xy = (int2)r3.xy; + r3.xy = r3.xy * r4.xy; + o0.xy = r3.xy * float2(0.5,0.5) + float2(0.5,0.5); + r3.x = 0.00390625 * r2.y; + r2.z = floor(r3.x); + r2.w = -r2.z * 256 + r2.y; + r2.xyz = float3(0.000977517106,0.333333343,0.00392156886) * r2.xzw; + o0.zw = r2.xy; + o1.w = r2.z; + o1.xyz = v5.xyz * r1.xyz; + o2.xyz = r0.zyx; + o3.x = r0.w * r6.z; + o3.z = r6.x; + o2.w = 0.501960993; + r0.x = cb3[3].y * v5.x + cb3[3].x; + r0.x = r1.w * r0.x; + o3.y = cb3[2].w * r0.x; + o3.w = cb3[3].z * 0.00392156886 + 0.125490203; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl new file mode 100644 index 00000000..dfd45a41 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl @@ -0,0 +1,97 @@ +// ---- Created with 3Dmigoto v1.3.16 on Tue Jul 14 19:50:52 2026 + +cbuffer CBuffer_Data : register(b0) +{ + float2 TexCoordScale0 : packoffset(c0); + float2 MaxTexCoord0 : packoffset(c0.z); + float2 Gamma : packoffset(c1); +} + +SamplerState TextureSampler_s : register(s0); +Texture2D SourceBuffer0 : register(t0); +Texture2D SourceBuffer1 : register(t1); + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#include "./Includes/RCAS.hlsl" + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + out float4 o0 : SV_TARGET0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + +// // r0.xy = TexCoordScale0.xy * v1.xy; +// // r0.xy = min(MaxTexCoord0.xy, r0.xy); +// // r0.xyz = SourceBuffer0.SampleLevel(TextureSampler_s, r0.xy, 0).xyz; //idk black, hud mask? +// // r1.xyzw = SourceBuffer1.SampleLevel(TextureSampler_s, v1.xy, 0).xyzw; //main color +// // r1.w = 1 + -r1.w; +// // +// // r1.xyz = log2(r1.xyz); +// // r1.xyz = Gamma.xxx * r1.xyz; +// // r1.xyz = exp2(r1.xyz); +// // r1.xyz = Gamma.yyy * r1.xyz; +// // +// // o0.xyz = r0.xyz * r1.www + r1.xyz; +// // o0.w = 1; +// +// // texcoords +// r0.xy = TexCoordScale0.xy * v1.xy; +// r0.xy = min(MaxTexCoord0.xy, r0.xy); +// +// //// GAME //// +// float3 game = SourceBuffer0.SampleLevel(TextureSampler_s, r0.xy, 0).xyz; +// // game = Neupow(game, HDR_PEAK, 2); //rolloff +// #if RCAS_ENABLED == 1 +// game = RCAS(game, SourceBuffer0, TextureSampler_s, r0.xy, GS.RCAS, GamePaperWhiteNits / ITU_WhiteLevelNits); +// #endif +// game = max(game, 0); +// +// #if GAMMA_CORRECT_CUSTOM == 1 +// game.xyz = sRGB_Encode(game.xyz); +// game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : sRGB_Decode(game.xyz); +// #endif +// +// game *= HDR_INTSCALING; +// +// //// UI //// +// float4 ui = SourceBuffer1.SampleLevel(TextureSampler_s, v1.xy, 0).xyzw; +// ui.w = saturate(ui.w); +// ui.w = pow(ui.w, 2.2); +// #if GAMMA_CORRECT_CUSTOM == 0 +// ui.xyz = sRGB_Decode(ui.xyz); +// #else +// ui.xyz = ui.xyz < 1 ? pow(ui.xyz, 2.2) : sRGB_Decode(ui.xyz); +// #endif +// ui = max(ui, 0); +// +// //// COMBINE //// +// float3 x = game * (1 - ui.w) + ui.xyz; +// x = min(HDR_PEAK * HDR_INTSCALING, x); +// +// //// TEST_USER_PEAK //// +// #if TEST_USER_PEAK == 1 +// x = 0; +// x = DrawRect(v1.xy, float4(0.35, 0.47, 0.65, 0.53), x, 10000.f/UIPaperWhiteNits); +// x = DrawRect(v1.xy, float4(0.365, 0.483, 0.448, 0.517), x, PeakWhiteNits*2/UIPaperWhiteNits); +// x = DrawRect(v1.xy, float4(0.458, 0.483, 0.542, 0.517), x, PeakWhiteNits/UIPaperWhiteNits); +// x = DrawRect(v1.xy, float4(0.552, 0.483, 0.635, 0.517), x, PeakWhiteNits/2/UIPaperWhiteNits); +// #endif + + float3 x; + + //do a pink checkboard pattern + if (fmod(floor(v1.x * 128) + floor(v1.y * 128), 2) == 0) + x = float3(0.1, 0, 0.1); + else + x = float3(0, 0, 0); + + o0.xyz = x; + o0.w = 1; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl new file mode 100644 index 00000000..94445a7a --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl @@ -0,0 +1,138 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:12 2026 + +cbuffer CBuffer_Data : register(b0) +{ + float2 TexCoordScale0 : packoffset(c0); + float2 MaxTexCoord0 : packoffset(c0.z); + float2 Gamma : packoffset(c1); +} + +SamplerState TextureSampler_s : register(s0); +Texture2D SourceBuffer0 : register(t0); +Texture2D SourceBuffer1 : register(t1); + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#include "./Includes/RCAS.hlsl" + +float3 GameGamma(float3 x) { + float3 r0, r1, r2; + r0.xyz = x; + r0.xyz = log2(r0.xyz); + r0.xyz = Gamma.xxx * r0.xyz; + r1.xyz = float3(0.416666657,0.416666657,0.416666657) * r0.xyz; + r0.xyz = exp2(r0.xyz); + r1.xyz = exp2(r1.xyz); + r1.xyz = r1.xyz * float3(1.05499995,1.05499995,1.05499995) + float3(-0.0549999997,-0.0549999997,-0.0549999997); + r2.xyz = cmp(r0.xyz < float3(0.00313080009,0.00313080009,0.00313080009)); + r0.xyz = float3(12.9200001,12.9200001,12.9200001) * r0.xyz; + return r2.xyz ? r0.xyz : r1.xyz; +} + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + out float4 o0 : SV_TARGET0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + + // texcoords + r0.xy = TexCoordScale0.xy * v1.xy; + r0.xy = min(MaxTexCoord0.xy, r0.xy); + + //// GAME //// + float3 game = SourceBuffer0.SampleLevel(TextureSampler_s, r0.xy, 0).xyz; + game = max(game, 0); + + #if RCAS_ENABLED == 1 + game = RCAS(game, SourceBuffer0, TextureSampler_s, r0.xy, GS.RCAS, GamePaperWhiteNits / ITU_WhiteLevelNits); + game = max(game, 0); + #endif + + if (!HDR_ENABLED) + { + game = sRGB_Decode(game); //decode gamma slider + } else { + #if GAMMA_CORRECT_CUSTOM == 1 + game.xyz = sRGB_Encode(game.xyz); + game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : sRGB_Decode(game.xyz); + #endif + + game *= HDR_INTSCALING; + } + + //// UI //// + float4 ui = SourceBuffer1.SampleLevel(TextureSampler_s, v1.xy, 0).xyzw; + ui.xyzw = max(0, ui.xyzw); + ui.w = min(ui.w, 1); + + float3 uiBack = ui.xyz; + ui.xyz = sRGB_Decode(ui.xyz); + + if (HDR_ENABLED) { + #if GAMMA_CORRECT_CUSTOM == 1 + ui.xyz = ui.xyz < 1 ? pow(uiBack, 2.2) : ui.xyz; + #endif + } else { + ui.xyz = GameGamma(ui.xyz); + ui.xyz = sRGB_Decode(ui.xyz); + } + + //// COMBINE //// + ui.xyz = sRGB_Encode(ui.xyz); // TODO: or 2.2? prob doesnt matter + game = sRGB_Encode(game); + float3 x = game * (1 - ui.w) + ui.xyz; //in gamma space + x = sRGB_Decode(x); + if (HDR_ENABLED) x = min(HDR_PEAK * HDR_INTSCALING, x); //peak clamp + + //// TEST_USER_PEAK //// + #if TEST_USER_PEAK == 1 + x = 0; + x = DrawRect(v1.xy, float4(0.35, 0.47, 0.65, 0.53), x, 10000.f/UIPaperWhiteNits); + x = DrawRect(v1.xy, float4(0.365, 0.483, 0.448, 0.517), x, PeakWhiteNits*2/UIPaperWhiteNits); + x = DrawRect(v1.xy, float4(0.458, 0.483, 0.542, 0.517), x, PeakWhiteNits/UIPaperWhiteNits); + x = DrawRect(v1.xy, float4(0.552, 0.483, 0.635, 0.517), x, PeakWhiteNits/2/UIPaperWhiteNits); + #endif + + o0.xyz = x; + o0.w = 1; + return; +} + +// void main( +// float4 v0 : SV_POSITION0, +// float2 v1 : TEXCOORD0, +// out float4 o0 : SV_TARGET0) +// { +// float4 r0,r1,r2; +// uint4 bitmask, uiDest; +// float4 fDest; +// +// r0.xyzw = SourceBuffer1.SampleLevel(TextureSampler_s, v1.xy, 0).xyzw; +// r0.w = 1 + -r0.w; +// r0.xyz = log2(r0.xyz); +// r0.xyz = Gamma.xxx * r0.xyz; +// r1.xyz = float3(0.416666657,0.416666657,0.416666657) * r0.xyz; +// r0.xyz = exp2(r0.xyz); +// r1.xyz = exp2(r1.xyz); +// r1.xyz = r1.xyz * float3(1.05499995,1.05499995,1.05499995) + float3(-0.0549999997,-0.0549999997,-0.0549999997); +// r2.xyz = cmp(r0.xyz < float3(0.00313080009,0.00313080009,0.00313080009)); +// r0.xyz = float3(12.9200001,12.9200001,12.9200001) * r0.xyz; +// r0.xyz = r2.xyz ? r0.xyz : r1.xyz; +// +// r1.xy = TexCoordScale0.xy * v1.xy; +// r1.xy = min(MaxTexCoord0.xy, r1.xy); +// r1.xyz = SourceBuffer0.SampleLevel(TextureSampler_s, r1.xy, 0).xyz; +// #if RCAS_ENABLED == 1 +// r1.xyz = RCAS(r1.xyz, SourceBuffer0, TextureSampler_s, r0.xy, GS.RCAS, 1); +// r1.xyz = max(r1.xyz, 0); +// #endif +// +// o0.xyz = r1.xyz * r0.www + r0.xyz; +// o0.w = 1; +// return; +// } diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl new file mode 100644 index 00000000..10807b7c --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl @@ -0,0 +1,164 @@ +// ---- Created with 3Dmigoto v1.3.16 on Tue Jul 14 19:39:24 2026 +Buffer t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[4]; +} + + + + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#include "../Includes/ColorGradingLUT.hlsl" +float3 PerceptualLerp(float3 colorA, float3 colorB, float alpha, float gamma = 2.2) +{ + float luminanceA = GetLuminance(colorA.rgb); + float luminanceB = GetLuminance(colorB.rgb); + float gammaLuminanceA = pow(max(luminanceA, 0.f), 1.0 / gamma); // Linear->Gamma + float gammaLuminanceB = pow(max(luminanceB, 0.f), 1.0 / gamma); // Linear->Gamma + float targetLuminance = pow(lerp(gammaLuminanceA, gammaLuminanceB, alpha), gamma); // Blend in gamma space + + float3 colorLerped = lerp(colorA, colorB, alpha); + float sourceLuminance = GetLuminance(colorLerped.rgb); + if (sourceLuminance != 0.f) colorLerped.rgb *= max(targetLuminance / sourceLuminance, 0.f); // If any of the two luminance is negative, clip to black + return colorLerped; +} + +// https://www.desmos.com/calculator/stnfdhk9t1 +float Rolloff(float x, float invPeak, float invExposure) {return DivideSafe(x, x * invPeak + invExposure, 0);} +float3 Rolloff(float3 x, float invPeak, float invExposure) {return DivideSafe(x, x * invPeak + invExposure, 0);} + +float RolloffComplete(float x, float contrast, float invPeak, float invExposure) { + x = pow(x, contrast); + return DivideSafe(x, x * invPeak + invExposure, 0); +} +float3 RolloffComplete(float3 x, float contrast, float invPeak, float invExposure) { + x = pow(x, contrast); + return DivideSafe(x, x * invPeak + invExposure, 0); +} + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float2 v2 : TEXCOORD1, + uint v3 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1; + uint4 bitmask, uiDest; + float4 fDest; + + // color + r0.xy = v1.xy / v1.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.xyz = t0.Sample(s0_s, r0.xy).xyz; + + // flashbang mask? + r1.xyz = (int3)r0.xyz & int3(0x7f800000,0x7f800000,0x7f800000); + r1.xyz = cmp((int3)r1.xyz != int3(0x7f800000, 0x7f800000, 0x7f800000)); + r0.xyz = r1.xyz ? r0.xyz : float3(65000,65000,65000); + +// // pow +// // r0.xyz = pow(r0.xyz, cb3[0].x); +// #define POW_MODE 1 +// #if POW_MODE == 0 +// // reduced +// r0.xyz = pow(r0.xyz, lerp(cb3[0].x , min(1.42, cb3[0].x), 0.8)); +// #elif POW_MODE == 1 +// // reduced & low passed +// { +// float3 o = r0.xyz; +// float lg = lerp(cb3[0].x, min(1.42, cb3[0].x), 0.8); +// float ug = lerp(cb3[0].x, min(1.248, cb3[0].x), 0.8); +// float3 l = pow(r0.xyz, lg); +// float3 u = pow(r0.xyz, ug); +// float s = saturate(GetLuminance(l) * 3); +// float3 s3 = saturate(l * 3); +// // r0.xyz = lerp(l, u, 0.8 * s); +// r0.xyz = PerceptualLerp(l, u, s * 0.8, (lerp(lg, ug, s) + 1) * 0.8); +// // r0.xyz = pow(r0.xyz, (1/1.05)); +// } +// #endif +// +// // Reinhard Coeffs +// r0.w = t1.Load(1).x /* DVS2 */; //inv peak (this can go negative, meaning inv tonemap ahh asymptote for highlights...) +// r1.x = t1.Load(2).x /* DVS1 */; //inv exposure/contrast +// +// // r1.xyz = r0.xyz * r0.www + r1.xxx; +// // r1.xyz = max(float3(9.99999975e-006,9.99999975e-006,9.99999975e-006), r1.xyz); +// // r0.xyz = r0.xyz / r1.xyz; +// #if 0 +// // original improved, unclamped +// r0.w = max(r0.w, 0.0); //NO INVERSE TONEMAP AHH +// r0.xyz = Rolloff(r0.xyz, r0.w, r1.x); +// r0.xyz *= (80.f / 500.f); +// #else +// // replacement +// r0.xyz *= DivideSafe(1, r1.x, 0) * (80.f / 500.f); +// // r0.xyz *= (Rolloff(0.18, max(r0.w, 0.0), r1.x) / 0.18) * (80.f / 500.f); +// r0.xyz = Neupow(r0.xyz, HDR_PEAK, 2 * GS.WhiteClip); +// #endif + +// // pow and Reinhard +// // r0.w = t1.Load(1).x; //useless +// r1.x = t1.Load(2).x; +// r0.xyz = pow(r0.xyz, cb3[0].x); +// r0.xyz *= DivideSafe(1, r1.x, 0); +// r0.xyz = pow(r0.xyz, 1/cb3[0].x); +// { +// float3 o = r0.xyz; +// float lg = lerp(cb3[0].x, min(1.42, cb3[0].x), 0.8); +// float ug = lerp(cb3[0].x, min(1.248, cb3[0].x), 0.8); +// float3 l = pow(r0.xyz, lg); +// float3 u = pow(r0.xyz, ug); +// float s = saturate(GetLuminance(l) * 3); +// float3 s3 = saturate(l * 3); +// r0.xyz = PerceptualLerp(l, u, s * 0.8, (lerp(lg, ug, s) + 1) * 0.8); +// } +// r0.xyz *= (80.f / 500.f); +// r0.xyz = HDRTonemap(r0.xyz, HDR_PEAK); + + // pow and Reinhard + // r0.w = t1.Load(1).x; //useless + r1.x = t1.Load(2).x; + r0.xyz *= DivideSafe(1, pow(r1.x, 0.6), 0); + r0.xyz = pow(r0.xyz, pow(cb3[0].x, 0.6)); + r0.xyz *= (80.f / 500.f); + r0.xyz = HDRTonemap(r0.xyz, HDR_PEAK); + + r0.w = max3(r0.x, r0.y, r0.z); + r0.w = max(9.99999975e-006, r0.w); + r0.xyz = r0.xyz / r0.www; + r0.xyz = pow(r0.xyz, cb3[0].y); + r1.xyz = float3(1,1,1) + -r0.xyz; + r1.w = -cb3[0].w * cb3[1].x + r0.w; + r1.w = max(0, r1.w); + r1.w = cb3[0].z * r1.w; + r0.xyz = r1.www * r1.xyz + r0.xyz; + r0.xyz = r0.xyz * r0.www; + + // clean + r0.xyz = max(r0.xyz, 0); + r0.xyz = min(r0.xyz, cb3[1].x); //usually 125, idk + + // gamma + // r0.xyz = r0.xyz / cb3[1].xxx; //normalize 0-cb3[1].x (makes influence even more deadly) + // r0.xyz = pow(r0.xyz, cb3[1].y); + // r0.xyz = cb3[1].xxx * r0.xyz; + + o0.xyz = r0.xyz; + o0.w = 1; + return; +} \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl new file mode 100644 index 00000000..c666faa7 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl @@ -0,0 +1,243 @@ +// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:51 2026 +Buffer t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb3 : register(b3) +{ + float4 cb3[4]; +} + +// 3Dmigoto declarations +#define cmp - +#include "./common.hlsl" +#include "../Includes/ColorGradingLUT.hlsl" + +float3 PerceptualLerp(float3 colorA, float3 colorB, float alpha, float gamma = 2.2) +{ + float luminanceA = GetLuminance(colorA.rgb); + float luminanceB = GetLuminance(colorB.rgb); + float gammaLuminanceA = pow(max(luminanceA, 0.f), 1.0 / gamma); // Linear->Gamma + float gammaLuminanceB = pow(max(luminanceB, 0.f), 1.0 / gamma); // Linear->Gamma + float targetLuminance = pow(lerp(gammaLuminanceA, gammaLuminanceB, alpha), gamma); // Blend in gamma space + + float3 colorLerped = lerp(colorA, colorB, alpha); + float sourceLuminance = GetLuminance(colorLerped.rgb); + if (sourceLuminance != 0.f) colorLerped.rgb *= max(targetLuminance / sourceLuminance, 0.f); // If any of the two luminance is negative, clip to black + return colorLerped; +} + +float3 RenoDX_Contrast(float3 x, float contrast, float mid_gray = 0.18f) { + return pow(max(0, x / mid_gray), contrast) * mid_gray; +} + +// https://www.desmos.com/calculator/stnfdhk9t1 +float Rolloff(float x, float contrast, float invPeak, float invExposure) { + x = pow(x, contrast); + return DivideSafe(x, x * invPeak + invExposure, 0); +} +float3 Rolloff(float3 x, float contrast, float invPeak, float invExposure) { + x = pow(x, contrast); + return DivideSafe(x, x * invPeak + invExposure, 0); +} + +float RolloffLocalMax(float contrast, float invPeak, float invExposure) { + float c = contrast; + float a = invPeak; + float b = invExposure; + return pow((b * c - b) / (a * c + a), rcp(c)); //2nd derivative = 0 +} +float RolloffSlope(float x, float contrast, float invPeak, float invExposure) { + return (invExposure * contrast * pow(x, contrast - 1)) / pow((invPeak * pow(x, contrast) + invExposure), 2); //1st derivative @ x +} +float3 RolloffExt(float3 x, float contrast, float invPeak, float invExposure) { + float3 xBack = x; + + // extend + float thres = RolloffLocalMax(contrast, invPeak, invExposure); + float3 lower = Rolloff(x, contrast, invPeak, invExposure); + float3 higher = RolloffSlope(max(thres, 0.000001), contrast, invPeak, invExposure) * (x - thres) + Rolloff(thres, contrast, invPeak, invExposure); + x = x < thres ? lower : higher; + + // HDR per channel + x = Neupow(x, HDR_PEAK, 2.2 * GS.WhiteClip); + // x = ExponentialRollOff(x, thres, HDR_PEAK, 100 / GS.WhiteClip); + + // correct HDR perchannel; + { + float3 sdr = lower; + sdr = UCS_Encode(sdr); + x = UCS_Encode(x); + x = RestoreHueAndChrominanceUcs(x, sdr, GS.BlowoutCorrection, 0, 0); + x = UCS_Decode(x); + + // clean under/over shoot + x = max(x, 0); + x = min(HDR_PEAK, x); + } + + return x; +} + +void main( + float4 v0 : SV_POSITION0, + float4 v1 : TEXCOORD0, + float2 v2 : TEXCOORD1, + uint v3 : SV_IsFrontFace0, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2; + uint4 bitmask, uiDest; + float4 fDest; + + // color + r0.xy = v1.xy / v1.ww; + r0.xy = min(cb2[22].zw, r0.xy); + r0.xyz = t0.Sample(s0_s, r0.xy).xyz; + + // idk mask + r1.xyz = (int3)r0.xyz & int3(0x7f800000,0x7f800000,0x7f800000); + r1.xyz = cmp((int3)r1.xyz != int3(0x7f800000,0x7f800000,0x7f800000)); + r0.xyz = r1.xyz ? r0.xyz : float3(65000,65000,65000); + + // rolloff + float contrast = cb3[0].x; + float invPeak = t1.Load(1).x; //aka white clip + float invExposure = t1.Load(2).x; + if (HDR_ENABLED) { + r0.xyz = RolloffExt(r0.xyz, contrast, invPeak, invExposure); + } else { + r0.xyz = Rolloff(r0.xyz, contrast, invPeak, invExposure); + } + + // r0.xyz = t1.Load(1).x - DVS1; //debug identify invPeak + // r0.xyz = t1.Load(2).x - DVS1; //debug identify invExposure + + // max channel saturation / white path + r0.w = max(r0.y, r0.z); + r0.w = max(r0.x, r0.w); + + r0.w = max(9.99999975e-006, r0.w); + r0.xyz = r0.xyz / r0.www; //to 1 + + r0.xyz = pow(r0.xyz, cb3[0].y); //global saturation + // only use white path in SDR! this is also disabled in original HDR + if (!HDR_ENABLED) { + r1.xyz = float3(1,1,1) + -r0.xyz; //SDR centric + r1.w = -cb3[0].w * cb3[1].x + r0.w; + r1.w = max(0, r1.w); + r1.w = cb3[0].z * r1.w; + r0.xyz = r1.www * r1.xyz + r0.xyz; + } + + r0.xyz = r0.xyz * r0.www; + + // clamp + r0.xyz = max(float3(0,0,0), r0.xyz); + if (!HDR_ENABLED) r0.xyz = min(cb3[1].xxx, r0.xyz); + + // Modded sRGB Encode + if (!HDR_ENABLED) { + r0.xyz = log2(r0.xyz); + r0.xyz = cb3[1].yyy * r0.xyz; //user settings + r1.xyz = float3(0.416666657,0.416666657,0.416666657) * r0.xyz; + r0.xyz = exp2(r0.xyz); + r1.xyz = exp2(r1.xyz); + r1.xyz = r1.xyz * float3(1.05499995,1.05499995,1.05499995) + float3(-0.0549999997,-0.0549999997,-0.0549999997); + r2.xyz = cmp(r0.xyz < float3(0.00313080009,0.00313080009,0.00313080009)); + r0.xyz = float3(12.9200001,12.9200001,12.9200001) * r0.xyz; + r0.xyz = r2.xyz ? r0.xyz : r1.xyz; + } + + o0.xyz = r0.xyz; + o0.w = 1; + return; +} + +// // ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:51 2026 +// Buffer t1 : register(t1); +// +// Texture2D t0 : register(t0); +// +// SamplerState s0_s : register(s0); +// +// cbuffer cb2 : register(b2) +// { +// float4 cb2[53]; +// } +// +// cbuffer cb3 : register(b3) +// { +// float4 cb3[4]; +// } +// +// // 3Dmigoto declarations +// #define cmp - +// #include "./common.hlsl" +// +// void main( +// float4 v0 : SV_POSITION0, +// float4 v1 : TEXCOORD0, +// float2 v2 : TEXCOORD1, +// uint v3 : SV_IsFrontFace0, +// out float4 o0 : SV_Target0) +// { +// float4 r0,r1,r2; +// uint4 bitmask, uiDest; +// float4 fDest; +// +// r0.xy = v1.xy / v1.ww; +// r0.xy = min(cb2[22].zw, r0.xy); +// r0.xyz = t0.Sample(s0_s, r0.xy).xyz; +// +// r1.xyz = (int3)r0.xyz & int3(0x7f800000,0x7f800000,0x7f800000); +// r1.xyz = cmp((int3)r1.xyz != int3(0x7f800000,0x7f800000,0x7f800000)); +// r0.xyz = r1.xyz ? r0.xyz : float3(65000,65000,65000); +// +// r0.xyz = pow(r0.xyz, cb3[0].x); //contrast +// r0.w = t1.Load(1).x; // inv peak +// r1.x = t1.Load(2).x; // inv exposure +// r1.xyz = r0.xyz * r0.www + r1.xxx; +// r1.xyz = max(float3(9.99999975e-006,9.99999975e-006,9.99999975e-006), r1.xyz); +// r0.xyz = r0.xyz / r1.xyz; +// +// r0.w = max(r0.y, r0.z); +// r0.w = max(r0.x, r0.w); +// r0.w = max(9.99999975e-006, r0.w); +// r0.xyz = r0.xyz / r0.www; +// r0.xyz = log2(r0.xyz); +// r0.xyz = cb3[0].yyy * r0.xyz; +// r0.xyz = exp2(r0.xyz); +// r1.xyz = float3(1,1,1) + -r0.xyz; +// r1.w = -cb3[0].w * cb3[1].x + r0.w; +// r1.w = max(0, r1.w); +// r1.w = cb3[0].z * r1.w; +// r0.xyz = r1.www * r1.xyz + r0.xyz; +// r0.xyz = r0.xyz * r0.www; +// +// r0.xyz = max(float3(0,0,0), r0.xyz); +// r0.xyz = min(cb3[1].xxx, r0.xyz); +// +// // sRGB Encode +// r0.xyz = log2(r0.xyz); +// r0.xyz = cb3[1].yyy * r0.xyz; //user settings +// r1.xyz = float3(0.416666657,0.416666657,0.416666657) * r0.xyz; +// r0.xyz = exp2(r0.xyz); +// r1.xyz = exp2(r1.xyz); +// r1.xyz = r1.xyz * float3(1.05499995,1.05499995,1.05499995) + float3(-0.0549999997,-0.0549999997,-0.0549999997); +// r2.xyz = cmp(r0.xyz < float3(0.00313080009,0.00313080009,0.00313080009)); +// r0.xyz = float3(12.9200001,12.9200001,12.9200001) * r0.xyz; +// r0.xyz = r2.xyz ? r0.xyz : r1.xyz; +// // o0.xyz = sRGB_Encode(r0.xyz); +// +// o0.xyz = r0.xyz; +// o0.w = 1; +// return; +// } diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index d9348b4c..f73129e3 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -4,206 +4,761 @@ #include "..\..\Core\core.hpp" -// TODO: Fix this globaly? Define NOMINMAX before including windows.h. -#undef min -#undef max - namespace { - const ShaderHashesList shader_hashes_linearize_depth_and_generate_mvs = { .compute_shaders = { 0x0E095BB1 }}; - const ShaderHashesList shader_hashes_TAA = { .pixel_shaders = { 0x8D06D556 }}; - - float g_jitter_x; - float g_jitter_y; + const ShaderHashesList shader_hashes_linearize_depth_and_generate_mvs = {.compute_shaders = {0x0E095BB1}}; + const ShaderHashesList shader_hashes_TAA = {.pixel_shaders = {0x8D06D556}}; + const ShaderHashesList shader_hashes_tonemap = {.pixel_shaders = {0xA4592384, 0xFD32C367}}; + const ShaderHashesList shader_hashes_photomode_exposure = {.pixel_shaders = {0xF4316866}}; + const ShaderHashesList shader_hashes_swapchain = {.pixel_shaders = {0x68EABB8D, 0x09C22C0E}}; + + // Jitter from TAA cb + float g_jitter_x; + float g_jitter_y; + + // User toggle for UI + bool is_ui = true; + + // Various settings for SR related + namespace SRUser + { + static bool copy_resource_def = false; + static bool copy_resource = copy_resource_def; + + static bool allow_upgraded_samplers_def = false; + static bool allow_upgraded_samplers = allow_upgraded_samplers_def; + + static void OnLoadConfigs(reshade::api::effect_runtime* runtime) + { + reshade::get_config_value(runtime, NAME, "copy_resource", copy_resource); + reshade::get_config_value(runtime, NAME, "allow_upgraded_samplers", allow_upgraded_samplers); + ignore_upgraded_samplers = !allow_upgraded_samplers; + } + } } struct GameDeviceDataMiddleEarthShadowOfWar final : GameDeviceData { + bool drawn_tonemap = false; + bool drawn_swapchain = false; + + void OnPresent() + { + drawn_tonemap = false; + drawn_swapchain = false; + } }; -class MiddleEarthShadowOfWar final : public Game +namespace DisplayMode { -public: - - static GameDeviceDataMiddleEarthShadowOfWar& GetGameDeviceData(DeviceData& device_data) - { - return *(GameDeviceDataMiddleEarthShadowOfWar*)device_data.game; - } - - void OnLoad(std::filesystem::path& file_path, bool failed = false) override - { - reshade::register_event(OnUpdateBufferRegion); - } - - void OnInit(bool async) override - { - // ### Update these (find the right values) ### - // ### See the "GameCBuffers.hlsl" in the shader directory to expand settings ### - luma_settings_cbuffer_index = 13; - luma_data_cbuffer_index = 12; - } - - static bool OnUpdateBufferRegion(reshade::api::device* device, const void* data, reshade::api::resource resource, uint64_t offset, uint64_t size) - { - auto native_resource = (ID3D11Resource*)resource.handle; - ComPtr buffer; - auto hr = native_resource->QueryInterface(buffer.put()); - if (SUCCEEDED(hr)) { - D3D11_BUFFER_DESC desc; - buffer->GetDesc(&desc); - - // This alone should be reliable? Needs testing! - if (desc.BindFlags == D3D11_BIND_CONSTANT_BUFFER && desc.ByteWidth == 544) { - // cb0[31].xy in PS TAA 0x8D06D556. - g_jitter_x = ((float4*)data)[31].x; - g_jitter_y = ((float4*)data)[31].y; + static bool IsHDR() { return cb_luma_global_settings.DisplayMode == DisplayModeType::HDR; } + + static bool is_first = true; + constexpr auto flag_file = "Luma_AlwaysHDRLaunch"; + + // Stolen from core + void ChangeDisplayModeHDR(reshade::api::effect_runtime* runtime, bool enable_hdr_on_display = true, IDXGISwapChain3* swapchain = nullptr) + { + DisplayModeType display_mode = DisplayModeType::HDR; + int display_mode_i = int(DisplayModeType::HDR); + reshade::set_config_value(runtime, NAME, "DisplayMode", display_mode_i); + cb_luma_global_settings.DisplayMode = display_mode; + OnDisplayModeChanged(); + if (display_mode >= DisplayModeType::HDR) + { + if (enable_hdr_on_display) + { + Display::SetHDREnabled(game_window); + bool dummy_bool; + Display::IsHDRSupportedAndEnabled(game_window, dummy_bool, hdr_enabled_display, swapchain); + } + if (!reshade::get_config_value(runtime, NAME, "ScenePeakWhite", cb_luma_global_settings.ScenePeakWhite) || cb_luma_global_settings.ScenePeakWhite <= 0.f) + { + cb_luma_global_settings.ScenePeakWhite = default_paper_white; + } + + if (use_os_reference_white_level) + { + float hdr_paper_white = 80.f; + if (Display::GetSDRWhiteLevel(0, hdr_paper_white)) + { + cb_luma_global_settings.ScenePaperWhite = hdr_paper_white; + cb_luma_global_settings.UIPaperWhite = hdr_paper_white; } - } - return false; - } - - DrawOrDispatchOverrideType OnDrawOrDispatch(ID3D11Device* native_device, ID3D11DeviceContext* native_device_context, CommandListData& cmd_list_data, DeviceData& device_data, reshade::api::shader_stage stages, const ShaderHashesList& original_shader_hashes, bool is_custom_pass, bool& updated_cbuffers, std::function* original_draw_dispatch_func) override - { - auto& game_device_data = GetGameDeviceData(device_data); - auto& managed_resources = game_device_data.managed_resources; - - if (original_shader_hashes.Contains(shader_hashes_linearize_depth_and_generate_mvs)) - { - ComPtr srv; - native_device_context->CSGetShaderResources(1, 1, srv.put()); - srv->GetResource(managed_resources.resources["depth"_h].put()); - return DrawOrDispatchOverrideType::None; - } - - if (original_shader_hashes.Contains(shader_hashes_TAA)) - { - if (device_data.sr_type != SR::Type::None) + else { - // DLSS requires an immediate context for execution! - ASSERT_ONCE(native_device_context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - - auto* sr_instance_data = device_data.GetSRInstanceData(); - ASSERT_ONCE(sr_instance_data); - - SR::SettingsData settings_data; - settings_data.output_width = device_data.output_resolution.x; - settings_data.output_height = device_data.output_resolution.y; - settings_data.render_width = device_data.render_resolution.x; - settings_data.render_height = device_data.render_resolution.y; - settings_data.dynamic_resolution = false; - settings_data.hdr = true; - settings_data.inverted_depth = true; - settings_data.mvs_jittered = false; - - // MVs are in UV space so we need to scale them to screen space for DLSS. - settings_data.mvs_x_scale = -device_data.render_resolution.x; - settings_data.mvs_y_scale = -device_data.render_resolution.y; - - settings_data.render_preset = dlss_render_preset; - settings_data.auto_exposure = true; - - sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); - - std::array srvs; - native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); - - ComPtr resource_mvs; - srvs[0]->GetResource(resource_mvs.put()); - ComPtr resource_scene; - srvs[1]->GetResource(resource_scene.put()); - - ComPtr rtv; - native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); - ComPtr resource_rt; - rtv->GetResource(resource_rt.put()); - - SR::SuperResolutionImpl::DrawData draw_data; - draw_data.source_color = resource_scene.get(); - draw_data.output_color = resource_rt.get(); - draw_data.motion_vectors = resource_mvs.get(); - draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); - - // Jitters are in range [-1, 1]. - draw_data.jitter_x = g_jitter_x * -0.5f; - draw_data.jitter_y = g_jitter_y * 0.5f; - - draw_data.render_width = device_data.render_resolution.x; - draw_data.render_height = device_data.render_resolution.y; - - sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); - - ResetCOMArray(srvs); - - return DrawOrDispatchOverrideType::Replaced; + use_os_reference_white_level = false; } - return DrawOrDispatchOverrideType::None; - } - - return DrawOrDispatchOverrideType::None; - } - - void OnPresent(ID3D11Device* native_device, DeviceData& device_data) override - { - auto& game_device_data = GetGameDeviceData(device_data); - - if (!custom_texture_mip_lod_bias_offset) - { - std::shared_lock shared_lock_samplers(s_mutex_samplers); - if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed) + } + else + { + if (!reshade::get_config_value(runtime, NAME, "ScenePaperWhite", cb_luma_global_settings.ScenePaperWhite)) { - device_data.texture_mip_lod_bias_offset = SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); // This results in -1 at output res + cb_luma_global_settings.ScenePaperWhite = default_paper_white; } - else + if (!reshade::get_config_value(runtime, NAME, "UIPaperWhite", cb_luma_global_settings.UIPaperWhite)) { - device_data.texture_mip_lod_bias_offset = 0.0f; + cb_luma_global_settings.UIPaperWhite = default_paper_white; } - } - } + } + } + }; + + static void OnInitSwapchain(reshade::api::swapchain* swapchain) + { + // gatekeep: is_first + if (!is_first) return; + is_first = false; + + // If is HDR, tell user, force, and exit. + bool has_file = std::filesystem::exists(flag_file); + bool enabled; + bool supported; + Display::IsHDRSupportedAndEnabled(game_window, supported, enabled); + if (enabled) + { + // inform user + if (!has_file) MessageBoxA(game_window, "For proper HDR upgrades, we need the game to launch in SDR mode.\n\nLuma will try to disable Windows HDR and relaunch.\nThis will become automated if successful.", "Relaunch Required", MB_OK | MB_ICONINFORMATION); + + // disable HDR + if (Display::SetHDREnabled(game_window, false)) + { + MessageBoxA(game_window, "Failed to disable Windows HDR.\n\nPlease disable it manually and relaunch the game.", "HDR Disable Failed", MB_OK | MB_ICONERROR); + std::exit(1); + } + + // start new process + { + // ModuleFileName + char exe_path[MAX_PATH]; + GetModuleFileNameA(NULL, exe_path, MAX_PATH); + + // start + STARTUPINFOA si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (!CreateProcessA(exe_path, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) + { + MessageBoxA(game_window, "Failed to relaunch the game in SDR mode.\n\nPlease relaunch manually.", "Relaunch Failed", MB_OK | MB_ICONERROR); + std::exit(1); + } + } + + // create flag file + if (!has_file) + { + std::ofstream stream(flag_file); + stream.close(); + } + + std::exit(0); //exit + } + else + { + ChangeDisplayModeHDR(nullptr); + } + + + is_first = false; + } +} + +namespace CB +{ + static void OnInit() + { + // Set Defaults + default_luma_global_game_settings.WhiteClip = cb_luma_global_settings.GameSettings.WhiteClip = 1.; + default_luma_global_game_settings.BlowoutCorrection = cb_luma_global_settings.GameSettings.BlowoutCorrection = 0.3; + default_luma_global_game_settings.GodRays = cb_luma_global_settings.GameSettings.GodRays = 1.; + default_luma_global_game_settings.Bloom = cb_luma_global_settings.GameSettings.Bloom = 1.; + default_luma_global_game_settings.RCAS = cb_luma_global_settings.GameSettings.RCAS = 0.; + } + + static void OnLoadConfigs(reshade::api::effect_runtime* runtime) + { + // Load configs + reshade::get_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); + reshade::get_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); + reshade::get_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); + reshade::get_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); + reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); + } +} + +// Helpers to change Shader Defines by UI +namespace ShaderDefineInfo +{ + constexpr uint32_t GAMMA_CORRECT_CUSTOM = char_ptr_crc32("GAMMA_CORRECT_CUSTOM"); + constexpr uint32_t TEST_USER_PEAK = char_ptr_crc32("TEST_USER_PEAK"); + constexpr uint32_t FIRE_RETUNED = char_ptr_crc32("FIRE_RETUNED"); + constexpr uint32_t RCAS_ENABLED = char_ptr_crc32("RCAS_ENABLED"); + + void OnInit() + { + // New + static const std::vector game_shader_defines_data = { + {"GAMMA_CORRECTION_RANGE_TYPE", '0', true, !DEVELOPMENT, "0 - Full range.\n1 - 0-1 only.", 1}, + {"TEST_USER_PEAK", '0', true, false, "Show white rectangles for peak test.", 1}, + {"GAMMA_CORRECT_CUSTOM", '1', true, false, "Correct gamma decode, lowering shadows to match SDR.", 1}, + {"FIRE_RETUNED", '1', true, false, "Retuned fire shader to reduce clipping.", 1}, + {"RCAS_ENABLED", '0', true, false, "Robust Contrast Adaptive Sharpening.", 1}, + }; + shader_defines_data.append_range(game_shader_defines_data); + + // Change defaults + GetShaderDefineData(POST_PROCESS_SPACE_TYPE_HASH).SetDefaultValue('1'); // linear + GetShaderDefineData(GAMMA_CORRECTION_TYPE_HASH).SetDefaultValue('0'); // don't use built in gamma correction + GetShaderDefineData(UI_DRAW_TYPE_HASH).SetDefaultValue('2'); // Direct (inverse scene brightness draws) + + // Force + auto_recompile_defines = true; + } + + static char InvertCharBool(char b) + { + return b == '0' ? '1' : '0'; + } + + static int Get(uint32_t p) + { + auto* d = &GetShaderDefineData(p); + return d->editable_data.value[0] - '0'; + } + + static bool GetBool(uint32_t p) + { + return Get(p) > 0; + } + + static void Set(uint32_t p, char c) + { + auto* d = &GetShaderDefineData(p); + if (d->editable_data.value[0] == c) return; + d->SetValue(c); + defines_need_recompilation = true; + } + + static void Set(uint32_t p, int i) + { + auto* d = &GetShaderDefineData(p); + char c = static_cast(i + '0'); + Set(p, c); + } + + static void Set(uint32_t p, bool b) + { + int i = b ? 1 : 0; + Set(p, i); + } + + static void ToggleBool(uint32_t p) + { + auto* d = &GetShaderDefineData(p); + d->SetValue(InvertCharBool(d->editable_data.value[0])); + defines_need_recompilation = true; + } + + static void UIResetButton(uint32_t p) + { + auto* d = &GetShaderDefineData(p); + if (d->editable_data.value[0] != d->default_data.value[0]) { + int id = static_cast(reinterpret_cast(d)); + ImGui::PushID(id); + ImGui::SameLine(); + if (ImGui::SmallButton(ICON_FK_UNDO)) + { + d->Reset(); + defines_need_recompilation = true; + } + ImGui::PopID(); + } + } + + static bool UIToggleCheckmark(uint32_t d, const char* label, const char* tooltip) + { + bool def = GetBool(d); + + ImGui::PushID(std::string(label).append("_").append(std::to_string(d)).c_str()); + bool c = ImGui::Checkbox(label, &def); + ImGui::PopID(); + + if (tooltip && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip(tooltip); + + if (c) ToggleBool(d); + + UIResetButton(d); + return def; + } + + static int UIDropDown(uint32_t d, const char* label, const char* const items[], const char* tooltip) + { + int def = Get(d); + bool c = ImGui::Combo(label, &def, items, IM_ARRAYSIZE(items)); + if (c) Set(d, def); + if (tooltip && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip(tooltip); + UIResetButton(d); + return def; + } + + static int UIDropDown(uint32_t d, const char* label, std::initializer_list items_list, const char* tooltip) + { + std::vector items(items_list); + int def = Get(d); + ImGui::PushID(std::string(label).append("_").append(std::to_string(d)).c_str()); + bool c = ImGui::Combo(label, &def, items.data(), static_cast(items.size())); + ImGui::PopID(); + if (c) Set(d, def); + if (tooltip && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip(tooltip); + UIResetButton(d); + return def; + } +} + +namespace Website +{ + void OpenWebsite(const char* url) { +#if defined(_WIN32) || defined(_WIN64) + std::string command = "start " + std::string(url); + std::system(command.c_str()); +#elif defined(__linux__) + std::string command = "xdg-open " + std::string(url); + std::system(command.c_str()); +#elif defined(__APPLE__) + std::string command = "open " + std::string(url); + std::system(command.c_str()); +#endif + } +} - void PrintImGuiAbout() override - { - ImGui::Text("Middle-earth: Shadow of War Luma mod - about and credits section", ""); - } +class MiddleEarthShadowOfWar final : public Game +{ +public: + static GameDeviceDataMiddleEarthShadowOfWar& GetGameDeviceData(DeviceData& device_data) + { + return *(GameDeviceDataMiddleEarthShadowOfWar*)device_data.game; + } + + void OnLoad(std::filesystem::path& file_path, bool failed = false) override + { + // log + message(reshade::log::level::info, "OnLoad()"); + + reshade::register_event(OnUpdateBufferRegion); + } + + void OnInit(bool async) override + { + // log + message(reshade::log::level::info, "OnInit()"); + + // Shader Defines + ShaderDefineInfo::OnInit(); + + // CB + CB::OnInit(); + + // UI Buffer Indirect Upgrades + { + // Add many, since Alt-Tabbing (swapchain recreates) will clear upgrades. + auto_texture_format_upgrade_shader_hashes[0x3D829665] = std::pair{std::vector{0}, std::vector()}; // ui base + auto_texture_format_upgrade_shader_hashes[0x61BC2E86] = std::pair{std::vector{0}, std::vector()}; // ui glow + auto_texture_format_upgrade_shader_hashes[0xE6453EB0] = std::pair{std::vector{0}, std::vector()}; // ui idk... + auto_texture_format_upgrade_shader_hashes[0x34A2050F] = std::pair{std::vector{0}, std::vector()}; // ui trans + auto_texture_format_upgrade_shader_hashes[0x9BA33763] = std::pair{std::vector{0}, std::vector()}; // ui text + auto_texture_format_upgrade_shader_hashes[0xB2EAAA62] = std::pair{std::vector{0}, std::vector()}; // ui mov + + auto_texture_format_upgrade_shader_hashes[0xFD32C367] = std::pair{std::vector{0}, std::vector()}; // tonemap SDR + } + + // cb + luma_settings_cbuffer_index = 13; + luma_data_cbuffer_index = 12; + } + + void OnInitSwapchain(reshade::api::swapchain* swapchain) + { + // DisplayMode + DisplayMode::OnInitSwapchain(swapchain); + } + + static bool OnUpdateBufferRegion(reshade::api::device* device, const void* data, reshade::api::resource resource, uint64_t offset, uint64_t size) + { + // Find TAA jitter offset + auto native_resource = (ID3D11Resource*)resource.handle; + ComPtr buffer; + auto hr = native_resource->QueryInterface(buffer.put()); + if (SUCCEEDED(hr)) + { + D3D11_BUFFER_DESC desc; + buffer->GetDesc(&desc); + + // This alone should be reliable? Needs testing! + if (desc.BindFlags == D3D11_BIND_CONSTANT_BUFFER && desc.ByteWidth == 544) + { + // cb0[31].xy in PS TAA 0x8D06D556. + g_jitter_x = ((float4*)data)[31].x; + g_jitter_y = ((float4*)data)[31].y; + } + } + return false; + } + + DrawOrDispatchOverrideType OnDrawOrDispatch(ID3D11Device* native_device, ID3D11DeviceContext* native_device_context, CommandListData& cmd_list_data, DeviceData& device_data, reshade::api::shader_stage stages, const ShaderHashesList& original_shader_hashes, bool is_custom_pass, bool& updated_cbuffers, std::function* original_draw_dispatch_func) override + { + auto& game_device_data = GetGameDeviceData(device_data); + auto& managed_resources = game_device_data.managed_resources; + + // Motion Vectors + if (original_shader_hashes.Contains(shader_hashes_linearize_depth_and_generate_mvs)) + { + // Take depth + ComPtr srv; + native_device_context->CSGetShaderResources(1, 1, srv.put()); + srv->GetResource(managed_resources.resources["depth"_h].put()); + return DrawOrDispatchOverrideType::None; + } + + // TAA + if (original_shader_hashes.Contains(shader_hashes_TAA)) + { + if (device_data.sr_type != SR::Type::None) + { + // DLSS requires an immediate context for execution! + ASSERT_ONCE(native_device_context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); + + // Settings + auto* sr_instance_data = device_data.GetSRInstanceData(); + ASSERT_ONCE(sr_instance_data); + + SR::SettingsData settings_data; + settings_data.output_width = device_data.output_resolution.x; + settings_data.output_height = device_data.output_resolution.y; + settings_data.render_width = device_data.render_resolution.x; + settings_data.render_height = device_data.render_resolution.y; + settings_data.dynamic_resolution = false; + settings_data.hdr = true; + settings_data.inverted_depth = true; + settings_data.mvs_jittered = false; + + // MVs are in UV space so we need to scale them to screen space for DLSS. + settings_data.mvs_x_scale = -device_data.render_resolution.x; + settings_data.mvs_y_scale = -device_data.render_resolution.y; + + settings_data.render_preset = dlss_render_preset; + settings_data.auto_exposure = true; + + sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); + + // Get resources + std::array srvs; + native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); + + ComPtr resource_mvs; + srvs[0]->GetResource(resource_mvs.put()); + ComPtr resource_scene; + srvs[1]->GetResource(resource_scene.put()); + + ComPtr rtv; + native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); + ComPtr resource_rt; + rtv->GetResource(resource_rt.put()); + + SR::SuperResolutionImpl::DrawData draw_data; + draw_data.source_color = resource_scene.get(); + draw_data.output_color = resource_rt.get(); + draw_data.motion_vectors = resource_mvs.get(); + draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); + + // Jitters are in range [-1, 1]. + draw_data.jitter_x = g_jitter_x * -0.5f; + draw_data.jitter_y = g_jitter_y * 0.5f; + + draw_data.render_width = device_data.render_resolution.x; + draw_data.render_height = device_data.render_resolution.y; + + // DRAW + device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); + + // Copy back to input, fixing missing transparency FXs. + if (SRUser::copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); + + // Reset pointers + ResetCOMArray(srvs); + + return DrawOrDispatchOverrideType::Replaced; + } + return DrawOrDispatchOverrideType::None; + } + + // Tonemap + if (original_shader_hashes.Contains(shader_hashes_tonemap)) + { + game_device_data.drawn_tonemap = true; + return DrawOrDispatchOverrideType::None; + } + + // Swapchain / UI Combine + if (original_shader_hashes.Contains(shader_hashes_swapchain)) + { + game_device_data.drawn_swapchain = true; + return DrawOrDispatchOverrideType::None; + } + + // User UI toggle + if (!is_ui && game_device_data.drawn_tonemap && !game_device_data.drawn_swapchain) + { + return DrawOrDispatchOverrideType::Skip; + } + + return DrawOrDispatchOverrideType::None; + } + + void OnPresent(ID3D11Device* native_device, DeviceData& device_data) override + { + auto& game_device_data = GetGameDeviceData(device_data); + + // game_device_data + game_device_data.OnPresent(); + + // // DetectPhotoMode + // DetectPhotoMode::OnPresent(); + + // force_reset_sr + if (!device_data.has_drawn_sr) device_data.force_reset_sr = true; + + // texture_mip_lod_bias_offset + if (!custom_texture_mip_lod_bias_offset) + { + std::shared_lock shared_lock_samplers(s_mutex_samplers); + if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !SRUser::allow_upgraded_samplers) + { + device_data.texture_mip_lod_bias_offset = SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); // This results in -1 at output res + } + else + { + device_data.texture_mip_lod_bias_offset = 0.0f; + } + } + } + + void LoadConfigs() override + { + message(reshade::log::level::info, "LoadConfigs()"); + reshade::api::effect_runtime* runtime = nullptr; + + // CB + CB::OnLoadConfigs(runtime); + + // SRUser + SRUser::OnLoadConfigs(runtime); + } + + void DrawImGuiSettings(DeviceData& device_data) override + { + reshade::api::effect_runtime* runtime = nullptr; + + ImGui::Separator(); //////////////////////////////////////////////////////////////////////////// + + // SECTION: Gamma Correction + if (DisplayMode::IsHDR() && ImGui::CollapsingHeader("Gamma Correction")) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Windows' gamma decode in HDR is weaker than in SDR, causing washed out shadows.]"); + ImGui::PopStyleColor(); + + ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::GAMMA_CORRECT_CUSTOM, "Enable Correction", "sRGB -> 2.2"); + + if (ImGui::Button("Further Explanation & Test (Google Slides)")) + Website::OpenWebsite("https://docs.google.com/presentation/d/e/2PACX-1vSXeLHlbm6repcS7fels1-SXYGRmzziRrnuJ8nDO8J5rsWV3dT1-nVyCKp0Tj_stwx-9qlCI-N6rYIT/pub?start=false&loop=false&slide=id.g3e007eafba8_0_0"); + } + + // SECTION: Peak Brightness + if (DisplayMode::IsHDR() && ImGui::CollapsingHeader("Peak Brightness")) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Don't Exceed Display Maximum!]"); + ImGui::PopStyleColor(); + + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("(Use default Luma sliders above.)"); + ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::TEST_USER_PEAK, "Test Pattern (Read Tooltip)", "3 rectangles inside a big one.\n- Left should disappear.\n- Middle should be barely visible.\n- Right should be easy to see."); + + ImGui::NewLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Extended Highlights Customization]"); + ImGui::PopStyleColor(); + + ImGui::PushID("Peak Brightness: WhiteClip"); + if (ImGui::SliderFloat("Clip", &cb_luma_global_settings.GameSettings.WhiteClip, 0.f, 4.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Increase to make rolloff compression straighter, where the highlights becomes more clipped."); + DrawResetButton(cb_luma_global_settings.GameSettings.WhiteClip, default_luma_global_game_settings.WhiteClip, "WhiteClip", runtime); + + ImGui::PushID("Peak Brightness: BlowoutCorrection"); + if (ImGui::SliderFloat("Blowout Correction", &cb_luma_global_settings.GameSettings.BlowoutCorrection, 0.f, 0.8f, "%.3f")) + reshade::set_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Correct the hues of new highlights using the results from SDR.\nToo high will look unnatural."); + DrawResetButton(cb_luma_global_settings.GameSettings.BlowoutCorrection, default_luma_global_game_settings.BlowoutCorrection, "BlowoutCorrection", runtime); + + } + + // SECTION: SR + ImGui::PushID("Super Resolution Header Tab"); //conflicts if not pushed + bool show_sr_settings = ImGui::CollapsingHeader("Super Resolution"); + ImGui::PopID(); + if (show_sr_settings) + { + if (device_data.sr_type == SR::Type::None) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.f)); + ImGui::TextWrapped("Inactive..."); + ImGui::PopStyleColor(); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[In-game Graphics Settings]"); + ImGui::PopStyleColor(); + + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Unfortunately, only 100%% internal/render resolution is supported."); + + ImGui::NewLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Bloom & Other FX Missing Fix]"); + ImGui::PopStyleColor(); + + ImGui::PushID("SR: copy_resource"); + if (ImGui::Checkbox("Copy Resource Fix", &SRUser::copy_resource)) + reshade::set_config_value(runtime, NAME, "copy_resource", SRUser::copy_resource); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("If Bloom and other transparency are missing, enable this."); + DrawResetButton(SRUser::copy_resource, SRUser::copy_resource_def, "copy_resource", runtime); + } + + ImGui::NewLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Higher Quality Textures Sampling]"); + ImGui::PopStyleColor(); + + ImGui::PushID("SR: allow_upgraded_samplers"); + if (ImGui::Checkbox("Allow Sampler Upgrades (Read Tooltip)", &SRUser::allow_upgraded_samplers)) + { + reshade::set_config_value(runtime, NAME, "allow_upgraded_samplers", SRUser::allow_upgraded_samplers); + ignore_upgraded_samplers = !SRUser::allow_upgraded_samplers; + } + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance. Unnoticeable?\nMay change more than just texture detail.\nWill costs some performance."); + DrawResetButton(SRUser::allow_upgraded_samplers, SRUser::allow_upgraded_samplers_def, "allow_upgraded_samplers", runtime); + } + + // SECTION: Miscellaneous + if (ImGui::CollapsingHeader("Miscellaneous")) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Various FX sliders & toggles.]"); + ImGui::PopStyleColor(); + + if (ImGui::SliderFloat("GodRays", &cb_luma_global_settings.GameSettings.GodRays, 0.f, 2.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Final god rays multiplier."); + DrawResetButton(cb_luma_global_settings.GameSettings.GodRays, default_luma_global_game_settings.GodRays, "GodRays", runtime); + + ImGui::PushID("Miscellaneous: Bloom"); + if (ImGui::SliderFloat("Bloom", &cb_luma_global_settings.GameSettings.Bloom, 0.f, 2.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Final bloom multiplier."); + DrawResetButton(cb_luma_global_settings.GameSettings.Bloom, default_luma_global_game_settings.Bloom, "Bloom", runtime); + + ImGui::PushID("Miscellaneous: RCAS"); + if (ImGui::SliderFloat("RCAS", &cb_luma_global_settings.GameSettings.RCAS, 0.f, 1.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Robust Contrast Adaptive Sharpening on scene color."); + DrawResetButton(cb_luma_global_settings.GameSettings.RCAS, default_luma_global_game_settings.RCAS, "RCAS", runtime); + ShaderDefineInfo::Set(ShaderDefineInfo::RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh + + // TODO: AO + + ImGui::PushID("Miscellaneous: UIToggle is_allowed"); + ImGui::Checkbox("UI", &is_ui); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Can skip drawing the UI (everything after tonemap shader)."); + ImGui::PopID(); + } + + // SECTION: Retuned Fire + if (ImGui::CollapsingHeader("Retuned Fire")) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Alleviates clipping for fire texture sprites.]"); + ImGui::PopStyleColor(); + + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("This changes its style, becoming more lava-ish orange."); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("If off, shaders will intentionally break, so just ignore the warning. Thanks!"); + + ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); + } + + if (DEVELOPMENT) ImGui::Separator(); //////////////////////////////////////////////////////////////////////////// + } + + void PrintImGuiAbout() override + { + ImGui::Text("Build Date:"); + ImGui::Text(__DATE__); + ImGui::Text(__TIME__); + ImGui::NewLine(); + + ImGui::Text("Middle-earth: Shadow of War Luma mod - about and credits section", ""); + } + + void OnDisplayModeChanged() + { + // FORCED: Gamma Correct + ShaderDefineInfo::Set(ShaderDefineInfo::GAMMA_CORRECT_CUSTOM, DisplayMode::IsHDR()); + } }; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - if (ul_reason_for_call == DLL_PROCESS_ATTACH) - { - Globals::SetGlobals(PROJECT_NAME, "Middle-earth: Shadow of War Luma mod"); - Globals::VERSION = 1; - - swapchain_format_upgrade_type = TextureFormatUpgradesType::AllowedEnabled; - swapchain_upgrade_type = SwapchainUpgradeType::scRGB; - texture_format_upgrades_type = TextureFormatUpgradesType::AllowedEnabled; - // ### Check which of these are needed and remove the rest ### - texture_upgrade_formats = { - //reshade::api::format::r8g8b8a8_unorm, - //reshade::api::format::r8g8b8a8_unorm_srgb, - //reshade::api::format::r8g8b8a8_typeless, - //reshade::api::format::r8g8b8x8_unorm, - //reshade::api::format::r8g8b8x8_unorm_srgb, - //reshade::api::format::b8g8r8a8_unorm, - //reshade::api::format::b8g8r8a8_unorm_srgb, - //reshade::api::format::b8g8r8a8_typeless, - //reshade::api::format::b8g8r8x8_unorm, - //reshade::api::format::b8g8r8x8_unorm_srgb, - //reshade::api::format::b8g8r8x8_typeless, - // - //reshade::api::format::r11g11b10_float, - }; - // ### Check these if textures are not upgraded ### - texture_format_upgrades_2d_size_filters = 0 | (uint32_t)TextureFormatUpgrades2DSizeFilters::SwapchainResolution | (uint32_t)TextureFormatUpgrades2DSizeFilters::SwapchainAspectRatio; - - enable_samplers_upgrade = true; - - // TODO: Remove this later! - Globals::DEVELOPMENT_STATE = Globals::ModDevelopmentState::WorkInProgress; - - game = new MiddleEarthShadowOfWar(); - } - - CoreMain(hModule, ul_reason_for_call, lpReserved); - - return TRUE; + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + // Globals + Globals::SetGlobals(PROJECT_NAME, "Middle-earth: Shadow of War Luma mod"); + Globals::VERSION = 1; + + // Swapchain upgrades + swapchain_format_upgrade_type = TextureFormatUpgradesType::AllowedEnabled; + swapchain_upgrade_type = SwapchainUpgradeType::scRGB; + + // Resource upgrades + texture_format_upgrades_type = TextureFormatUpgradesType::AllowedEnabled; + enable_chain_indirect_texture_format_upgrades = ChainTextureFormatUpgradesType::DirectDependencies; + + // SR + enable_samplers_upgrade = true; + + game = new MiddleEarthShadowOfWar(); + } + + CoreMain(hModule, ul_reason_for_call, lpReserved); + + return TRUE; } \ No newline at end of file From c25ff947e0082c925220771e2af22c0ded9ceacc Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 19:33:31 -0700 Subject: [PATCH 02/33] Shadow of War: Include everything and GameCBuffers --- .../Middle-earth Shadow of War.vcxproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj b/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj index 405663e1..de0d6e62 100644 --- a/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj +++ b/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj @@ -180,7 +180,7 @@ - ..\..\External\reshade;..\..\External\NGX;%(AdditionalIncludeDirectories) + ..\..\External\reshade;..\..\External\DKUtil;..\..\External\FidelityFX;..\..\External\NGX;..\..\External\NVAPI;..\..\External\WDK;%(AdditionalIncludeDirectories) EnableFastChecks ProgramDatabase Sync @@ -197,7 +197,7 @@ true true stdclatest - %(ForcedIncludeFiles) + ../../../Shaders/$(ProjectName)/Includes/GameCBuffers.hlsl;%(ForcedIncludeFiles) %(PreprocessorDefinitions);_DEBUG;_WINDOWS @@ -284,7 +284,7 @@ - ..\..\External\reshade;..\..\External\NGX;%(AdditionalIncludeDirectories) + ..\..\External\reshade;..\..\External\DKUtil;..\..\External\FidelityFX;..\..\External\NGX;..\..\External\NVAPI;..\..\External\WDK;%(AdditionalIncludeDirectories) Sync Default stdcpplatest @@ -299,7 +299,7 @@ true true stdclatest - %(ForcedIncludeFiles) + ../../../Shaders/$(ProjectName)/Includes/GameCBuffers.hlsl;%(ForcedIncludeFiles) %(PreprocessorDefinitions);_WINDOWS;NDEBUG @@ -331,7 +331,7 @@ - ..\..\External\reshade;..\..\External\NGX;%(AdditionalIncludeDirectories) + ..\..\External\reshade;..\..\External\DKUtil;..\..\External\FidelityFX;..\..\External\NGX;..\..\External\NVAPI;..\..\External\WDK;%(AdditionalIncludeDirectories) Sync Default stdcpplatest @@ -346,7 +346,7 @@ true true stdclatest - %(ForcedIncludeFiles) + ../../../Shaders/$(ProjectName)/Includes/GameCBuffers.hlsl;%(ForcedIncludeFiles) %(PreprocessorDefinitions);_WINDOWS;NDEBUG @@ -378,7 +378,7 @@ - ..\..\External\reshade;..\..\External\NGX;%(AdditionalIncludeDirectories) + ..\..\External\reshade;..\..\External\DKUtil;..\..\External\FidelityFX;..\..\External\NGX;..\..\External\NVAPI;..\..\External\WDK;%(AdditionalIncludeDirectories) Sync Default stdcpplatest @@ -393,7 +393,7 @@ true true stdclatest - %(ForcedIncludeFiles) + ../../../Shaders/$(ProjectName)/Includes/GameCBuffers.hlsl;%(ForcedIncludeFiles) %(PreprocessorDefinitions);_WINDOWS;NDEBUG From 289fac077d54b5fbc514bba326b3625125e74b91 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 19:52:30 -0700 Subject: [PATCH 03/33] Shadow of War: Del unused shaders --- .../Includes/HermiteSpline_portable.hlsl | 163 ------------------ 1 file changed, 163 deletions(-) delete mode 100644 Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl diff --git a/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl b/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl deleted file mode 100644 index 1059254a..00000000 --- a/Shaders/Middle-earth Shadow of War/Includes/HermiteSpline_portable.hlsl +++ /dev/null @@ -1,163 +0,0 @@ -//https://github.com/clshortfuse/renodx/blob/main/src/shaders/tonemap/hermite_spline.hlsl -#include "../Includes/Color.hlsl" - -namespace pq { - static const float M1 = 2610.f / 16384.f; // 0.1593017578125f; - static const float M2 = 128.f * (2523.f / 4096.f); // 78.84375f; - static const float C1 = 3424.f / 4096.f; // 0.8359375f; - static const float C2 = 32.f * (2413.f / 4096.f); // 18.8515625f; - static const float C3 = 32.f * (2392.f / 4096.f); // 18.6875f; - - float Encode(float color, float scaling = 10000.f) { - color *= (scaling / 10000.f); - float y_m1 = pow(color, M1); - return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); - } - - float3 Encode(float3 color, float scaling = 10000.f) { - color *= (scaling / 10000.f); - float3 y_m1 = pow(color, M1); - return pow((C1 + C2 * y_m1) / (1.f + C3 * y_m1), M2); - } - - float Decode(float color, float scaling = 10000.f) { - float e_m12 = pow(color, 1.f / M2); - float out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); - return out_color * (10000.f / scaling); - } - - float3 Decode(float3 color, float scaling = 10000.f) { - float3 e_m12 = pow(color, 1.f / M2); - float3 out_color = pow(max(0, e_m12 - C1) / (C2 - C3 * e_m12), 1.f / M1); - return out_color * (10000.f / scaling); - } - - float3 EncodeSafe(float3 color, float scaling = 10000.f) { - return Encode(max(0, color), scaling); - } - - float3 DecodeSafe(float3 color, float scaling = 10000.f) { - return Decode(max(0, color), scaling); - } -} - -float Rescale(float x, float x_min, float x_max, float y_min = 0, float y_max = 1, bool clamp = false) { - float value = lerp(y_min, y_max, (x - x_min) / (x_max - x_min)); - if (clamp) value = saturate(value); - return value; -} - -float HermiteSplineRolloff(float input, float target_white = 1.f, float max_white = 20.f) { - float l_w = max_white; - float l_max = target_white; - float e_1 = Rescale(input, 0, l_w); - float max_lum = Rescale(l_max, 0, l_w); - float knee_start = 1.5f * max_lum - 0.5f; - float t_b = Rescale(e_1, knee_start, 1.f); - float t_b_squared = t_b * t_b; - float t_b_cubed = t_b_squared * t_b; - float two_t_b_cubed = 2.f * t_b_cubed; - float three_t_b_squared = 3.f * t_b_squared; - float p_e1_h00 = (two_t_b_cubed - three_t_b_squared + 1.f); - float p_e1_h10 = (t_b_cubed - 2.f * t_b_squared + t_b); - float p_e1_h01 = (-two_t_b_cubed + three_t_b_squared); - float p_e1 = p_e1_h00 * knee_start - + p_e1_h10 * (1.f - knee_start) - + p_e1_h01 * max_lum; - float e_2 = (e_1 < knee_start) ? e_1 : p_e1; - float e_3 = e_2; - float e_4 = l_w * e_3; - return min(e_4, target_white); -} -float HermiteSplineRolloff( - float input, - float target_white, - float max_white, - float target_black, - float min_black = 0.f) { - float l_w = max_white; - float l_b = min_black; - float l_min = target_black; - float l_max = target_white; - float e_1 = Rescale(input, l_b, l_w); - float min_lum = Rescale(l_min, l_b, l_w); - float max_lum = Rescale(l_max, l_b, l_w); - float knee_start = 1.5f * max_lum - 0.5f; - float b = min_lum; - float t_b = Rescale(e_1, knee_start, 1.f); - float t_b_squared = t_b * t_b; - float t_b_cubed = t_b_squared * t_b; - float two_t_b_cubed = 2.f * t_b_cubed; - float three_t_b_squared = 3.f * t_b_squared; - float p_e1_h00 = (two_t_b_cubed - three_t_b_squared + 1.f); - float p_e1_h10 = (t_b_cubed - 2.f * t_b_squared + t_b); - float p_e1_h01 = (-two_t_b_cubed + three_t_b_squared); - float p_e1 = p_e1_h00 * knee_start - + p_e1_h10 * (1.f - knee_start) - + p_e1_h01 * max_lum; - float e_2 = (e_1 < knee_start) ? e_1 : p_e1; - float e_3a1 = (1 - e_2) * (1 - e_2); - float e_3a2 = e_3a1 * (1 - e_2); - float e_3 = e_2 + (b * e_3a2); - e_3 = saturate(e_3); - float e_4 = lerp(l_b, l_w, e_3); - return e_4; -} - -float HermiteSplineLuminanceRolloff(float luminance, float target_white, float max_white, float target_black, float min_black, float nits = 100.f) { - float luminance_pq = pq::Encode(luminance, nits); - float target_white_pq = pq::Encode(target_white, nits); - float max_white_pq = pq::Encode(max_white, nits); - float target_black_pq = pq::Encode(target_black, nits); - float min_black_pq = pq::Encode(min_black, nits); - - float scaled = HermiteSplineRolloff(luminance_pq, target_white_pq, max_white_pq, target_black_pq, min_black_pq); - - float unpq_scaled = pq::Decode(scaled, nits); - return unpq_scaled; -} - -float3 HermiteSplineLuminanceRolloff(float3 color, float target_white, float max_white, float target_black, float min_black = 0.f, float nits = 100.f) { - float y = GetLuminance(color, CS_BT709); - float new_y = HermiteSplineLuminanceRolloff(y, target_white, max_white, target_black, min_black, nits); - float3 new_color = y > 0 ? color * (new_y / y) : 0; - return new_color; -} - -float3 HermiteSplinePerChannelRolloff(float3 input, float target_white, float max_white, float target_black, float min_black = 0.f, float nits = 100.f) { - float3 input_pq = pq::Encode(input, nits); - float target_white_pq = pq::Encode(target_white, nits); - float max_white_pq = pq::Encode(max_white, nits); - float target_black_pq = pq::Encode(target_black, nits); - float min_black_pq = pq::Encode(min_black, nits); - - float3 scaled = float3( - HermiteSplineRolloff(input_pq.r, target_white_pq, max_white_pq, target_black_pq, min_black_pq), - HermiteSplineRolloff(input_pq.g, target_white_pq, max_white_pq, target_black_pq, min_black_pq), - HermiteSplineRolloff(input_pq.b, target_white_pq, max_white_pq, target_black_pq, min_black_pq)); - - float3 unpq_scaled = pq::Decode(scaled, nits); - return unpq_scaled; -} - -float HermiteSplineLuminanceRolloff(float luminance, float target_white = 1.f, float max_white = 20.f) { - if (luminance == 0) return 0; - return exp2(HermiteSplineRolloff(log2(luminance), log2(target_white), log2(max_white))); -} - -float3 HermiteSplineLuminanceRolloff(float3 color, float target_white = 1.f, float max_white = 20.f) { - float y = GetLuminance(color, CS_BT709); - float new_y = HermiteSplineLuminanceRolloff(y, target_white, max_white); - float3 new_color = y > 0 ? color * (new_y / y) : 0; - return new_color; -} - -float3 HermiteSplinePerChannelRolloff(float3 input, float target_white = 1.f, float max_white = 20.f) { - float target_white_log2 = log2(target_white); - float max_white_log2 = log2(max_white); - float3 scaled = float3( - input.r == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.r), target_white_log2, max_white_log2)), - input.g == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.g), target_white_log2, max_white_log2)), - input.b == 0 ? 0 : exp2(HermiteSplineRolloff(log2(input.b), target_white_log2, max_white_log2))); - return scaled; -} \ No newline at end of file From 6de25a8f646839f005431dbe85c68d694137e274 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 20:27:02 -0700 Subject: [PATCH 04/33] Shadow of War: include a bunch of libs --- .../Middle-earth Shadow of War.vcxproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj b/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj index de0d6e62..b481cbdd 100644 --- a/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj +++ b/Source/Games/Middle-earth Shadow of War/Middle-earth Shadow of War.vcxproj @@ -212,8 +212,8 @@ %(Filename)_p.c - nvsdk_ngx_d_dbg.lib - ..\..\External\NGX\libs + nvsdk_ngx_d.lib;ffx_backend_dx11_x64.lib;ffx_fsr3_x64.lib;ffx_frameinterpolation_x64.lib;ffx_fsr3upscaler_x64.lib;ffx_opticalflow_x64.lib + ..\..\External\NGX\libs;..\..\External\FidelityFX\libs %(AdditionalOptions) /machine:x64 DebugFull @@ -314,8 +314,8 @@ %(Filename)_p.c - nvsdk_ngx_d.lib - ..\..\External\NGX\libs + nvsdk_ngx_d.lib;ffx_backend_dx11_x64.lib;ffx_fsr3_x64.lib;ffx_frameinterpolation_x64.lib;ffx_fsr3upscaler_x64.lib;ffx_opticalflow_x64.lib + ..\..\External\NGX\libs;..\..\External\FidelityFX\libs %(AdditionalOptions) /machine:x64 false @@ -361,8 +361,8 @@ %(Filename)_p.c - nvsdk_ngx_d.lib - ..\..\External\NGX\libs + nvsdk_ngx_d.lib;ffx_backend_dx11_x64.lib;ffx_fsr3_x64.lib;ffx_frameinterpolation_x64.lib;ffx_fsr3upscaler_x64.lib;ffx_opticalflow_x64.lib + ..\..\External\NGX\libs;..\..\External\FidelityFX\libs %(AdditionalOptions) /machine:x64 DebugFull @@ -408,8 +408,8 @@ %(Filename)_p.c - nvsdk_ngx_d.lib - ..\..\External\NGX\libs + nvsdk_ngx_d.lib;ffx_backend_dx11_x64.lib;ffx_fsr3_x64.lib;ffx_frameinterpolation_x64.lib;ffx_fsr3upscaler_x64.lib;ffx_opticalflow_x64.lib + ..\..\External\NGX\libs;..\..\External\FidelityFX\libs %(AdditionalOptions) /machine:x64 DebugFull From 4f2e9ce80b3184399fdd9f16797727b639e72621 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 20:27:20 -0700 Subject: [PATCH 05/33] Shadow of War: Clean main --- .../Games/Middle-earth Shadow of War/main.cpp | 101 +++++++++--------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index f73129e3..02cabf37 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -4,8 +4,13 @@ #include "..\..\Core\core.hpp" +// TODO: Fix this globaly? Define NOMINMAX before including windows.h. +#undef min +#undef max + namespace { + // Shader Hashes const ShaderHashesList shader_hashes_linearize_depth_and_generate_mvs = {.compute_shaders = {0x0E095BB1}}; const ShaderHashesList shader_hashes_TAA = {.pixel_shaders = {0x8D06D556}}; const ShaderHashesList shader_hashes_tonemap = {.pixel_shaders = {0xA4592384, 0xFD32C367}}; @@ -15,34 +20,18 @@ namespace // Jitter from TAA cb float g_jitter_x; float g_jitter_y; - - // User toggle for UI - bool is_ui = true; - - // Various settings for SR related - namespace SRUser - { - static bool copy_resource_def = false; - static bool copy_resource = copy_resource_def; - - static bool allow_upgraded_samplers_def = false; - static bool allow_upgraded_samplers = allow_upgraded_samplers_def; - - static void OnLoadConfigs(reshade::api::effect_runtime* runtime) - { - reshade::get_config_value(runtime, NAME, "copy_resource", copy_resource); - reshade::get_config_value(runtime, NAME, "allow_upgraded_samplers", allow_upgraded_samplers); - ignore_upgraded_samplers = !allow_upgraded_samplers; - } - } + + bool is_ui = true; // User toggle for UI skip draw + bool sr_copy_resource = false; // User toggle to exec CopyResource() to fix missing bloom + bool sr_user_allow_upgraded_samplers = false; // Let user control ignore_upgraded_samplers } struct GameDeviceDataMiddleEarthShadowOfWar final : GameDeviceData { bool drawn_tonemap = false; bool drawn_swapchain = false; - - void OnPresent() + + void ResetDrawnState() { drawn_tonemap = false; drawn_swapchain = false; @@ -56,7 +45,7 @@ namespace DisplayMode static bool is_first = true; constexpr auto flag_file = "Luma_AlwaysHDRLaunch"; - // Stolen from core + // Change to HDR and set brightness settings //TODO: Make ChangeDisplayMode() publicly available from core.hpp void ChangeDisplayModeHDR(reshade::api::effect_runtime* runtime, bool enable_hdr_on_display = true, IDXGISwapChain3* swapchain = nullptr) { DisplayModeType display_mode = DisplayModeType::HDR; @@ -103,7 +92,8 @@ namespace DisplayMode } } }; - + + // Forces user to launch in SDR mode for proper HDR upgrades. static void OnInitSwapchain(reshade::api::swapchain* swapchain) { // gatekeep: is_first @@ -165,6 +155,7 @@ namespace DisplayMode } } +// Constant Buffer variables, grouped here to allow easier editing. namespace CB { static void OnInit() @@ -188,14 +179,16 @@ namespace CB } } -// Helpers to change Shader Defines by UI -namespace ShaderDefineInfo +// Shader Defines, with helpers to draw ImGui for them +namespace ShaderDefines { + // Hashes for new defines constexpr uint32_t GAMMA_CORRECT_CUSTOM = char_ptr_crc32("GAMMA_CORRECT_CUSTOM"); constexpr uint32_t TEST_USER_PEAK = char_ptr_crc32("TEST_USER_PEAK"); constexpr uint32_t FIRE_RETUNED = char_ptr_crc32("FIRE_RETUNED"); constexpr uint32_t RCAS_ENABLED = char_ptr_crc32("RCAS_ENABLED"); + // Append new & change defaults void OnInit() { // New @@ -354,10 +347,10 @@ class MiddleEarthShadowOfWar final : public Game // log message(reshade::log::level::info, "OnInit()"); - // Shader Defines - ShaderDefineInfo::OnInit(); + // Shader Defines append new & change defaults + ShaderDefines::OnInit(); - // CB + // CB init default values CB::OnInit(); // UI Buffer Indirect Upgrades @@ -373,14 +366,17 @@ class MiddleEarthShadowOfWar final : public Game auto_texture_format_upgrade_shader_hashes[0xFD32C367] = std::pair{std::vector{0}, std::vector()}; // tonemap SDR } - // cb + // cb inject indices luma_settings_cbuffer_index = 13; luma_data_cbuffer_index = 12; } void OnInitSwapchain(reshade::api::swapchain* swapchain) { - // DisplayMode + // log + message(reshade::log::level::info, "OnInitSwapchain()"); + + // DisplayMode force restart into SDR mode DisplayMode::OnInitSwapchain(swapchain); } @@ -483,7 +479,7 @@ class MiddleEarthShadowOfWar final : public Game device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); // Copy back to input, fixing missing transparency FXs. - if (SRUser::copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); + if (sr_copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); // Reset pointers ResetCOMArray(srvs); @@ -520,11 +516,8 @@ class MiddleEarthShadowOfWar final : public Game { auto& game_device_data = GetGameDeviceData(device_data); - // game_device_data - game_device_data.OnPresent(); - - // // DetectPhotoMode - // DetectPhotoMode::OnPresent(); + // game_device_data reset state tracking + game_device_data.ResetDrawnState(); // force_reset_sr if (!device_data.has_drawn_sr) device_data.force_reset_sr = true; @@ -533,7 +526,7 @@ class MiddleEarthShadowOfWar final : public Game if (!custom_texture_mip_lod_bias_offset) { std::shared_lock shared_lock_samplers(s_mutex_samplers); - if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !SRUser::allow_upgraded_samplers) + if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !sr_user_allow_upgraded_samplers) { device_data.texture_mip_lod_bias_offset = SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); // This results in -1 at output res } @@ -549,11 +542,13 @@ class MiddleEarthShadowOfWar final : public Game message(reshade::log::level::info, "LoadConfigs()"); reshade::api::effect_runtime* runtime = nullptr; - // CB + // CB load user CB::OnLoadConfigs(runtime); // SRUser - SRUser::OnLoadConfigs(runtime); + reshade::get_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); + reshade::get_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); + ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; } void DrawImGuiSettings(DeviceData& device_data) override @@ -569,7 +564,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::TextWrapped("[Windows' gamma decode in HDR is weaker than in SDR, causing washed out shadows.]"); ImGui::PopStyleColor(); - ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::GAMMA_CORRECT_CUSTOM, "Enable Correction", "sRGB -> 2.2"); + ShaderDefines::UIToggleCheckmark(ShaderDefines::GAMMA_CORRECT_CUSTOM, "Enable Correction", "sRGB -> 2.2"); if (ImGui::Button("Further Explanation & Test (Google Slides)")) Website::OpenWebsite("https://docs.google.com/presentation/d/e/2PACX-1vSXeLHlbm6repcS7fels1-SXYGRmzziRrnuJ8nDO8J5rsWV3dT1-nVyCKp0Tj_stwx-9qlCI-N6rYIT/pub?start=false&loop=false&slide=id.g3e007eafba8_0_0"); @@ -583,7 +578,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("(Use default Luma sliders above.)"); - ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::TEST_USER_PEAK, "Test Pattern (Read Tooltip)", "3 rectangles inside a big one.\n- Left should disappear.\n- Middle should be barely visible.\n- Right should be easy to see."); + ShaderDefines::UIToggleCheckmark(ShaderDefines::TEST_USER_PEAK, "Test Pattern (Read Tooltip)", "3 rectangles inside a big one.\n- Left should disappear.\n- Middle should be barely visible.\n- Right should be easy to see."); ImGui::NewLine(); @@ -637,12 +632,12 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("SR: copy_resource"); - if (ImGui::Checkbox("Copy Resource Fix", &SRUser::copy_resource)) - reshade::set_config_value(runtime, NAME, "copy_resource", SRUser::copy_resource); + if (ImGui::Checkbox("Copy Resource Fix", &sr_copy_resource)) + reshade::set_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("If Bloom and other transparency are missing, enable this."); - DrawResetButton(SRUser::copy_resource, SRUser::copy_resource_def, "copy_resource", runtime); + DrawResetButton(sr_copy_resource, false, "sr_copy_resource", runtime); } ImGui::NewLine(); @@ -651,16 +646,16 @@ class MiddleEarthShadowOfWar final : public Game ImGui::TextWrapped("[Higher Quality Textures Sampling]"); ImGui::PopStyleColor(); - ImGui::PushID("SR: allow_upgraded_samplers"); - if (ImGui::Checkbox("Allow Sampler Upgrades (Read Tooltip)", &SRUser::allow_upgraded_samplers)) + ImGui::PushID("SR: sr_user_allow_upgraded_samplers"); + if (ImGui::Checkbox("Allow Sampler Upgrades (Read Tooltip)", &sr_user_allow_upgraded_samplers)) { - reshade::set_config_value(runtime, NAME, "allow_upgraded_samplers", SRUser::allow_upgraded_samplers); - ignore_upgraded_samplers = !SRUser::allow_upgraded_samplers; + reshade::set_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); + ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; } ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance. Unnoticeable?\nMay change more than just texture detail.\nWill costs some performance."); - DrawResetButton(SRUser::allow_upgraded_samplers, SRUser::allow_upgraded_samplers_def, "allow_upgraded_samplers", runtime); + DrawResetButton(sr_user_allow_upgraded_samplers, false, "sr_user_allow_upgraded_samplers", runtime); } // SECTION: Miscellaneous @@ -692,7 +687,7 @@ class MiddleEarthShadowOfWar final : public Game if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Robust Contrast Adaptive Sharpening on scene color."); DrawResetButton(cb_luma_global_settings.GameSettings.RCAS, default_luma_global_game_settings.RCAS, "RCAS", runtime); - ShaderDefineInfo::Set(ShaderDefineInfo::RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh + ShaderDefines::Set(ShaderDefines::RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh // TODO: AO @@ -713,7 +708,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("This changes its style, becoming more lava-ish orange."); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("If off, shaders will intentionally break, so just ignore the warning. Thanks!"); - ShaderDefineInfo::UIToggleCheckmark(ShaderDefineInfo::FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); + ShaderDefines::UIToggleCheckmark(ShaderDefines::FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); } if (DEVELOPMENT) ImGui::Separator(); //////////////////////////////////////////////////////////////////////////// @@ -732,7 +727,7 @@ class MiddleEarthShadowOfWar final : public Game void OnDisplayModeChanged() { // FORCED: Gamma Correct - ShaderDefineInfo::Set(ShaderDefineInfo::GAMMA_CORRECT_CUSTOM, DisplayMode::IsHDR()); + ShaderDefines::Set(ShaderDefines::GAMMA_CORRECT_CUSTOM, DisplayMode::IsHDR()); } }; From 33f5d243795f8904371e50b3cab4969a0f93fee3 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 22:00:42 -0700 Subject: [PATCH 06/33] Shadow of War: uses global include RCAS --- .../Includes/RCAS.hlsl | 149 ------------------ .../swapchain_hdr_0x68EABB8D.ps_5_0.hlsl | 2 +- .../swapchain_sdr_0x09C22C0E.ps_5_0.hlsl | 42 ++++- 3 files changed, 37 insertions(+), 156 deletions(-) delete mode 100644 Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl diff --git a/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl b/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl deleted file mode 100644 index 411874a9..00000000 --- a/Shaders/Middle-earth Shadow of War/Includes/RCAS.hlsl +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef SRC_RCAS_HLSL -#define SRC_RCAS_HLSL - -// RCAS (Robust Contrast-Adaptive Sharpening) -// https://github.com/GPUOpen-Effects/FidelityFX-FSR2?tab=readme-ov-file#robust-contrast-adaptive-sharpening-rcas -// -// Our implementation is based on: "https://github.com/cdozdil/OptiScaler/blob/master/OptiScaler/shaders/rcas/precompile/rcas.hlsl", -// which is in turn based on: "https://github.com/RdenBlaauwen/RCAS-for-ReShade", -// which is in turn based on AMD FSR 1 RCAS: https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/master/ffx-fsr/ffx_fsr1.h - -// Try to detect noise or grain and not over sharpen it. This seemengly assumes the input is in the SDR 0-1 range. -#ifndef RCAS_DENOISE -#define RCAS_DENOISE 0 -#endif -// Lower means less artifacts and "less sharpening", it's unclear what 16 stands for here, and whether this is meant for linear or gamma space (probably gamma space) -// This is set at the limit of providing unnatural results for sharpening (anything more generates artifacts). -#ifndef RCAS_LIMIT -#define RCAS_LIMIT (0.25-(1.0/16.0)) -#endif -// This should look better, avoid hue shifts and be more compatible with HDR (scRGB, which can have negative values). This appears to have stronger sharpening when enabled, but also causes more black dots to appear at extreme sharpening values. -// For now it's disabled by default as there's not enough proof to justify it, sharpening is a perceptual trick so hue shifts don't really matter (in fact, possibly they make it better). -#define RCAS_LUMINANCE_BASED 0 - -float getRCASLuma(float3 rgb) -{ -#if 0 // LUMA FT: changed to use the proper Rec.709 luminance formula (but multiplied by 2 as the sum of the original RCAS formula is 2) - return GetLuminance(rgb) * 2; -#else - return dot(rgb, float3(0.5, 1.0, 0.5)); -#endif -} - -float3 RCAS(float3 color, Texture2D texColor, SamplerState sampler1, float2 uv, float sharpness, float paperWhite) -{ - // if (sharpness == 0.0f) return color; - - // RCAS is always "pixel based" (the next 4 pixels) - // b - // d e f - // h - // We check for "maxPixelCoord" and "minPixelCoord" to support dynamic resolution scaling. We assume "pixelCoord" is already within the limits. - float3 e = color; - float3 b = texColor.Sample(sampler1, uv, int2( 0,-1)).rgb; - float3 d = texColor.Sample(sampler1, uv, int2(-1, 0)).rgb; - float3 f = texColor.Sample(sampler1, uv, int2( 1, 0)).rgb; - float3 h = texColor.Sample(sampler1, uv, int2( 0, 1)).rgb; - b = max(0, b); - d = max(0, d); - f = max(0, f); - h = max(0, h); - e /= paperWhite; - b /= paperWhite; - d /= paperWhite; - f /= paperWhite; - h /= paperWhite; - -#if RCAS_DENOISE >= 1 - // Get lumas times 2. Should use luma weights that are twice as large as normal. - float bL = getRCASLuma(b); - float dL = getRCASLuma(d); - float eL = getRCASLuma(e); - float fL = getRCASLuma(f); - float hL = getRCASLuma(h); - - // denoise - float nz = (bL + dL + fL + hL) * 0.25 - eL; - float range = max(max(max(bL, dL), max(hL, fL)), eL) - min(min(min(bL, dL), min(eL, fL)), hL); - nz = saturate(abs(nz) * rcp(range)); - nz = -0.5 * nz + 1.0; -#endif - - static const float samplesNum = 4.0; // There's 4 (5) colors to be mixed - // Immediate constants for peak range. - static const float2 peakC = float2(1.0, -samplesNum); - -#if RCAS_LUMINANCE_BASED - // These should all be >= 0, but tiny values below zero shouldn't hurt anyway, still, we clip them below as they'd be clipped by the screen anyway - float bLum = GetLuminance(b); - float dLum = GetLuminance(d); - float eLum = GetLuminance(e); - float fLum = GetLuminance(f); - float hLum = GetLuminance(h); - - float minLum = max(min(min(bLum, dLum), min(fLum, hLum)), 0.0); - float maxLum = max(max(bLum, dLum), max(fLum, hLum)); - - float hitMin = minLum * rcp(samplesNum * maxLum); - float hitMax = (peakC.x - maxLum) * rcp(samplesNum * minLum + peakC.y); - - float localLobe = max(-hitMin, hitMax); -#else // !RCAS_LUMINANCE_BASED - // Min and max of ring. - float3 minRGB = min(min(b, d), min(f, h)); - float3 maxRGB = max(max(b, d), max(f, h)); - -#if 0 // It seems like it's ok if these values aren't in the 0-1 range, the code below will still work as expected, and avoid clipping HDR (or anyway ignoring values beyond SDR) //TODOFT3: Lilium claims the code below can break for negative rgb (scRGB) values, investigate and fix it - minRGB = saturate(minRGB); - maxRGB = saturate(maxRGB); -#endif - - // Limiters, these need to use high precision reciprocal operations. - // Decided to use standard rcp for now in hopes of optimizing it. - // It's fine if either of these can go below zero! - float3 hitMin = minRGB * rcp(samplesNum * maxRGB); - float3 hitMax = (peakC.xxx - maxRGB) * rcp(samplesNum * minRGB + peakC.yyy); - - float3 lobeRGB = max(-hitMin, hitMax); -#if 0 // An attempt to make this code, which branches by r g b channel, color space agnostic. Without this, the result heavily depends by where the rgb coordinates are in the CIE color graph, and by how luminous they are. Unfortunately this drastically reduces the sharpening intensity, even if it makes it look even more natural. - float localLobe = max(lobeRGB.r * Rec709_Luminance.r * 3.0, max(lobeRGB.g * Rec709_Luminance.g * 3.0, lobeRGB.b * Rec709_Luminance.b * 3.0)); -#else - float localLobe = max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)); -#endif -#endif // RCAS_LUMINANCE_BASED - - float lobe = max(-RCAS_LIMIT, min(localLobe, 0.0)) * sharpness; - -#if RCAS_DENOISE >= 1 - // denoise - lobe *= nz; -#endif - - // Resolve, which needs medium precision rcp approximation to avoid visible tonality changes. - float rcpL = rcp(samplesNum * lobe + 1.0); - -#if RCAS_LUMINANCE_BASED - float outputLum = ((bLum + dLum + hLum + fLum) * lobe + eLum) * rcpL; - // Questionable choice: in case the source center pixel had luminance zero (even if the rgb ratio wasn't flat), elevate it to grey and match the target luminance, or we'd have a division by zero. - // The alternative would be to keep "e" intact, but that then wouldn't have applied any sharpening. - float3 output = eLum != 0 ? (e * (outputLum / eLum)) : outputLum; -#else // !RCAS_LUMINANCE_BASED - float3 output = ((b + d + f + h) * lobe + e) * rcpL; -#endif // RCAS_LUMINANCE_BASED - -#if 0 // Debug - if (dynamicSharpening) - { - if (originalSharpness < sharpness) - output.r *= 1 + (12.0 * (sharpness - originalSharpness)); - else - output.g *= 1 + (12.0 * (originalSharpness - sharpness)); - } -#endif - - output *= paperWhite; - - return output; -} - -#endif // SRC_RCAS_HLSL \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl index dfd45a41..9b515bec 100644 --- a/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl @@ -15,7 +15,7 @@ Texture2D SourceBuffer1 : register(t1); // 3Dmigoto declarations #define cmp - #include "./common.hlsl" -#include "./Includes/RCAS.hlsl" +// #include "./Includes/RCAS.hlsl" void main( float4 v0 : SV_POSITION0, diff --git a/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl index 94445a7a..dbd885ac 100644 --- a/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl @@ -5,17 +5,39 @@ cbuffer CBuffer_Data : register(b0) float2 TexCoordScale0 : packoffset(c0); float2 MaxTexCoord0 : packoffset(c0.z); float2 Gamma : packoffset(c1); + float2 RenderResolution : packoffset(c1.z); + float2 SwapchainResolution : packoffset(c2); + float2 idk1 : packoffset(c2.z); + + /* + 1 + 1 + 0.999857 + 0.999745 + + 1 + 6.25 + 960 + 540 + + 3840 + 2160 + 0 + 0 + */ } SamplerState TextureSampler_s : register(s0); Texture2D SourceBuffer0 : register(t0); Texture2D SourceBuffer1 : register(t1); +Texture2D Dummy; //TODO: take in MVs for dynamic RCAS? + // 3Dmigoto declarations #define cmp - #include "./common.hlsl" -#include "./Includes/RCAS.hlsl" +#include "../Includes/RCAS.hlsl" float3 GameGamma(float3 x) { float3 r0, r1, r2; @@ -40,16 +62,24 @@ void main( uint4 bitmask, uiDest; float4 fDest; - // texcoords + // texcoords (in subnative res, color smaller top left) r0.xy = TexCoordScale0.xy * v1.xy; r0.xy = min(MaxTexCoord0.xy, r0.xy); //// GAME //// - float3 game = SourceBuffer0.SampleLevel(TextureSampler_s, r0.xy, 0).xyz; - game = max(game, 0); - #if RCAS_ENABLED == 1 - game = RCAS(game, SourceBuffer0, TextureSampler_s, r0.xy, GS.RCAS, GamePaperWhiteNits / ITU_WhiteLevelNits); + #if RCAS_ENABLED == 0 + float3 game = SourceBuffer0.SampleLevel(TextureSampler_s, r0.xy, 0).xyz; + #else + float3 game = RCAS( + r0.xy * RenderResolution, + int2(0,0), + int2(RenderResolution), + GS.RCAS, + SourceBuffer0, + Dummy, + GamePaperWhiteNits / ITU_WhiteLevelNits + ).xyz; game = max(game, 0); #endif From c8183bc89aad782765fb7c4c50c5958bd2a50153 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 23:06:30 -0700 Subject: [PATCH 07/33] Shadow of War: Reworded SR ImGui Section --- .../taa_0x8D06D556.ps_5_0.hlsl 1 | 708 ++++++++++++++++++ .../Games/Middle-earth Shadow of War/main.cpp | 18 +- 2 files changed, 717 insertions(+), 9 deletions(-) create mode 100644 Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 diff --git a/Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 new file mode 100644 index 00000000..bb4572c5 --- /dev/null +++ b/Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 @@ -0,0 +1,708 @@ +// TODO: Can't decompile correctly. + + +// ---- Created with 3Dmigoto v1.3.16 on Sun Jul 19 22:09:03 2026 +Texture2D t4 : register(t4); + +Texture2D t3 : register(t3); + +Texture2D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb2 : register(b2) +{ + float4 cb2[53]; +} + +cbuffer cb0 : register(b0) +{ + float4 cb0[34]; +} + +// 3Dmigoto declarations +#define cmp - + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + float2 w1 : TEXCOORD1, + out float4 o0 : SV_Target0) +{ + float4 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15; + uint4 bitmask, uiDest; + float4 fDest; + + o0.xyzw = t1.Sample(s0_s, w1.xy).xyzw; + return; + + discard; + + r0.yz = -cb0[32].wz + w1.xy; + r1.xy = cb0[32].zw + w1.xy; + r2.xy = w1.xy + r0.zy; + r2.xy = float2(0.5,0.5) * r2.xy; + r2.xy = saturate(min(cb2[22].zw, r2.xy)); + r3.xyzw = t3.Gather(s0_s, r2.xy).xyzw; + + r2.zw = w1.xy + r1.xy; + r2.zw = float2(0.5,0.5) * r2.zw; + r2.zw = saturate(min(cb2[22].zw, r2.zw)); + r4.xyz = t3.Gather(s0_s, r2.zw).xyz; + r5.xyzw = t4.Gather(s0_s, r2.xy).xyzw; + r5.xyzw = float4(255,255,255,255) * r5.xyzw; + r2.xyz = t4.Gather(s0_s, r2.zw).xyz; + r2.xyzw = float4(255,255,255,255) * r2.zxyz; + r0.xw = w1.xy; + r6.zw = saturate(min(cb2[22].zw, r0.xy)); + r1.zw = w1.xy; + r7.zw = saturate(min(cb2[22].zw, r1.xz)); + r8.zw = saturate(min(cb2[22].zw, r1.xy)); + r9.zw = saturate(min(cb2[22].zw, r1.wy)); + r10.zw = saturate(min(cb2[22].zw, r0.zw)); + r11.zw = saturate(min(cb2[22].zw, r0.zy)); + r1.z = cmp(r3.x < r3.y); + r10.x = r5.x; + r10.y = r3.x; + r12.x = r5.y; + r12.y = r3.y; + r12.zw = w1.xy; + r12.xyzw = r1.zzzz ? r10.xyzw : r12.xyzw; + r1.z = cmp(r3.w < r12.y); + r11.x = r5.w; + r11.y = r3.w; + r12.xyzw = r1.zzzz ? r11.xyzw : r12.xyzw; + r1.z = cmp(r3.z < r12.y); + r6.x = r5.z; + r6.y = r3.z; + r3.xyzw = r1.zzzz ? r6.xyzw : r12.xyzw; + r1.z = cmp(r4.z < r3.y); + r7.x = r2.w; + r7.y = r4.z; + r3.xyzw = r1.zzzz ? r7.xyzw : r3.xyzw; + r1.z = cmp(r4.y < r3.y); + r8.x = r2.z; + r8.y = r4.y; + r3.xyzw = r1.zzzz ? r8.xyzw : r3.xyzw; + r1.z = cmp(r4.x < r3.y); + r9.x = r2.y; + r9.y = r4.x; + r3.xyzw = r1.zzzz ? r9.xyzw : r3.xyzw; + r4.xyzw = t1.Sample(s0_s, w1.xy).xyzw; + // o0 = r4; r4.w = 10; return; + + + + r1.z = cmp(r3.y < 10000000); + if (r1.z != 0) { + r12.xyzw = max(float4(0,0,0,0), r4.xyzw); + r1.z = dot(r12.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r1.z = 1 + r1.z; + r12.xyz = r12.xyz / r1.zzz; + r1.zw = t0.Sample(s0_s, r3.zw).xy; + r1.zw = cb2[22].yx * r1.wz; + r1.zw = -r1.zw * float2(2,2) + w1.xy; + r3.yz = cb0[33].yx / cb2[22].yx; + r6.xy = r3.yz * r1.zw; + r7.xy = saturate(r1.wz * r3.zy + -cb0[32].zw); + r1.zw = saturate(r1.wz * r3.zy + cb0[32].zw); + r1.zw = saturate(cb0[33].zw + -r1.zw); + r1.z = r1.z * r1.w; + r1.z = r1.z * r7.x; + r1.z = r1.z * r7.y; + r13.xyzw = t2.Gather(s0_s, r6.yx).xyzw; + r14.xyzw = cmp(r5.xyzw == r13.xxxx); + r1.w = (int)r14.y | (int)r14.x; + r1.w = (int)r14.z | (int)r1.w; + r1.w = (int)r14.w | (int)r1.w; + r14.xyzw = cmp(r2.yzwy == r13.xxxy); + r1.w = (int)r1.w | (int)r14.x; + r1.w = (int)r14.y | (int)r1.w; + r1.w = (int)r14.z | (int)r1.w; + r15.xyzw = cmp(r5.xyzw == r13.yyyy); + r3.y = (int)r15.y | (int)r15.x; + r3.y = (int)r15.z | (int)r3.y; + r3.y = (int)r15.w | (int)r3.y; + r3.y = (int)r14.w | (int)r3.y; + r14.xyzw = cmp(r2.zwyz == r13.yyzz); + r3.y = (int)r3.y | (int)r14.x; + r15.xyzw = cmp(r5.xyzw == r13.zzzz); + r3.z = (int)r15.y | (int)r15.x; + r3.z = (int)r15.z | (int)r3.z; + r3.z = (int)r15.w | (int)r3.z; + r3.yz = (int2)r14.yz | (int2)r3.yz; + r3.z = (int)r14.w | (int)r3.z; + r2.xyzw = cmp(r2.xyzw == r13.zwww); + r2.x = (int)r2.x | (int)r3.z; + r5.xyzw = cmp(r5.xyzw == r13.wwww); + r3.z = (int)r5.y | (int)r5.x; + r3.z = (int)r5.z | (int)r3.z; + r3.z = (int)r5.w | (int)r3.z; + r2.y = (int)r2.y | (int)r3.z; + r2.y = (int)r2.z | (int)r2.y; + r2.y = (int)r2.w | (int)r2.y; + r1.z = cmp(r1.z == 0.000000); + r1.w = ~(int)r1.w; + r1.z = (int)r1.w | (int)r1.z; + r1.w = ~(int)r3.y; + r1.z = (int)r1.w | (int)r1.z; + r1.w = ~(int)r2.x; + r1.z = (int)r1.w | (int)r1.z; + r1.w = ~(int)r2.y; + r1.z = (int)r1.w | (int)r1.z; + if (r1.z != 0) { + r2.xy = -cb0[31].xy * cb0[32].zw + w1.xy; + r2.xy = saturate(min(cb2[22].zw, r2.xy)); + r2.xyz = t1.Sample(s0_s, r2.xy).xyz; + r2.xyz = max(float3(0,0,0), r2.xyz); + r1.w = dot(r2.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r1.w = 1 + r1.w; + r2.xyz = r2.xyz / r1.www; + r2.xyz = r12.xyz + r2.xyz; + r2.xyz = float3(0.5,0.5,0.5) * r2.xyz; + r1.w = dot(r2.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r1.w = 1 + -r1.w; + r1.w = max(9.99999997e-007, r1.w); + r2.xyz = r2.xyz / r1.www; + r3.yzw = (int3)r2.xyz & int3(0x7f800000,0x7f800000,0x7f800000); + r3.yzw = cmp((int3)r3.yzw == int3(0x7f800000,0x7f800000,0x7f800000)); + o0.xyz = r3.yzw ? float3(65000,65000,65000) : r2.xyz; + o0.w = r12.w; + } else { + o0.xyzw = r4.xyzw; + } + if (r1.z == 0) { + r0.xw = r1.xy; + r0.xyzw = saturate(min(cb2[22].zwzw, r0.xyzw)); + r1.x = cmp(r3.x == 96.000000); + r1.y = cmp(r3.x < 128); + r1.z = cmp(r3.x >= 200); + r2.x = dot(float3(0.25,0.5,0.25), r12.xyz); + r2.y = dot(float3(-0.25,0.5,-0.25), r12.xyz); + r2.z = dot(float2(0.5,-0.5), r12.xz); + r3.xyz = t1.Sample(s0_s, r6.zw).xyz; + r3.xyz = max(float3(0,0,0), r3.xyz); + r1.w = dot(r3.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r1.w = 1 + r1.w; + r3.xyz = r3.xyz / r1.www; + r5.x = dot(float3(0.25,0.5,0.25), r3.xyz); + r5.y = dot(float3(-0.25,0.5,-0.25), r3.xyz); + r5.z = dot(float2(0.5,-0.5), r3.xz); + r3.xyz = max(r5.xyz, r2.xyz); + r2.xyz = min(r5.xyz, r2.xyz); + r5.xyz = t1.Sample(s0_s, r0.xy).xyz; + r5.xyz = max(float3(0,0,0), r5.xyz); + r0.x = dot(r5.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.x = 1 + r0.x; + r5.xyz = r5.xyz / r0.xxx; + r13.x = dot(float3(0.25,0.5,0.25), r5.xyz); + r13.y = dot(float3(-0.25,0.5,-0.25), r5.xyz); + r13.z = dot(float2(0.5,-0.5), r5.xz); + r5.xyz = max(r13.xyz, r3.xyz); + r13.xyz = min(r13.xyz, r2.xyz); + r7.xyz = t1.Sample(s0_s, r7.zw).xyz; + r7.xyz = max(float3(0,0,0), r7.xyz); + r0.x = dot(r7.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.x = 1 + r0.x; + r7.xyz = r7.xyz / r0.xxx; + r14.x = dot(float3(0.25,0.5,0.25), r7.xyz); + r14.y = dot(float3(-0.25,0.5,-0.25), r7.xyz); + r14.z = dot(float2(0.5,-0.5), r7.xz); + r5.xyz = max(r14.xyz, r5.xyz); + r7.xyz = min(r14.xyz, r13.xyz); + r3.xyz = max(r14.xyz, r3.xyz); + r2.xyz = min(r14.xyz, r2.xyz); + r8.xyz = t1.Sample(s0_s, r8.zw).xyz; + r8.xyz = max(float3(0,0,0), r8.xyz); + r0.x = dot(r8.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.x = 1 + r0.x; + r8.xyz = r8.xyz / r0.xxx; + r13.x = dot(float3(0.25,0.5,0.25), r8.xyz); + r13.y = dot(float3(-0.25,0.5,-0.25), r8.xyz); + r13.z = dot(float2(0.5,-0.5), r8.xz); + r5.xyz = max(r13.xyz, r5.xyz); + r7.xyz = min(r13.xyz, r7.xyz); + r8.xyz = t1.Sample(s0_s, r9.zw).xyz; + r8.xyz = max(float3(0,0,0), r8.xyz); + r0.x = dot(r8.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.x = 1 + r0.x; + r8.xyz = r8.xyz / r0.xxx; + r9.x = dot(float3(0.25,0.5,0.25), r8.xyz); + r9.y = dot(float3(-0.25,0.5,-0.25), r8.xyz); + r9.z = dot(float2(0.5,-0.5), r8.xz); + r5.xyz = max(r9.xyz, r5.xyz); + r7.xyz = min(r9.xyz, r7.xyz); + r3.xyz = max(r9.xyz, r3.xyz); + r2.xyz = min(r9.xyz, r2.xyz); + r0.xyz = t1.Sample(s0_s, r0.zw).xyz; + r0.xyz = max(float3(0,0,0), r0.xyz); + r0.w = dot(r0.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.w = 1 + r0.w; + r0.xyz = r0.xyz / r0.www; + r8.x = dot(float3(0.25,0.5,0.25), r0.xyz); + r8.y = dot(float3(-0.25,0.5,-0.25), r0.xyz); + r8.z = dot(float2(0.5,-0.5), r0.xz); + r0.xyz = max(r8.xyz, r5.xyz); + r5.xyz = min(r8.xyz, r7.xyz); + r7.xyz = t1.Sample(s0_s, r10.zw).xyz; + r7.xyz = max(float3(0,0,0), r7.xyz); + r0.w = dot(r7.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.w = 1 + r0.w; + r7.xyz = r7.xyz / r0.www; + r8.x = dot(float3(0.25,0.5,0.25), r7.xyz); + r8.y = dot(float3(-0.25,0.5,-0.25), r7.xyz); + r8.z = dot(float2(0.5,-0.5), r7.xz); + r0.xyz = max(r8.xyz, r0.xyz); + r5.xyz = min(r8.xyz, r5.xyz); + r3.xyz = max(r8.xyz, r3.xyz); + r2.xyz = min(r8.xyz, r2.xyz); + r7.xyz = t1.Sample(s0_s, r11.zw).xyz; + r7.xyz = max(float3(0,0,0), r7.xyz); + r0.w = dot(r7.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.w = 1 + r0.w; + r7.xyz = r7.xyz / r0.www; + r8.x = dot(float3(0.25,0.5,0.25), r7.xyz); + r8.y = dot(float3(-0.25,0.5,-0.25), r7.xyz); + r8.z = dot(float2(0.5,-0.5), r7.xz); + r0.xyz = max(r8.xyz, r0.xyz); + r5.xyz = min(r8.xyz, r5.xyz); + r0.xyz = r0.xyz + r3.xyz; + r0.xyz = float3(0.5,0.5,0.5) * r0.xyz; + r2.xyz = r5.xyz + r2.xyz; + r2.xyz = float3(0.5,0.5,0.5) * r2.xyz; + r3.xy = r6.yx * cb0[32].xy + float2(-0.5,-0.5); + r3.xy = floor(r3.xy); + r5.xyzw = float4(0.5,0.5,-0.5,-0.5) + r3.xyxy; + r3.zw = r6.xy * cb0[32].yx + -r5.yx; + r6.xy = r3.wz * r3.wz; + r6.zw = r6.xy * r3.wz; + r7.xy = r6.yx * r3.zw + r3.zw; + r7.xy = -r7.xy * float2(0.5,0.5) + r6.yx; + r7.zw = float2(2.5,2.5) * r6.yx; + r6.zw = r6.wz * float2(1.5,1.5) + -r7.zw; + r6.zw = float2(1,1) + r6.zw; + r3.zw = r6.xy * r3.wz + -r6.xy; + r6.xy = float2(0.5,0.5) * r3.zw; + r7.zw = float2(1,1) + -r7.yx; + r7.zw = r7.zw + -r6.wz; + r3.zw = -r3.zw * float2(0.5,0.5) + r7.zw; + r6.zw = r6.zw + r3.wz; + r3.zw = r3.zw / r6.wz; + r3.zw = r5.xy + r3.zw; + r3.xy = float2(2.5,2.5) + r3.xy; + r5.xw = cb0[32].zw * r5.zw; + r5.yz = cb0[32].wz * r3.wz; + r3.xy = cb0[32].zw * r3.xy; + r8.xyz = t2.Sample(s1_s, r5.xw).xyz; + r9.xyz = t2.Sample(s1_s, r5.zw).xyz; + r3.zw = r5.wy; + r10.xyz = t2.Sample(s1_s, r3.xz).xyz; + r11.xyz = t2.Sample(s1_s, r5.xy).xyz; + r13.xyz = t2.Sample(s1_s, r5.zy).xyz; + r14.xyz = t2.Sample(s1_s, r3.xw).xyz; + r5.y = r3.y; + r15.xyz = t2.Sample(s1_s, r5.xy).xyz; + r5.xyz = t2.Sample(s1_s, r5.zy).xyz; + r3.xyz = t2.Sample(s1_s, r3.xy).xyz; + r0.w = r7.y * r7.x; + r7.zw = r6.wz * r7.xy; + r9.xyz = r9.xyz * r7.zzz; + r7.xy = r6.xy * r7.xy; + r1.w = r6.w * r6.z; + r6.zw = r6.xy * r6.zw; + r2.w = r6.x * r6.y; + r8.xyz = r8.xyz * r0.www + r9.xyz; + r8.xyz = r10.xyz * r7.xxx + r8.xyz; + r7.xzw = r11.xyz * r7.www + r8.xyz; + r7.xzw = r13.xyz * r1.www + r7.xzw; + r6.xyz = r14.xyz * r6.zzz + r7.xzw; + r6.xyz = r15.xyz * r7.yyy + r6.xyz; + r5.xyz = r5.xyz * r6.www + r6.xyz; + r3.xyz = r3.xyz * r2.www + r5.xyz; + r3.xyz = max(float3(0,0,0), r3.xyz); + r0.w = dot(r3.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.w = 1 + r0.w; + r3.xyz = r3.xyz / r0.www; + r5.x = dot(float3(0.25,0.5,0.25), r3.xyz); + r5.y = dot(float3(-0.25,0.5,-0.25), r3.xyz); + r5.z = dot(float2(0.5,-0.5), r3.xz); + r2.xyz = max(r5.xyz, r2.xyz); + r0.xyz = min(r2.xyz, r0.xyz); + r2.x = dot(float3(1,-1,1), r0.xyz); + r2.y = dot(float2(1,1), r0.xy); + r2.z = dot(float3(1,-1,-1), r0.xyz); + r0.xyz = float3(0.200000003,0.400000006,0.600000024) * cb0[31].zzz; + r0.y = r1.z ? r0.y : r0.z; + r0.x = r1.y ? r0.x : r0.y; + r0.x = 1 + -r0.x; + r0.x = r1.x ? 0.5 : r0.x; + r0.y = 1 + -r0.x; + r0.xzw = r0.xxx * r2.xyz; + r0.xyz = r0.yyy * r12.xyz + r0.xzw; + r0.w = dot(r0.xyz, float3(0.212599993,0.715200007,0.0722000003)); + r0.w = 1 + -r0.w; + r0.w = max(9.99999997e-007, r0.w); + r0.xyz = r0.xyz / r0.www; + r1.xyz = (int3)r0.xyz & int3(0x7f800000,0x7f800000,0x7f800000); + r1.xyz = cmp((int3)r1.xyz == int3(0x7f800000,0x7f800000,0x7f800000)); + o0.xyz = r1.xyz ? float3(65000,65000,65000) : r0.xyz; + o0.w = r12.w; + } + } else { + o0.xyzw = r4.xyzw; + } + return; +} + +/* +// +// Generated by Microsoft (R) D3D Shader Disassembler +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float +// TEXCOORD 1 zw 1 NONE float zw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// + 0x00000000: ps_5_0 + 0x00000008: dcl_globalFlags refactoringAllowed + 0x0000000C: dcl_constantbuffer CB0[34], immediateIndexed + 0x0000001C: dcl_constantbuffer CB2[53], immediateIndexed + 0x0000002C: dcl_sampler s0, mode_default + 0x00000038: dcl_sampler s1, mode_default + 0x00000044: dcl_resource_texture2d (float,float,float,float) t0 + 0x00000054: dcl_resource_texture2d (float,float,float,float) t1 + 0x00000064: dcl_resource_texture2d (float,float,float,float) t2 + 0x00000074: dcl_resource_texture2d (float,float,float,float) t3 + 0x00000084: dcl_resource_texture2d (float,float,float,float) t4 + 0x00000094: dcl_input_ps linear v1.zw + 0x000000A0: dcl_output o0.xyzw + 0x000000AC: dcl_temps 16 + 0 0x000000B4: add r0.yz, v1.wwzw, -cb0[32].wwzw + 1 0x000000D8: add r1.xy, v1.zwzz, cb0[32].zwzz + 2 0x000000F8: add r2.xy, r0.zyzz, v1.zwzz + 3 0x00000114: mul r2.xy, r2.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000) + 4 0x0000013C: min_sat r2.xy, r2.xyxx, cb2[22].zwzz + 5 0x0000015C: gather4_indexable(texture2d)(float,float,float,float) r3.xyzw, r2.xyxx, t3.xyzw, s0.x + 6 0x00000188: add r2.zw, r1.xxxy, v1.zzzw + 7 0x000001A4: mul r2.zw, r2.zzzw, l(0.000000, 0.000000, 0.500000, 0.500000) + 8 0x000001CC: min_sat r2.zw, r2.zzzw, cb2[22].zzzw + 9 0x000001EC: gather4_indexable(texture2d)(float,float,float,float) r4.xyz, r2.zwzz, t3.xyzw, s0.x + 10 0x00000218: gather4_indexable(texture2d)(float,float,float,float) r5.xyzw, r2.xyxx, t4.xyzw, s0.w + 11 0x00000244: mul r5.xyzw, r5.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) + 12 0x0000026C: gather4_indexable(texture2d)(float,float,float,float) r2.xyz, r2.zwzz, t4.xyzw, s0.w + 13 0x00000298: mul r2.xyzw, r2.zxyz, l(255.000000, 255.000000, 255.000000, 255.000000) + 14 0x000002C0: mov r0.xw, v1.zzzw + 15 0x000002D4: min_sat r6.zw, r0.xxxy, cb2[22].zzzw + 16 0x000002F4: mov r1.zw, v1.wwwz + 17 0x00000308: min_sat r7.zw, r1.xxxz, cb2[22].zzzw + 18 0x00000328: min_sat r8.zw, r1.xxxy, cb2[22].zzzw + 19 0x00000348: min_sat r9.zw, r1.wwwy, cb2[22].zzzw + 20 0x00000368: min_sat r10.zw, r0.zzzw, cb2[22].zzzw + 21 0x00000388: min_sat r11.zw, r0.zzzy, cb2[22].zzzw + 22 0x000003A8: lt r1.z, r3.x, r3.y + 23 0x000003C4: mov r10.x, r5.x + 24 0x000003D8: mov r10.y, r3.x + 25 0x000003EC: mov r12.x, r5.y + 26 0x00000400: mov r12.y, r3.y + 27 0x00000414: mov r12.zw, v1.zzzw + 28 0x00000428: movc r12.xyzw, r1.zzzz, r10.xyzw, r12.xyzw + 29 0x0000044C: lt r1.z, r3.w, r12.y + 30 0x00000468: mov r11.x, r5.w + 31 0x0000047C: mov r11.y, r3.w + 32 0x00000490: movc r12.xyzw, r1.zzzz, r11.xyzw, r12.xyzw + 33 0x000004B4: lt r1.z, r3.z, r12.y + 34 0x000004D0: mov r6.x, r5.z + 35 0x000004E4: mov r6.y, r3.z + 36 0x000004F8: movc r3.xyzw, r1.zzzz, r6.xyzw, r12.xyzw + 37 0x0000051C: lt r1.z, r4.z, r3.y + 38 0x00000538: mov r7.x, r2.w + 39 0x0000054C: mov r7.y, r4.z + 40 0x00000560: movc r3.xyzw, r1.zzzz, r7.xyzw, r3.xyzw + 41 0x00000584: lt r1.z, r4.y, r3.y + 42 0x000005A0: mov r8.x, r2.z + 43 0x000005B4: mov r8.y, r4.y + 44 0x000005C8: movc r3.xyzw, r1.zzzz, r8.xyzw, r3.xyzw + 45 0x000005EC: lt r1.z, r4.x, r3.y + 46 0x00000608: mov r9.x, r2.y + 47 0x0000061C: mov r9.y, r4.x + 48 0x00000630: movc r3.xyzw, r1.zzzz, r9.xyzw, r3.xyzw + 49 0x00000654: sample_indexable(texture2d)(float,float,float,float) r4.xyzw, v1.zwzz, t1.xyzw, s0 + 50 0x00000680: lt r1.z, r3.y, l(10000000.000000) + 51 0x0000069C: if_nz r1.z + 52 0x000006A8: max r12.xyzw, r4.xyzw, l(0.000000, 0.000000, 0.000000, 0.000000) + 53 0x000006D0: dp3 r1.z, r12.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 54 0x000006F8: add r1.z, r1.z, l(1.000000) + 55 0x00000714: div r12.xyz, r12.xyzx, r1.zzzz + 56 0x00000730: sample_indexable(texture2d)(float,float,float,float) r1.zw, r3.zwzz, t0.zwxy, s0 + 57 0x0000075C: mul r1.zw, r1.wwwz, cb2[22].yyyx + 58 0x0000077C: mad r1.zw, -r1.zzzw, l(0.000000, 0.000000, 2.000000, 2.000000), v1.wwwz + 59 0x000007B0: div r3.yz, cb0[33].yyxy, cb2[22].yyxy + 60 0x000007D4: mul r6.xy, r1.zwzz, r3.yzyy + 61 0x000007F0: mad_sat r7.xy, r1.wzww, r3.zyzz, -cb0[32].zwzz + 62 0x0000081C: mad_sat r1.zw, r1.wwwz, r3.zzzy, cb0[32].zzzw + 63 0x00000844: add_sat r1.zw, -r1.zzzw, cb0[33].zzzw + 64 0x00000868: mul r1.z, r1.w, r1.z + 65 0x00000884: mul r1.z, r7.x, r1.z + 66 0x000008A0: mul r1.z, r7.y, r1.z + 67 0x000008BC: gather4_indexable(texture2d)(float,float,float,float) r13.xyzw, r6.yxyy, t2.xyzw, s0.w + 68 0x000008E8: eq r14.xyzw, r5.xyzw, r13.xxxx + 69 0x00000904: or r1.w, r14.y, r14.x + 70 0x00000920: or r1.w, r14.z, r1.w + 71 0x0000093C: or r1.w, r14.w, r1.w + 72 0x00000958: eq r14.xyzw, r2.yzwy, r13.xxxy + 73 0x00000974: or r1.w, r1.w, r14.x + 74 0x00000990: or r1.w, r14.y, r1.w + 75 0x000009AC: or r1.w, r14.z, r1.w + 76 0x000009C8: eq r15.xyzw, r5.xyzw, r13.yyyy + 77 0x000009E4: or r3.y, r15.y, r15.x + 78 0x00000A00: or r3.y, r15.z, r3.y + 79 0x00000A1C: or r3.y, r15.w, r3.y + 80 0x00000A38: or r3.y, r14.w, r3.y + 81 0x00000A54: eq r14.xyzw, r2.zwyz, r13.yyzz + 82 0x00000A70: or r3.y, r3.y, r14.x + 83 0x00000A8C: eq r15.xyzw, r5.xyzw, r13.zzzz + 84 0x00000AA8: or r3.z, r15.y, r15.x + 85 0x00000AC4: or r3.z, r15.z, r3.z + 86 0x00000AE0: or r3.z, r15.w, r3.z + 87 0x00000AFC: or r3.yz, r14.yyzy, r3.yyzy + 88 0x00000B18: or r3.z, r14.w, r3.z + 89 0x00000B34: eq r2.xyzw, r2.xyzw, r13.zwww + 90 0x00000B50: or r2.x, r2.x, r3.z + 91 0x00000B6C: eq r5.xyzw, r5.xyzw, r13.wwww + 92 0x00000B88: or r3.z, r5.y, r5.x + 93 0x00000BA4: or r3.z, r5.z, r3.z + 94 0x00000BC0: or r3.z, r5.w, r3.z + 95 0x00000BDC: or r2.y, r2.y, r3.z + 96 0x00000BF8: or r2.y, r2.z, r2.y + 97 0x00000C14: or r2.y, r2.w, r2.y + 98 0x00000C30: eq r1.z, r1.z, l(0.000000) + 99 0x00000C4C: not r1.w, r1.w + 100 0x00000C60: or r1.z, r1.w, r1.z + 101 0x00000C7C: not r1.w, r3.y + 102 0x00000C90: or r1.z, r1.w, r1.z + 103 0x00000CAC: not r1.w, r2.x + 104 0x00000CC0: or r1.z, r1.w, r1.z + 105 0x00000CDC: not r1.w, r2.y + 106 0x00000CF0: or r1.z, r1.w, r1.z + 107 0x00000D0C: if_nz r1.z + 108 0x00000D18: mad r2.xy, -cb0[31].xyxx, cb0[32].zwzz, v1.zwzz + 109 0x00000D48: min_sat r2.xy, r2.xyxx, cb2[22].zwzz + 110 0x00000D68: sample_indexable(texture2d)(float,float,float,float) r2.xyz, r2.xyxx, t1.xyzw, s0 + 111 0x00000D94: max r2.xyz, r2.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 112 0x00000DBC: dp3 r1.w, r2.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 113 0x00000DE4: add r1.w, r1.w, l(1.000000) + 114 0x00000E00: div r2.xyz, r2.xyzx, r1.wwww + 115 0x00000E1C: add r2.xyz, r2.xyzx, r12.xyzx + 116 0x00000E38: mul r2.xyz, r2.xyzx, l(0.500000, 0.500000, 0.500000, 0.000000) + 117 0x00000E60: dp3 r1.w, r2.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 118 0x00000E88: add r1.w, -r1.w, l(1.000000) + 119 0x00000EA8: max r1.w, r1.w, l(0.000001) + 120 0x00000EC4: div r2.xyz, r2.xyzx, r1.wwww + 121 0x00000EE0: and r3.yzw, r2.xxyz, l(0, 0x7f800000, 0x7f800000, 0x7f800000) + 122 0x00000F08: ieq r3.yzw, r3.yyzw, l(0, 0x7f800000, 0x7f800000, 0x7f800000) + 123 0x00000F30: movc o0.xyz, r3.yzwy, l(65000.000000,65000.000000,65000.000000,0), r2.xyzx + 124 0x00000F60: mov o0.w, r12.w + 125 0x00000F74: else + 126 0x00000F78: mov o0.xyzw, r4.xyzw + 127 0x00000F8C: endif + 128 0x00000F90: if_z r1.z + 129 0x00000F9C: mov r0.xw, r1.xxxy + 130 0x00000FB0: min_sat r0.xyzw, r0.xyzw, cb2[22].zwzw + 131 0x00000FD0: eq r1.x, r3.x, l(96.000000) + 132 0x00000FEC: lt r1.y, r3.x, l(128.000000) + 133 0x00001008: ge r1.z, r3.x, l(200.000000) + 134 0x00001024: dp3 r2.x, l(0.250000, 0.500000, 0.250000, 0.000000), r12.xyzx + 135 0x0000104C: dp3 r2.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r12.xyzx + 136 0x00001074: dp2 r2.z, l(0.500000, -0.500000, 0.000000, 0.000000), r12.xzxx + 137 0x0000109C: sample_indexable(texture2d)(float,float,float,float) r3.xyz, r6.zwzz, t1.xyzw, s0 + 138 0x000010C8: max r3.xyz, r3.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 139 0x000010F0: dp3 r1.w, r3.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 140 0x00001118: add r1.w, r1.w, l(1.000000) + 141 0x00001134: div r3.xyz, r3.xyzx, r1.wwww + 142 0x00001150: dp3 r5.x, l(0.250000, 0.500000, 0.250000, 0.000000), r3.xyzx + 143 0x00001178: dp3 r5.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r3.xyzx + 144 0x000011A0: dp2 r5.z, l(0.500000, -0.500000, 0.000000, 0.000000), r3.xzxx + 145 0x000011C8: max r3.xyz, r2.xyzx, r5.xyzx + 146 0x000011E4: min r2.xyz, r2.xyzx, r5.xyzx + 147 0x00001200: sample_indexable(texture2d)(float,float,float,float) r5.xyz, r0.xyxx, t1.xyzw, s0 + 148 0x0000122C: max r5.xyz, r5.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 149 0x00001254: dp3 r0.x, r5.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 150 0x0000127C: add r0.x, r0.x, l(1.000000) + 151 0x00001298: div r5.xyz, r5.xyzx, r0.xxxx + 152 0x000012B4: dp3 r13.x, l(0.250000, 0.500000, 0.250000, 0.000000), r5.xyzx + 153 0x000012DC: dp3 r13.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r5.xyzx + 154 0x00001304: dp2 r13.z, l(0.500000, -0.500000, 0.000000, 0.000000), r5.xzxx + 155 0x0000132C: max r5.xyz, r3.xyzx, r13.xyzx + 156 0x00001348: min r13.xyz, r2.xyzx, r13.xyzx + 157 0x00001364: sample_indexable(texture2d)(float,float,float,float) r7.xyz, r7.zwzz, t1.xyzw, s0 + 158 0x00001390: max r7.xyz, r7.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 159 0x000013B8: dp3 r0.x, r7.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 160 0x000013E0: add r0.x, r0.x, l(1.000000) + 161 0x000013FC: div r7.xyz, r7.xyzx, r0.xxxx + 162 0x00001418: dp3 r14.x, l(0.250000, 0.500000, 0.250000, 0.000000), r7.xyzx + 163 0x00001440: dp3 r14.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r7.xyzx + 164 0x00001468: dp2 r14.z, l(0.500000, -0.500000, 0.000000, 0.000000), r7.xzxx + 165 0x00001490: max r5.xyz, r5.xyzx, r14.xyzx + 166 0x000014AC: min r7.xyz, r13.xyzx, r14.xyzx + 167 0x000014C8: max r3.xyz, r3.xyzx, r14.xyzx + 168 0x000014E4: min r2.xyz, r2.xyzx, r14.xyzx + 169 0x00001500: sample_indexable(texture2d)(float,float,float,float) r8.xyz, r8.zwzz, t1.xyzw, s0 + 170 0x0000152C: max r8.xyz, r8.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 171 0x00001554: dp3 r0.x, r8.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 172 0x0000157C: add r0.x, r0.x, l(1.000000) + 173 0x00001598: div r8.xyz, r8.xyzx, r0.xxxx + 174 0x000015B4: dp3 r13.x, l(0.250000, 0.500000, 0.250000, 0.000000), r8.xyzx + 175 0x000015DC: dp3 r13.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r8.xyzx + 176 0x00001604: dp2 r13.z, l(0.500000, -0.500000, 0.000000, 0.000000), r8.xzxx + 177 0x0000162C: max r5.xyz, r5.xyzx, r13.xyzx + 178 0x00001648: min r7.xyz, r7.xyzx, r13.xyzx + 179 0x00001664: sample_indexable(texture2d)(float,float,float,float) r8.xyz, r9.zwzz, t1.xyzw, s0 + 180 0x00001690: max r8.xyz, r8.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 181 0x000016B8: dp3 r0.x, r8.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 182 0x000016E0: add r0.x, r0.x, l(1.000000) + 183 0x000016FC: div r8.xyz, r8.xyzx, r0.xxxx + 184 0x00001718: dp3 r9.x, l(0.250000, 0.500000, 0.250000, 0.000000), r8.xyzx + 185 0x00001740: dp3 r9.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r8.xyzx + 186 0x00001768: dp2 r9.z, l(0.500000, -0.500000, 0.000000, 0.000000), r8.xzxx + 187 0x00001790: max r5.xyz, r5.xyzx, r9.xyzx + 188 0x000017AC: min r7.xyz, r7.xyzx, r9.xyzx + 189 0x000017C8: max r3.xyz, r3.xyzx, r9.xyzx + 190 0x000017E4: min r2.xyz, r2.xyzx, r9.xyzx + 191 0x00001800: sample_indexable(texture2d)(float,float,float,float) r0.xyz, r0.zwzz, t1.xyzw, s0 + 192 0x0000182C: max r0.xyz, r0.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 193 0x00001854: dp3 r0.w, r0.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 194 0x0000187C: add r0.w, r0.w, l(1.000000) + 195 0x00001898: div r0.xyz, r0.xyzx, r0.wwww + 196 0x000018B4: dp3 r8.x, l(0.250000, 0.500000, 0.250000, 0.000000), r0.xyzx + 197 0x000018DC: dp3 r8.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r0.xyzx + 198 0x00001904: dp2 r8.z, l(0.500000, -0.500000, 0.000000, 0.000000), r0.xzxx + 199 0x0000192C: max r0.xyz, r5.xyzx, r8.xyzx + 200 0x00001948: min r5.xyz, r7.xyzx, r8.xyzx + 201 0x00001964: sample_indexable(texture2d)(float,float,float,float) r7.xyz, r10.zwzz, t1.xyzw, s0 + 202 0x00001990: max r7.xyz, r7.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 203 0x000019B8: dp3 r0.w, r7.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 204 0x000019E0: add r0.w, r0.w, l(1.000000) + 205 0x000019FC: div r7.xyz, r7.xyzx, r0.wwww + 206 0x00001A18: dp3 r8.x, l(0.250000, 0.500000, 0.250000, 0.000000), r7.xyzx + 207 0x00001A40: dp3 r8.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r7.xyzx + 208 0x00001A68: dp2 r8.z, l(0.500000, -0.500000, 0.000000, 0.000000), r7.xzxx + 209 0x00001A90: max r0.xyz, r0.xyzx, r8.xyzx + 210 0x00001AAC: min r5.xyz, r5.xyzx, r8.xyzx + 211 0x00001AC8: max r3.xyz, r3.xyzx, r8.xyzx + 212 0x00001AE4: min r2.xyz, r2.xyzx, r8.xyzx + 213 0x00001B00: sample_indexable(texture2d)(float,float,float,float) r7.xyz, r11.zwzz, t1.xyzw, s0 + 214 0x00001B2C: max r7.xyz, r7.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 215 0x00001B54: dp3 r0.w, r7.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 216 0x00001B7C: add r0.w, r0.w, l(1.000000) + 217 0x00001B98: div r7.xyz, r7.xyzx, r0.wwww + 218 0x00001BB4: dp3 r8.x, l(0.250000, 0.500000, 0.250000, 0.000000), r7.xyzx + 219 0x00001BDC: dp3 r8.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r7.xyzx + 220 0x00001C04: dp2 r8.z, l(0.500000, -0.500000, 0.000000, 0.000000), r7.xzxx + 221 0x00001C2C: max r0.xyz, r0.xyzx, r8.xyzx + 222 0x00001C48: min r5.xyz, r5.xyzx, r8.xyzx + 223 0x00001C64: add r0.xyz, r3.xyzx, r0.xyzx + 224 0x00001C80: mul r0.xyz, r0.xyzx, l(0.500000, 0.500000, 0.500000, 0.000000) + 225 0x00001CA8: add r2.xyz, r2.xyzx, r5.xyzx + 226 0x00001CC4: mul r2.xyz, r2.xyzx, l(0.500000, 0.500000, 0.500000, 0.000000) + 227 0x00001CEC: mad r3.xy, r6.yxyy, cb0[32].xyxx, l(-0.500000, -0.500000, 0.000000, 0.000000) + 228 0x00001D20: round_ni r3.xy, r3.xyxx + 229 0x00001D34: add r5.xyzw, r3.xyxy, l(0.500000, 0.500000, -0.500000, -0.500000) + 230 0x00001D5C: mad r3.zw, r6.xxxy, cb0[32].yyyx, -r5.yyyx + 231 0x00001D88: mul r6.xy, r3.wzww, r3.wzww + 232 0x00001DA4: mul r6.zw, r3.wwwz, r6.xxxy + 233 0x00001DC0: mad r7.xy, r6.yxyy, r3.zwzz, r3.zwzz + 234 0x00001DE4: mad r7.xy, -r7.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000), r6.yxyy + 235 0x00001E18: mul r7.zw, r6.yyyx, l(0.000000, 0.000000, 2.500000, 2.500000) + 236 0x00001E40: mad r6.zw, r6.wwwz, l(0.000000, 0.000000, 1.500000, 1.500000), -r7.zzzw + 237 0x00001E74: add r6.zw, r6.zzzw, l(0.000000, 0.000000, 1.000000, 1.000000) + 238 0x00001E9C: mad r3.zw, r6.xxxy, r3.wwwz, -r6.xxxy + 239 0x00001EC4: mul r6.xy, r3.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000) + 240 0x00001EEC: add r7.zw, -r7.yyyx, l(0.000000, 0.000000, 1.000000, 1.000000) + 241 0x00001F18: add r7.zw, -r6.wwwz, r7.zzzw + 242 0x00001F38: mad r3.zw, -r3.zzzw, l(0.000000, 0.000000, 0.500000, 0.500000), r7.zzzw + 243 0x00001F6C: add r6.zw, r3.wwwz, r6.zzzw + 244 0x00001F88: div r3.zw, r3.zzzw, r6.wwwz + 245 0x00001FA4: add r3.zw, r3.zzzw, r5.xxxy + 246 0x00001FC0: add r3.xy, r3.xyxx, l(2.500000, 2.500000, 0.000000, 0.000000) + 247 0x00001FE8: mul r5.xw, r5.zzzw, cb0[32].zzzw + 248 0x00002008: mul r5.yz, r3.wwzw, cb0[32].wwzw + 249 0x00002028: mul r3.xy, r3.xyxx, cb0[32].zwzz + 250 0x00002048: sample_indexable(texture2d)(float,float,float,float) r8.xyz, r5.xwxx, t2.xyzw, s1 + 251 0x00002074: sample_indexable(texture2d)(float,float,float,float) r9.xyz, r5.zwzz, t2.xyzw, s1 + 252 0x000020A0: mov r3.zw, r5.wwwy + 253 0x000020B4: sample_indexable(texture2d)(float,float,float,float) r10.xyz, r3.xzxx, t2.xyzw, s1 + 254 0x000020E0: sample_indexable(texture2d)(float,float,float,float) r11.xyz, r5.xyxx, t2.xyzw, s1 + 255 0x0000210C: sample_indexable(texture2d)(float,float,float,float) r13.xyz, r5.zyzz, t2.xyzw, s1 + 256 0x00002138: sample_indexable(texture2d)(float,float,float,float) r14.xyz, r3.xwxx, t2.xyzw, s1 + 257 0x00002164: mov r5.y, r3.y + 258 0x00002178: sample_indexable(texture2d)(float,float,float,float) r15.xyz, r5.xyxx, t2.xyzw, s1 + 259 0x000021A4: sample_indexable(texture2d)(float,float,float,float) r5.xyz, r5.zyzz, t2.xyzw, s1 + 260 0x000021D0: sample_indexable(texture2d)(float,float,float,float) r3.xyz, r3.xyxx, t2.xyzw, s1 + 261 0x000021FC: mul r0.w, r7.x, r7.y + 262 0x00002218: mul r7.zw, r7.xxxy, r6.wwwz + 263 0x00002234: mul r9.xyz, r7.zzzz, r9.xyzx + 264 0x00002250: mul r7.xy, r7.xyxx, r6.xyxx + 265 0x0000226C: mul r1.w, r6.z, r6.w + 266 0x00002288: mul r6.zw, r6.zzzw, r6.xxxy + 267 0x000022A4: mul r2.w, r6.y, r6.x + 268 0x000022C0: mad r8.xyz, r8.xyzx, r0.wwww, r9.xyzx + 269 0x000022E4: mad r8.xyz, r10.xyzx, r7.xxxx, r8.xyzx + 270 0x00002308: mad r7.xzw, r11.xxyz, r7.wwww, r8.xxyz + 271 0x0000232C: mad r7.xzw, r13.xxyz, r1.wwww, r7.xxzw + 272 0x00002350: mad r6.xyz, r14.xyzx, r6.zzzz, r7.xzwx + 273 0x00002374: mad r6.xyz, r15.xyzx, r7.yyyy, r6.xyzx + 274 0x00002398: mad r5.xyz, r5.xyzx, r6.wwww, r6.xyzx + 275 0x000023BC: mad r3.xyz, r3.xyzx, r2.wwww, r5.xyzx + 276 0x000023E0: max r3.xyz, r3.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000) + 277 0x00002408: dp3 r0.w, r3.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 278 0x00002430: add r0.w, r0.w, l(1.000000) + 279 0x0000244C: div r3.xyz, r3.xyzx, r0.wwww + 280 0x00002468: dp3 r5.x, l(0.250000, 0.500000, 0.250000, 0.000000), r3.xyzx + 281 0x00002490: dp3 r5.y, l(-0.250000, 0.500000, -0.250000, 0.000000), r3.xyzx + 282 0x000024B8: dp2 r5.z, l(0.500000, -0.500000, 0.000000, 0.000000), r3.xzxx + 283 0x000024E0: max r2.xyz, r2.xyzx, r5.xyzx + 284 0x000024FC: min r0.xyz, r0.xyzx, r2.xyzx + 285 0x00002518: dp3 r2.x, l(1.000000, -1.000000, 1.000000, 0.000000), r0.xyzx + 286 0x00002540: dp2 r2.y, l(1.000000, 1.000000, 0.000000, 0.000000), r0.xyxx + 287 0x00002568: dp3 r2.z, l(1.000000, -1.000000, -1.000000, 0.000000), r0.xyzx + 288 0x00002590: mul r0.xyz, cb0[31].zzzz, l(0.200000, 0.400000, 0.600000, 0.000000) + 289 0x000025BC: movc r0.y, r1.z, r0.y, r0.z + 290 0x000025E0: movc r0.x, r1.y, r0.x, r0.y + 291 0x00002604: add r0.x, -r0.x, l(1.000000) + 292 0x00002624: movc r0.x, r1.x, l(0.500000), r0.x + 293 0x00002648: add r0.y, -r0.x, l(1.000000) + 294 0x00002668: mul r0.xzw, r2.xxyz, r0.xxxx + 295 0x00002684: mad r0.xyz, r0.yyyy, r12.xyzx, r0.xzwx + 296 0x000026A8: dp3 r0.w, r0.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) + 297 0x000026D0: add r0.w, -r0.w, l(1.000000) + 298 0x000026F0: max r0.w, r0.w, l(0.000001) + 299 0x0000270C: div r0.xyz, r0.xyzx, r0.wwww + 300 0x00002728: and r1.xyz, r0.xyzx, l(0x7f800000, 0x7f800000, 0x7f800000, 0) + 301 0x00002750: ieq r1.xyz, r1.xyzx, l(0x7f800000, 0x7f800000, 0x7f800000, 0) + 302 0x00002778: movc o0.xyz, r1.xyzx, l(65000.000000,65000.000000,65000.000000,0), r0.xyzx + 303 0x000027A8: mov o0.w, r12.w + 304 0x000027BC: endif + 305 0x000027C0: else + 306 0x000027C4: mov o0.xyzw, r4.xyzw + 307 0x000027D8: endif + 308 0x000027DC: ret +// Approximately 0 instruction slots used + +*/ \ No newline at end of file diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 02cabf37..bb72d7ab 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -605,21 +605,21 @@ class MiddleEarthShadowOfWar final : public Game } // SECTION: SR - ImGui::PushID("Super Resolution Header Tab"); //conflicts if not pushed - bool show_sr_settings = ImGui::CollapsingHeader("Super Resolution"); - ImGui::PopID(); - if (show_sr_settings) + if (ImGui::CollapsingHeader("Temporal Anti-Aliasing")) { if (device_data.sr_type == SR::Type::None) { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.f)); - ImGui::TextWrapped("Inactive..."); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f * 0.5, 1.f * 0.5, 1.f * 0.5, 1.f)); + ImGui::TextWrapped("[Super Resolution: Disabled]"); ImGui::PopStyleColor(); + + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Vanilla TAA is pending a fix.\nIt'll artefact to black for extremely bright highlights."); + } else { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); - ImGui::TextWrapped("[In-game Graphics Settings]"); + ImGui::TextWrapped("[Super Resolution: Enabled]"); ImGui::PopStyleColor(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); @@ -628,7 +628,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::NewLine(); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); - ImGui::TextWrapped("[Bloom & Other FX Missing Fix]"); + ImGui::TextWrapped("[Super Resolution: Bloom & Transparency Missing Fix]"); ImGui::PopStyleColor(); ImGui::PushID("SR: copy_resource"); @@ -654,7 +654,7 @@ class MiddleEarthShadowOfWar final : public Game } ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance. Unnoticeable?\nMay change more than just texture detail.\nWill costs some performance."); + ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance, though unnoticeable?\nMay change more than just texture detail.\nWill costs some performance."); DrawResetButton(sr_user_allow_upgraded_samplers, false, "sr_user_allow_upgraded_samplers", runtime); } From 43f16491a1c9e2b64ff44c0f60711a63bd72a162 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 23:26:49 -0700 Subject: [PATCH 08/33] Shadow of War: Don't exec SR code if off. Reduced Namespaces. --- .../Games/Middle-earth Shadow of War/main.cpp | 222 ++++++++---------- 1 file changed, 102 insertions(+), 120 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index bb72d7ab..ffa730bf 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -17,9 +17,18 @@ namespace const ShaderHashesList shader_hashes_photomode_exposure = {.pixel_shaders = {0xF4316866}}; const ShaderHashesList shader_hashes_swapchain = {.pixel_shaders = {0x68EABB8D, 0x09C22C0E}}; + // Hashes for new Shader Defines + constexpr uint32_t GAMMA_CORRECT_CUSTOM = char_ptr_crc32("GAMMA_CORRECT_CUSTOM"); + constexpr uint32_t TEST_USER_PEAK = char_ptr_crc32("TEST_USER_PEAK"); + constexpr uint32_t FIRE_RETUNED = char_ptr_crc32("FIRE_RETUNED"); + constexpr uint32_t RCAS_ENABLED = char_ptr_crc32("RCAS_ENABLED"); + // Jitter from TAA cb float g_jitter_x; float g_jitter_y; + + // A copy of device_data.sr_type + SR::Type sr_type_copy = SR::Type::None; bool is_ui = true; // User toggle for UI skip draw bool sr_copy_resource = false; // User toggle to exec CopyResource() to fix missing bloom @@ -155,61 +164,9 @@ namespace DisplayMode } } -// Constant Buffer variables, grouped here to allow easier editing. -namespace CB -{ - static void OnInit() - { - // Set Defaults - default_luma_global_game_settings.WhiteClip = cb_luma_global_settings.GameSettings.WhiteClip = 1.; - default_luma_global_game_settings.BlowoutCorrection = cb_luma_global_settings.GameSettings.BlowoutCorrection = 0.3; - default_luma_global_game_settings.GodRays = cb_luma_global_settings.GameSettings.GodRays = 1.; - default_luma_global_game_settings.Bloom = cb_luma_global_settings.GameSettings.Bloom = 1.; - default_luma_global_game_settings.RCAS = cb_luma_global_settings.GameSettings.RCAS = 0.; - } - - static void OnLoadConfigs(reshade::api::effect_runtime* runtime) - { - // Load configs - reshade::get_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); - reshade::get_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); - reshade::get_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); - reshade::get_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); - reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); - } -} - -// Shader Defines, with helpers to draw ImGui for them +// Shader Defines helpers to draw ImGui namespace ShaderDefines { - // Hashes for new defines - constexpr uint32_t GAMMA_CORRECT_CUSTOM = char_ptr_crc32("GAMMA_CORRECT_CUSTOM"); - constexpr uint32_t TEST_USER_PEAK = char_ptr_crc32("TEST_USER_PEAK"); - constexpr uint32_t FIRE_RETUNED = char_ptr_crc32("FIRE_RETUNED"); - constexpr uint32_t RCAS_ENABLED = char_ptr_crc32("RCAS_ENABLED"); - - // Append new & change defaults - void OnInit() - { - // New - static const std::vector game_shader_defines_data = { - {"GAMMA_CORRECTION_RANGE_TYPE", '0', true, !DEVELOPMENT, "0 - Full range.\n1 - 0-1 only.", 1}, - {"TEST_USER_PEAK", '0', true, false, "Show white rectangles for peak test.", 1}, - {"GAMMA_CORRECT_CUSTOM", '1', true, false, "Correct gamma decode, lowering shadows to match SDR.", 1}, - {"FIRE_RETUNED", '1', true, false, "Retuned fire shader to reduce clipping.", 1}, - {"RCAS_ENABLED", '0', true, false, "Robust Contrast Adaptive Sharpening.", 1}, - }; - shader_defines_data.append_range(game_shader_defines_data); - - // Change defaults - GetShaderDefineData(POST_PROCESS_SPACE_TYPE_HASH).SetDefaultValue('1'); // linear - GetShaderDefineData(GAMMA_CORRECTION_TYPE_HASH).SetDefaultValue('0'); // don't use built in gamma correction - GetShaderDefineData(UI_DRAW_TYPE_HASH).SetDefaultValue('2'); // Direct (inverse scene brightness draws) - - // Force - auto_recompile_defines = true; - } - static char InvertCharBool(char b) { return b == '0' ? '1' : '0'; @@ -347,11 +304,30 @@ class MiddleEarthShadowOfWar final : public Game // log message(reshade::log::level::info, "OnInit()"); - // Shader Defines append new & change defaults - ShaderDefines::OnInit(); + // Shader Defines: append new + static const std::vector game_shader_defines_data = { + {"GAMMA_CORRECTION_RANGE_TYPE", '0', true, !DEVELOPMENT, "0 - Full range.\n1 - 0-1 only.", 1}, + {"TEST_USER_PEAK", '0', true, false, "Show white rectangles for peak test.", 1}, + {"GAMMA_CORRECT_CUSTOM", '1', true, false, "Correct gamma decode, lowering shadows to match SDR.", 1}, + {"FIRE_RETUNED", '1', true, false, "Retuned fire shader to reduce clipping.", 1}, + {"RCAS_ENABLED", '0', true, false, "Robust Contrast Adaptive Sharpening.", 1}, + }; + shader_defines_data.append_range(game_shader_defines_data); + + // Shader Defines: change defaults + GetShaderDefineData(POST_PROCESS_SPACE_TYPE_HASH).SetDefaultValue('1'); // linear + GetShaderDefineData(GAMMA_CORRECTION_TYPE_HASH).SetDefaultValue('0'); // don't use built in gamma correction + GetShaderDefineData(UI_DRAW_TYPE_HASH).SetDefaultValue('2'); // Direct (inverse scene brightness draws) + + // Force + auto_recompile_defines = true; // CB init default values - CB::OnInit(); + default_luma_global_game_settings.WhiteClip = cb_luma_global_settings.GameSettings.WhiteClip = 1.; + default_luma_global_game_settings.BlowoutCorrection = cb_luma_global_settings.GameSettings.BlowoutCorrection = 0.3; + default_luma_global_game_settings.GodRays = cb_luma_global_settings.GameSettings.GodRays = 1.; + default_luma_global_game_settings.Bloom = cb_luma_global_settings.GameSettings.Bloom = 1.; + default_luma_global_game_settings.RCAS = cb_luma_global_settings.GameSettings.RCAS = 0.; // UI Buffer Indirect Upgrades { @@ -382,7 +358,10 @@ class MiddleEarthShadowOfWar final : public Game static bool OnUpdateBufferRegion(reshade::api::device* device, const void* data, reshade::api::resource resource, uint64_t offset, uint64_t size) { - // Find TAA jitter offset + // RETURN: no SR + if (sr_type_copy == SR::Type::None) return false; + + // Find TAA jitter auto native_resource = (ID3D11Resource*)resource.handle; ComPtr buffer; auto hr = native_resource->QueryInterface(buffer.put()); @@ -407,8 +386,8 @@ class MiddleEarthShadowOfWar final : public Game auto& game_device_data = GetGameDeviceData(device_data); auto& managed_resources = game_device_data.managed_resources; - // Motion Vectors - if (original_shader_hashes.Contains(shader_hashes_linearize_depth_and_generate_mvs)) + // Depth & Motion Vectors (SR) + if (device_data.sr_type != SR::Type::None && original_shader_hashes.Contains(shader_hashes_linearize_depth_and_generate_mvs)) { // Take depth ComPtr srv; @@ -417,76 +396,74 @@ class MiddleEarthShadowOfWar final : public Game return DrawOrDispatchOverrideType::None; } - // TAA - if (original_shader_hashes.Contains(shader_hashes_TAA)) + // TODO AO + + // TAA (SR) + if (device_data.sr_type != SR::Type::None && original_shader_hashes.Contains(shader_hashes_TAA)) { - if (device_data.sr_type != SR::Type::None) - { - // DLSS requires an immediate context for execution! - ASSERT_ONCE(native_device_context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); + // DLSS requires an immediate context for execution! + ASSERT_ONCE(native_device_context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - // Settings - auto* sr_instance_data = device_data.GetSRInstanceData(); - ASSERT_ONCE(sr_instance_data); + // Settings + auto* sr_instance_data = device_data.GetSRInstanceData(); + ASSERT_ONCE(sr_instance_data); - SR::SettingsData settings_data; - settings_data.output_width = device_data.output_resolution.x; - settings_data.output_height = device_data.output_resolution.y; - settings_data.render_width = device_data.render_resolution.x; - settings_data.render_height = device_data.render_resolution.y; - settings_data.dynamic_resolution = false; - settings_data.hdr = true; - settings_data.inverted_depth = true; - settings_data.mvs_jittered = false; + SR::SettingsData settings_data; + settings_data.output_width = device_data.output_resolution.x; + settings_data.output_height = device_data.output_resolution.y; + settings_data.render_width = device_data.render_resolution.x; + settings_data.render_height = device_data.render_resolution.y; + settings_data.dynamic_resolution = false; + settings_data.hdr = true; + settings_data.inverted_depth = true; + settings_data.mvs_jittered = false; - // MVs are in UV space so we need to scale them to screen space for DLSS. - settings_data.mvs_x_scale = -device_data.render_resolution.x; - settings_data.mvs_y_scale = -device_data.render_resolution.y; + // MVs are in UV space so we need to scale them to screen space for DLSS. + settings_data.mvs_x_scale = -device_data.render_resolution.x; + settings_data.mvs_y_scale = -device_data.render_resolution.y; - settings_data.render_preset = dlss_render_preset; - settings_data.auto_exposure = true; + settings_data.render_preset = dlss_render_preset; + settings_data.auto_exposure = true; - sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); + sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); - // Get resources - std::array srvs; - native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); + // Get resources + std::array srvs; + native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); - ComPtr resource_mvs; - srvs[0]->GetResource(resource_mvs.put()); - ComPtr resource_scene; - srvs[1]->GetResource(resource_scene.put()); + ComPtr resource_mvs; + srvs[0]->GetResource(resource_mvs.put()); + ComPtr resource_scene; + srvs[1]->GetResource(resource_scene.put()); - ComPtr rtv; - native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); - ComPtr resource_rt; - rtv->GetResource(resource_rt.put()); + ComPtr rtv; + native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); + ComPtr resource_rt; + rtv->GetResource(resource_rt.put()); - SR::SuperResolutionImpl::DrawData draw_data; - draw_data.source_color = resource_scene.get(); - draw_data.output_color = resource_rt.get(); - draw_data.motion_vectors = resource_mvs.get(); - draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); + SR::SuperResolutionImpl::DrawData draw_data; + draw_data.source_color = resource_scene.get(); + draw_data.output_color = resource_rt.get(); + draw_data.motion_vectors = resource_mvs.get(); + draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); - // Jitters are in range [-1, 1]. - draw_data.jitter_x = g_jitter_x * -0.5f; - draw_data.jitter_y = g_jitter_y * 0.5f; + // Jitters are in range [-1, 1]. + draw_data.jitter_x = g_jitter_x * -0.5f; + draw_data.jitter_y = g_jitter_y * 0.5f; - draw_data.render_width = device_data.render_resolution.x; - draw_data.render_height = device_data.render_resolution.y; + draw_data.render_width = device_data.render_resolution.x; + draw_data.render_height = device_data.render_resolution.y; - // DRAW - device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); + // DRAW + device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); - // Copy back to input, fixing missing transparency FXs. - if (sr_copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); + // Copy back to input, fixing missing transparency FXs. + if (sr_copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); - // Reset pointers - ResetCOMArray(srvs); + // Reset pointers + ResetCOMArray(srvs); - return DrawOrDispatchOverrideType::Replaced; - } - return DrawOrDispatchOverrideType::None; + return DrawOrDispatchOverrideType::Replaced; } // Tonemap @@ -516,11 +493,12 @@ class MiddleEarthShadowOfWar final : public Game { auto& game_device_data = GetGameDeviceData(device_data); - // game_device_data reset state tracking + // game_device_data reset pipeline state tracking game_device_data.ResetDrawnState(); // force_reset_sr if (!device_data.has_drawn_sr) device_data.force_reset_sr = true; + sr_type_copy = device_data.sr_type; // texture_mip_lod_bias_offset if (!custom_texture_mip_lod_bias_offset) @@ -543,7 +521,11 @@ class MiddleEarthShadowOfWar final : public Game reshade::api::effect_runtime* runtime = nullptr; // CB load user - CB::OnLoadConfigs(runtime); + reshade::get_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); + reshade::get_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); + reshade::get_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); + reshade::get_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); + reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); // SRUser reshade::get_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); @@ -564,7 +546,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::TextWrapped("[Windows' gamma decode in HDR is weaker than in SDR, causing washed out shadows.]"); ImGui::PopStyleColor(); - ShaderDefines::UIToggleCheckmark(ShaderDefines::GAMMA_CORRECT_CUSTOM, "Enable Correction", "sRGB -> 2.2"); + ShaderDefines::UIToggleCheckmark(GAMMA_CORRECT_CUSTOM, "Enable Correction", "sRGB -> 2.2"); if (ImGui::Button("Further Explanation & Test (Google Slides)")) Website::OpenWebsite("https://docs.google.com/presentation/d/e/2PACX-1vSXeLHlbm6repcS7fels1-SXYGRmzziRrnuJ8nDO8J5rsWV3dT1-nVyCKp0Tj_stwx-9qlCI-N6rYIT/pub?start=false&loop=false&slide=id.g3e007eafba8_0_0"); @@ -578,7 +560,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("(Use default Luma sliders above.)"); - ShaderDefines::UIToggleCheckmark(ShaderDefines::TEST_USER_PEAK, "Test Pattern (Read Tooltip)", "3 rectangles inside a big one.\n- Left should disappear.\n- Middle should be barely visible.\n- Right should be easy to see."); + ShaderDefines::UIToggleCheckmark(TEST_USER_PEAK, "Test Pattern (Read Tooltip)", "3 rectangles inside a big one.\n- Left should disappear.\n- Middle should be barely visible.\n- Right should be easy to see."); ImGui::NewLine(); @@ -687,7 +669,7 @@ class MiddleEarthShadowOfWar final : public Game if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Robust Contrast Adaptive Sharpening on scene color."); DrawResetButton(cb_luma_global_settings.GameSettings.RCAS, default_luma_global_game_settings.RCAS, "RCAS", runtime); - ShaderDefines::Set(ShaderDefines::RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh + ShaderDefines::Set(RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh // TODO: AO @@ -708,7 +690,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("This changes its style, becoming more lava-ish orange."); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("If off, shaders will intentionally break, so just ignore the warning. Thanks!"); - ShaderDefines::UIToggleCheckmark(ShaderDefines::FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); + ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); } if (DEVELOPMENT) ImGui::Separator(); //////////////////////////////////////////////////////////////////////////// @@ -727,7 +709,7 @@ class MiddleEarthShadowOfWar final : public Game void OnDisplayModeChanged() { // FORCED: Gamma Correct - ShaderDefines::Set(ShaderDefines::GAMMA_CORRECT_CUSTOM, DisplayMode::IsHDR()); + ShaderDefines::Set(GAMMA_CORRECT_CUSTOM, DisplayMode::IsHDR()); } }; From a0359a7c331d3d8db2d04042ceac411ee3354ddd Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 23:33:53 -0700 Subject: [PATCH 09/33] Shadow of War: fixes --- Source/Games/Middle-earth Shadow of War/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index ffa730bf..a76af21d 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -306,7 +306,6 @@ class MiddleEarthShadowOfWar final : public Game // Shader Defines: append new static const std::vector game_shader_defines_data = { - {"GAMMA_CORRECTION_RANGE_TYPE", '0', true, !DEVELOPMENT, "0 - Full range.\n1 - 0-1 only.", 1}, {"TEST_USER_PEAK", '0', true, false, "Show white rectangles for peak test.", 1}, {"GAMMA_CORRECT_CUSTOM", '1', true, false, "Correct gamma decode, lowering shadows to match SDR.", 1}, {"FIRE_RETUNED", '1', true, false, "Retuned fire shader to reduce clipping.", 1}, @@ -498,13 +497,15 @@ class MiddleEarthShadowOfWar final : public Game // force_reset_sr if (!device_data.has_drawn_sr) device_data.force_reset_sr = true; + + // save to sr_type_copy sr_type_copy = device_data.sr_type; // texture_mip_lod_bias_offset if (!custom_texture_mip_lod_bias_offset) { std::shared_lock shared_lock_samplers(s_mutex_samplers); - if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !sr_user_allow_upgraded_samplers) + if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !ignore_upgraded_samplers) { device_data.texture_mip_lod_bias_offset = SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); // This results in -1 at output res } From fcc9accbd8809c352160f3547bcd904220bb2a0e Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 19 Jul 2026 23:40:57 -0700 Subject: [PATCH 10/33] Shadow of War: DISABLE_AUTO_DEBUGGER 1 --- Source/Games/Middle-earth Shadow of War/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index a76af21d..764a1642 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -2,6 +2,8 @@ #define ENABLE_NGX 1 +#define DISABLE_AUTO_DEBUGGER 1 + #include "..\..\Core\core.hpp" // TODO: Fix this globaly? Define NOMINMAX before including windows.h. From c4b19356f2873dbdbd67d50a999103b645104b25 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 00:47:04 -0700 Subject: [PATCH 11/33] Shadow of War: Fixed unreadable text color --- Source/Games/Middle-earth Shadow of War/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 764a1642..e6c3c951 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -594,7 +594,7 @@ class MiddleEarthShadowOfWar final : public Game { if (device_data.sr_type == SR::Type::None) { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f * 0.5, 1.f * 0.5, 1.f * 0.5, 1.f)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 0.75f, 0.75f, 1.f)); ImGui::TextWrapped("[Super Resolution: Disabled]"); ImGui::PopStyleColor(); From 57c91e7a7bc35a2159a03670ded53dba2f9d6006 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 00:51:45 -0700 Subject: [PATCH 12/33] Shadow of War: Removed duplicated shader --- ...12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl | 106 ------------------ 1 file changed, 106 deletions(-) delete mode 100644 Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl diff --git a/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl deleted file mode 100644 index 71aba26d..00000000 --- a/Shaders/Middle-earth Shadow of War/fire12_psaddsoftdistlut_0x922EBCCE.ps_5_0.hlsl +++ /dev/null @@ -1,106 +0,0 @@ -// ---- Created with 3Dmigoto v1.3.16 on Thu Jul 16 19:31:34 2026 -Texture2DArray t3 : register(t3); - -Texture2D t2 : register(t2); - -Texture2DArray t1 : register(t1); - -Texture2D t0 : register(t0); - -SamplerState s3_s : register(s3); - -SamplerState s2_s : register(s2); - -SamplerState s1_s : register(s1); - -SamplerState s0_s : register(s0); - -cbuffer cb2 : register(b2) -{ - float4 cb2[53]; -} - -cbuffer cb3 : register(b3) -{ - float4 cb3[8]; -} - -cbuffer cb1 : register(b1) -{ - float4 cb1[2]; -} - -#if FIRE_RETUNED == 0 -LET_THIS_BREAK -#endif -// 3Dmigoto declarations -#define cmp - -#include "./common.hlsl" - -void main( - float4 v0 : SV_POSITION0, - float4 v1 : TEXCOORD0, - float4 v2 : TEXCOORD2, - float4 v3 : TEXCOORD1, - float4 v4 : COLOR0, - uint v5 : SV_IsFrontFace0, - out float4 o0 : SV_Target0) -{ - float4 r0,r1; - uint4 bitmask, uiDest; - float4 fDest; - - r0.x = cb3[4].w * v1.x; - r0.y = cb3[5].x * v1.y; - r0.xy = cb1[1].xx * cb3[5].yz + r0.xy; - r0.xy = t0.Sample(s1_s, r0.xy).yw; - r0.xy = r0.xy * float2(2,2) + float2(-1,-1); - r0.z = -r0.y; - r0.xy = r0.xz * cb3[5].ww + v1.xy; - r0.z = v1.z; - r0.x = t1.Sample(s2_s, r0.xyz).x; - r0.y = 1 + cb3[6].x; - r0.y = v4.w * r0.y + r0.x; - r0.y = -1 + r0.y; - r0.z = 1 / cb3[6].x; - r0.y = saturate(r0.y * r0.z); - r0.z = r0.y * -2 + 3; - r0.y = r0.y * r0.y; - r0.y = r0.z * r0.y; - r0.z = -0.00499999989 + r0.x; - r0.x = v4.x * r0.x; - r0.z = saturate(ceil(r0.z)); - r0.y = r0.z * r0.y; - r0.x = r0.x * r0.y; - r0.x = v4.w * r0.x; - r0.yz = v3.xy / v3.ww; - r0.yz = min(cb2[22].zw, r0.yz); - r0.y = t2.Sample(s3_s, r0.yz).x; - r0.y = v3.w + -r0.y; - r0.y = saturate(abs(r0.y) / cb3[6].y); - r0.y = 1 + -r0.y; - r0.y = log2(r0.y); - r0.y = cb3[6].z * r0.y; - r0.y = exp2(r0.y); - r0.y = 1 + -r0.y; - r0.y = max(0, r0.y); - r0.x = r0.x * r0.y; - r1.x = r0.x * cb3[6].w + cb3[0].x; - r0.x = log2(r0.x); - r0.x = cb3[7].z * r0.x; - r0.x = exp2(r0.x); - r0.y = cmp(cb3[7].x < 0.5); - r1.z = r0.y ? cb3[7].y : 15; - r1.y = 0; - r1.x = FireTonemap(r1.x, FIRE_PEAK); - r0.yzw = t3.SampleLevel(s0_s, r1.xyz * 0.86, 0).xyz; - r0.yzw *= FIRE_BOOST; - r0.xyz = r0.yzw * r0.xxx; - r0.w = !cb3[1].x ? cb2[24].w : 1; - r0.xyz = r0.xyz * r0.www; - r1.xyz = cb2[26].www * r0.xyz; - r0.xyz = !cb3[1].xxx ? r1.xyz : r0.xyz; - o0.xyz = v2.www * r0.xyz; - o0.w = 0; - return; -} \ No newline at end of file From a35e79713f6fce592b40f1c7b82ff4441a489558 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 15:30:05 -0700 Subject: [PATCH 13/33] Shadow of War: DLSS Jitter History (DEVELOPMENT) --- .../Games/Middle-earth Shadow of War/main.cpp | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index e6c3c951..32e1c0fd 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -285,6 +285,49 @@ namespace Website } } +#if DEVELOPMENT +namespace JitterHistory +{ + //list + static std::vector history; + static bool is_scan = false; + + static void OnSRDraw(float2 jitter) + { + // looped? + for (const auto& j : history) + { + if (j.x == jitter.x && j.y == jitter.y) + { + is_scan = false; + return; + } + } + + // add new + history.push_back(jitter); + } + + static void DrawImGuiSettings() + { + // toggle + ImGui::PushID("JitterHistory: Scan"); + auto a = ImGui::Checkbox("Scan", &is_scan); + ImGui::PopID(); + if (a) + if (is_scan) + history.clear(); + + // list + ImGui::Text("Count: %d", static_cast(history.size())); + for (const auto& jitter : history) + { + ImGui::Text("(%f, %f)", jitter.x, jitter.y); + } + } +} +#endif + class MiddleEarthShadowOfWar final : public Game { public: @@ -297,7 +340,8 @@ class MiddleEarthShadowOfWar final : public Game { // log message(reshade::log::level::info, "OnLoad()"); - + + // Register reading CB for jitter reshade::register_event(OnUpdateBufferRegion); } @@ -451,6 +495,9 @@ class MiddleEarthShadowOfWar final : public Game // Jitters are in range [-1, 1]. draw_data.jitter_x = g_jitter_x * -0.5f; draw_data.jitter_y = g_jitter_y * 0.5f; +#if DEVELOPMENT + JitterHistory::OnSRDraw({draw_data.jitter_x, draw_data.jitter_y}); +#endif draw_data.render_width = device_data.render_resolution.x; draw_data.render_height = device_data.render_resolution.y; @@ -695,6 +742,11 @@ class MiddleEarthShadowOfWar final : public Game ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); } + +#if DEVELOPMENT + // SECTION: Jitter History + if (ImGui::CollapsingHeader("(DEVELOPMENT) Jitter History")) JitterHistory::DrawImGuiSettings(); +#endif if (DEVELOPMENT) ImGui::Separator(); //////////////////////////////////////////////////////////////////////////// } From ab5c53b279255b39ae7e93443afbc0cb515b75e7 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 15:31:47 -0700 Subject: [PATCH 14/33] Shadow of War: Fixed ImGui ID pushing --- Source/Games/Middle-earth Shadow of War/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 32e1c0fd..4342061a 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -697,6 +697,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::TextWrapped("[Various FX sliders & toggles.]"); ImGui::PopStyleColor(); + ImGui::PushID("Miscellaneous: GodRays"); if (ImGui::SliderFloat("GodRays", &cb_luma_global_settings.GameSettings.GodRays, 0.f, 2.f, "%.3f")) reshade::set_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); ImGui::PopID(); From e76a983578090bbca4c4735e6699525a1998653a Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 16:27:27 -0700 Subject: [PATCH 15/33] Shadow of War: Reword user settings --- .../Games/Middle-earth Shadow of War/main.cpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 4342061a..4ba18e10 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -619,11 +619,11 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("Peak Brightness: WhiteClip"); - if (ImGui::SliderFloat("Clip", &cb_luma_global_settings.GameSettings.WhiteClip, 0.f, 4.f, "%.3f")) + if (ImGui::SliderFloat("White Clip", &cb_luma_global_settings.GameSettings.WhiteClip, 0.f, 4.f, "%.3f")) reshade::set_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Increase to make rolloff compression straighter, where the highlights becomes more clipped."); + ImGui::SetTooltip("Increase to make rolloff compression start later, leading highlights becoming more clipped."); DrawResetButton(cb_luma_global_settings.GameSettings.WhiteClip, default_luma_global_game_settings.WhiteClip, "WhiteClip", runtime); ImGui::PushID("Peak Brightness: BlowoutCorrection"); @@ -631,9 +631,11 @@ class MiddleEarthShadowOfWar final : public Game reshade::set_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Correct the hues of new highlights using the results from SDR.\nToo high will look unnatural."); + ImGui::SetTooltip("By extending/straighting the rolloff curve to HDR, we lose the blowout originally intended by the SDR short curve.\nSo, increase to correct the hues of the new HDR highlights using the results from SDR."); DrawResetButton(cb_luma_global_settings.GameSettings.BlowoutCorrection, default_luma_global_game_settings.BlowoutCorrection, "BlowoutCorrection", runtime); + if (ImGui::Button("Extended Tonemap (Desmos)")) + Website::OpenWebsite("https://www.desmos.com/calculator/stnfdhk9t1"); } // SECTION: SR @@ -646,7 +648,6 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Vanilla TAA is pending a fix.\nIt'll artefact to black for extremely bright highlights."); - } else { @@ -655,7 +656,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); - ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Unfortunately, only 100%% internal/render resolution is supported."); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Only 100%% internal/render resolution is supported."); ImGui::NewLine(); @@ -664,11 +665,11 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("SR: copy_resource"); - if (ImGui::Checkbox("Copy Resource Fix", &sr_copy_resource)) + if (ImGui::Checkbox("Enable Fix", &sr_copy_resource)) reshade::set_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("If Bloom and other transparency are missing, enable this."); + ImGui::SetTooltip("For some reason (Motion Blur + Depth of Field?) bloom and other transparency effects may go missing after Super Resolution draws.\nEnable this to copy the output back to the input, somehow fixing the issue."); DrawResetButton(sr_copy_resource, false, "sr_copy_resource", runtime); } @@ -694,54 +695,53 @@ class MiddleEarthShadowOfWar final : public Game if (ImGui::CollapsingHeader("Miscellaneous")) { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); - ImGui::TextWrapped("[Various FX sliders & toggles.]"); + ImGui::TextWrapped("[Various sliders & toggles for FXs.]"); ImGui::PopStyleColor(); + ImGui::PushID("Miscellaneous: RCAS"); + if (ImGui::SliderFloat("Sharpening", &cb_luma_global_settings.GameSettings.RCAS, 0.f, 1.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Newly inserted Robust Contrast Adaptive Sharpening on scene color."); + DrawResetButton(cb_luma_global_settings.GameSettings.RCAS, default_luma_global_game_settings.RCAS, "RCAS", runtime); + ShaderDefines::Set(RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh + ImGui::PushID("Miscellaneous: GodRays"); - if (ImGui::SliderFloat("GodRays", &cb_luma_global_settings.GameSettings.GodRays, 0.f, 2.f, "%.3f")) + if (ImGui::SliderFloat("God Rays Strength", &cb_luma_global_settings.GameSettings.GodRays, 0.f, 2.f, "%.3f")) reshade::set_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Final god rays multiplier."); + ImGui::SetTooltip("Multiplier on God Rays results before compositing."); DrawResetButton(cb_luma_global_settings.GameSettings.GodRays, default_luma_global_game_settings.GodRays, "GodRays", runtime); ImGui::PushID("Miscellaneous: Bloom"); - if (ImGui::SliderFloat("Bloom", &cb_luma_global_settings.GameSettings.Bloom, 0.f, 2.f, "%.3f")) + if (ImGui::SliderFloat("Bloom Strength", &cb_luma_global_settings.GameSettings.Bloom, 0.f, 2.f, "%.3f")) reshade::set_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Final bloom multiplier."); + ImGui::SetTooltip("Multiplier on Bloom results before compositing."); DrawResetButton(cb_luma_global_settings.GameSettings.Bloom, default_luma_global_game_settings.Bloom, "Bloom", runtime); - ImGui::PushID("Miscellaneous: RCAS"); - if (ImGui::SliderFloat("RCAS", &cb_luma_global_settings.GameSettings.RCAS, 0.f, 1.f, "%.3f")) - reshade::set_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); - ImGui::PopID(); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Robust Contrast Adaptive Sharpening on scene color."); - DrawResetButton(cb_luma_global_settings.GameSettings.RCAS, default_luma_global_game_settings.RCAS, "RCAS", runtime); - ShaderDefines::Set(RCAS_ENABLED, cb_luma_global_settings.GameSettings.RCAS > 0.f); //bruh - // TODO: AO ImGui::PushID("Miscellaneous: UIToggle is_allowed"); - ImGui::Checkbox("UI", &is_ui); + ImGui::Checkbox("Draw UI", &is_ui); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Can skip drawing the UI (everything after tonemap shader)."); + ImGui::SetTooltip("If off all shaders after scene color gets tonemapped (UI shaders) are discarded."); ImGui::PopID(); } // SECTION: Retuned Fire - if (ImGui::CollapsingHeader("Retuned Fire")) + if (ImGui::CollapsingHeader("Fire Sprite Shaders Retuning")) { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); - ImGui::TextWrapped("[Alleviates clipping for fire texture sprites.]"); + ImGui::TextWrapped("[Reduce clipping for fire shaders.]"); ImGui::PopStyleColor(); - ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("This changes its style, becoming more lava-ish orange."); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("If off, shaders will intentionally break, so just ignore the warning. Thanks!"); - ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning", "Reduces fire texture clipping."); + ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning (Read Tooltips)", "\"Pick your poison...\"\n\nThe devs allowed their artists to tune the brightness curve of their fire sprites.\nHowever, they're boosted so high that the brightness -> color look up is clipped!\nIt is rather apparent for HDR, though not as much for SDR.\n\nEnabling this will reduces the clipping, but also makes them more orange.\nUnintended, but more preferable?"); } #if DEVELOPMENT From 60eebf41ccd130844f7fb5be75dcd3533426934d Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 17:15:01 -0700 Subject: [PATCH 16/33] Shadow of War: Cleaned Shaders --- .../Includes/Common.hlsl | 7 -- ...adialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 | 0 .../computeexposure_0xD2356014.cs_5_0.hlsl 1 | 0 .../motionblur_0xB3DC1377.ps_5_0.hlsl 1 | 2 +- ...otomode_exposure_0xF4316866.ps_5_0.hlsl 1} | 10 +- .../solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 | 3 - .../taa_0x8D06D556.ps_5_0.hlsl 1 | 11 +- ...withexposure_hdr_0xA4592384.ps_5_0.hlsl 1} | 14 +-- .../bloomblend_0xA35C971A.ps_5_0.hlsl | 8 -- .../Middle-earth Shadow of War/common.hlsl | 107 ------------------ .../mov_0xB2EAAA62.ps_5_0.hlsl | 4 +- .../swapchain_hdr_0x68EABB8D.ps_5_0.hlsl | 8 +- .../swapchain_sdr_0x09C22C0E.ps_5_0.hlsl | 20 ++-- ...mapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl | 6 +- 14 files changed, 36 insertions(+), 164 deletions(-) rename Shaders/Middle-earth Shadow of War/{ => Unused or Broken}/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 (100%) rename Shaders/Middle-earth Shadow of War/{ => Unused or Broken}/computeexposure_0xD2356014.cs_5_0.hlsl 1 (100%) rename Shaders/Middle-earth Shadow of War/{ => Unused or Broken}/motionblur_0xB3DC1377.ps_5_0.hlsl 1 (99%) rename Shaders/Middle-earth Shadow of War/{photomode_exposure_0xF4316866.ps_5_0.hlsl => Unused or Broken/photomode_exposure_0xF4316866.ps_5_0.hlsl 1} (83%) rename Shaders/Middle-earth Shadow of War/{ => Unused or Broken}/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 (99%) rename Shaders/Middle-earth Shadow of War/{ => Unused or Broken}/taa_0x8D06D556.ps_5_0.hlsl 1 (99%) rename Shaders/Middle-earth Shadow of War/{tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl => Unused or Broken/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl 1} (93%) diff --git a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl index 76e4d0c5..e5d71355 100644 --- a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl +++ b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl @@ -9,13 +9,6 @@ #define GS LumaSettings.GameSettings -float4 sRGB_Encode(float4 x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} -float3 sRGB_Encode(float3 x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} -float sRGB_Encode(float x) {return x < 0.0031308f ? x * 12.92f : 1.055f * pow(x, 1.f / 2.4f) - 0.055f;} -float4 sRGB_Decode(float4 x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} -float3 sRGB_Decode(float3 x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} -float sRGB_Decode(float x) {return x <= 0.04045f ? x / 12.92f : pow((x + 0.055f) / 1.055f, 2.4f);} - #define HDR_ENABLED LumaSettings.DisplayMode == 1 #define HDR_PEAK PeakWhiteNits / GamePaperWhiteNits #define HDR_INTSCALING GamePaperWhiteNits / UIPaperWhiteNits diff --git a/Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/Unused or Broken/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 similarity index 100% rename from Shaders/Middle-earth Shadow of War/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 rename to Shaders/Middle-earth Shadow of War/Unused or Broken/bloomradialblur_godrays_0x412F81E8.ps_5_0.hlsl 1 diff --git a/Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/Unused or Broken/computeexposure_0xD2356014.cs_5_0.hlsl 1 similarity index 100% rename from Shaders/Middle-earth Shadow of War/computeexposure_0xD2356014.cs_5_0.hlsl 1 rename to Shaders/Middle-earth Shadow of War/Unused or Broken/computeexposure_0xD2356014.cs_5_0.hlsl 1 diff --git a/Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/Unused or Broken/motionblur_0xB3DC1377.ps_5_0.hlsl 1 similarity index 99% rename from Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 rename to Shaders/Middle-earth Shadow of War/Unused or Broken/motionblur_0xB3DC1377.ps_5_0.hlsl 1 index 812432f2..5748cef4 100644 --- a/Shaders/Middle-earth Shadow of War/motionblur_0xB3DC1377.ps_5_0.hlsl 1 +++ b/Shaders/Middle-earth Shadow of War/Unused or Broken/motionblur_0xB3DC1377.ps_5_0.hlsl 1 @@ -47,7 +47,7 @@ void main( r0.xy = t0.Sample(s0_s, w1.xy).xy; r1.xyzw = t3.Sample(s0_s, w1.xy).xyzw; - o0 = r1; return;// debug + // o0 = r1; return;// debug r0.z = dot(r0.xy, r0.xy); r0.z = sqrt(r0.z); diff --git a/Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/Unused or Broken/photomode_exposure_0xF4316866.ps_5_0.hlsl 1 similarity index 83% rename from Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl rename to Shaders/Middle-earth Shadow of War/Unused or Broken/photomode_exposure_0xF4316866.ps_5_0.hlsl 1 index 634d0b4c..f98e61d7 100644 --- a/Shaders/Middle-earth Shadow of War/photomode_exposure_0xF4316866.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/Unused or Broken/photomode_exposure_0xF4316866.ps_5_0.hlsl 1 @@ -36,17 +36,17 @@ void main( r0.xy = min(cb2[22].zw, v1.zw); r0.xyz = t0.Sample(s0_s, r0.xy).xyz; + + r0.xyz = r0.xyz / cb0[25].xxx; //useless for HDR - // some EV thing - r0.xyz = r0.xyz / cb0[25].xxx; + // convert slider 0-1 to exposure multiplier r0.w = -0.5 + cb3[0].x; r0.w = 4 * r0.w; r0.w = exp2(r0.w); r0.xyz = r0.xyz * r0.www; - r0.xyz = cb0[25].xxx * r0.xyz; - - // if (HDR_ENABLED) r0.xyz = HDRTonemap(r0.xyz, HDR_PEAK); + r0.xyz = cb0[25].xxx * r0.xyz; //useless for HDR + o0.xyz = r0.xyz; return; } \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/Unused or Broken/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 similarity index 99% rename from Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 rename to Shaders/Middle-earth Shadow of War/Unused or Broken/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 index ecca9a57..34ff400b 100644 --- a/Shaders/Middle-earth Shadow of War/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 +++ b/Shaders/Middle-earth Shadow of War/Unused or Broken/solid00_lavagoop_0x4AF2E9C0.ps_5_0.hlsl 1 @@ -26,9 +26,6 @@ cbuffer cb1 : register(b1) float4 cb1[2]; } - - - // 3Dmigoto declarations #define cmp - #include "./common.hlsl" diff --git a/Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 b/Shaders/Middle-earth Shadow of War/Unused or Broken/taa_0x8D06D556.ps_5_0.hlsl 1 similarity index 99% rename from Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 rename to Shaders/Middle-earth Shadow of War/Unused or Broken/taa_0x8D06D556.ps_5_0.hlsl 1 index bb4572c5..5ca65c46 100644 --- a/Shaders/Middle-earth Shadow of War/taa_0x8D06D556.ps_5_0.hlsl 1 +++ b/Shaders/Middle-earth Shadow of War/Unused or Broken/taa_0x8D06D556.ps_5_0.hlsl 1 @@ -39,10 +39,10 @@ void main( uint4 bitmask, uiDest; float4 fDest; - o0.xyzw = t1.Sample(s0_s, w1.xy).xyzw; - return; - - discard; +// o0.xyzw = t1.Sample(s0_s, w1.xy).xyzw; +// return; +// +// discard; r0.yz = -cb0[32].wz + w1.xy; r1.xy = cb0[32].zw + w1.xy; @@ -95,9 +95,6 @@ void main( r9.y = r4.x; r3.xyzw = r1.zzzz ? r9.xyzw : r3.xyzw; r4.xyzw = t1.Sample(s0_s, w1.xy).xyzw; - // o0 = r4; r4.w = 10; return; - - r1.z = cmp(r3.y < 10000000); if (r1.z != 0) { diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/Unused or Broken/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl 1 similarity index 93% rename from Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl rename to Shaders/Middle-earth Shadow of War/Unused or Broken/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl 1 index 10807b7c..0f991377 100644 --- a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/Unused or Broken/tonemapwithexposure_hdr_0xA4592384.ps_5_0.hlsl 1 @@ -37,16 +37,16 @@ float3 PerceptualLerp(float3 colorA, float3 colorB, float alpha, float gamma = 2 } // https://www.desmos.com/calculator/stnfdhk9t1 -float Rolloff(float x, float invPeak, float invExposure) {return DivideSafe(x, x * invPeak + invExposure, 0);} -float3 Rolloff(float3 x, float invPeak, float invExposure) {return DivideSafe(x, x * invPeak + invExposure, 0);} +float Rolloff(float x, float invPeak, float invExposure) {return safeDivision(x, x * invPeak + invExposure, 0);} +float3 Rolloff(float3 x, float invPeak, float invExposure) {return safeDivision(x, x * invPeak + invExposure, 0);} float RolloffComplete(float x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return DivideSafe(x, x * invPeak + invExposure, 0); + return safeDivision(x, x * invPeak + invExposure, 0); } float3 RolloffComplete(float3 x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return DivideSafe(x, x * invPeak + invExposure, 0); + return safeDivision(x, x * invPeak + invExposure, 0); } void main( @@ -106,7 +106,7 @@ void main( // r0.xyz *= (80.f / 500.f); // #else // // replacement -// r0.xyz *= DivideSafe(1, r1.x, 0) * (80.f / 500.f); +// r0.xyz *= safeDivision(1, r1.x, 0) * (80.f / 500.f); // // r0.xyz *= (Rolloff(0.18, max(r0.w, 0.0), r1.x) / 0.18) * (80.f / 500.f); // r0.xyz = Neupow(r0.xyz, HDR_PEAK, 2 * GS.WhiteClip); // #endif @@ -115,7 +115,7 @@ void main( // // r0.w = t1.Load(1).x; //useless // r1.x = t1.Load(2).x; // r0.xyz = pow(r0.xyz, cb3[0].x); -// r0.xyz *= DivideSafe(1, r1.x, 0); +// r0.xyz *= safeDivision(1, r1.x, 0); // r0.xyz = pow(r0.xyz, 1/cb3[0].x); // { // float3 o = r0.xyz; @@ -133,7 +133,7 @@ void main( // pow and Reinhard // r0.w = t1.Load(1).x; //useless r1.x = t1.Load(2).x; - r0.xyz *= DivideSafe(1, pow(r1.x, 0.6), 0); + r0.xyz *= safeDivision(1, pow(r1.x, 0.6), 0); r0.xyz = pow(r0.xyz, pow(cb3[0].x, 0.6)); r0.xyz *= (80.f / 500.f); r0.xyz = HDRTonemap(r0.xyz, HDR_PEAK); diff --git a/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl index e15eccc8..a4197fdf 100644 --- a/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/bloomblend_0xA35C971A.ps_5_0.hlsl @@ -28,14 +28,6 @@ void main( r1.xyz = t0.SampleLevel(s0_s, r0.xy, 0).xyz * GS.Bloom; //bloom r0.xyz = t1.SampleLevel(s0_s, r0.xy, 0).xyz; //godrays o0.xyz = max(r1.xyz, r0.xyz); - // o0.xyz = r1.xyz + r0.xyz; - // { - // float y = GetLuminance(o0.xyz, CS_BT709); - // float y1 = y; - // y1 = Neutwo(y1, 0.055); - // y1 *= 1.25; - // o0.xyz *= DivideSafe(y1, y, 0); - // } o0.w = 1; return; } \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/common.hlsl b/Shaders/Middle-earth Shadow of War/common.hlsl index 3b9a857a..b9264009 100644 --- a/Shaders/Middle-earth Shadow of War/common.hlsl +++ b/Shaders/Middle-earth Shadow of War/common.hlsl @@ -57,12 +57,6 @@ float3 ClampByMaxChannel(float3 x, float p) { if (m > p) x *= p / m; return x; } -float DivideSafe(float numerator, float denominator, float defaultValue) { - return denominator != 0.0f ? numerator / denominator : defaultValue; -} -float3 DivideSafe(float3 numerator, float3 denominator, float3 defaultValue) { - return denominator != 0.0f ? numerator / denominator : defaultValue; -} bool FloatEquals(float a, float b, float epsilon) { return abs(a - b) <= epsilon; } @@ -177,110 +171,9 @@ float Neupow(float x, float peak, float clip, float power) { float denominator_pow = xx * ((cc - pp)) + (cc * pp); return numerator / pow(denominator_pow, rcp(power)); } -///////////////////////////////////////////////////////////////////////////////////////// -float ReinhardSimple(float x, float peak = 1.0) -{ - return x / ((abs(x) / peak) + 1.0); -} -float3 ReinhardSimple(float3 x, float peak = 1.0) -{ - return x / ((abs(x) / peak) + 1.0); -} -float ReinhardExtended(float color, float white_max = 1000.f / 203.f, float peak = 1.f) { - return ReinhardSimple(color, peak) * (1.f + (peak * color) / (white_max * white_max)); -} -float3 ReinhardExtended(float3 color, float white_max = 1000.f / 203.f, float peak = 1.f) { - return ReinhardSimple(color, peak) * (1.f + (peak * color) / (white_max * white_max)); -} -float ComputeReinhardScale(float channel_max = 1.f, float channel_min = 0.f, float gray_in = MidGray, float gray_out = MidGray) { - return (channel_max * (channel_min * gray_out + channel_min - gray_out)) - / (gray_in * (gray_out - channel_max)); -} -float3 ReinhardPiecewise(float3 x, float x_max = 1.f, float shoulder = 0.18f) { - const float x_min = 0.f; - float exposure = ComputeReinhardScale(x_max, x_min, shoulder, shoulder); - float3 tonemapped = mad(x, exposure, x_min) / mad(x, exposure / x_max, 1.f - x_min); - return lerp(x, tonemapped, step(shoulder, x)); -} -float ReinhardPiecewise(float x, float x_max = 1.f, float shoulder = 0.18f) { - const float x_min = 0.f; - float exposure = ComputeReinhardScale(x_max, x_min, shoulder, shoulder); - float tonemapped = mad(x, exposure, x_min) / mad(x, exposure / x_max, 1.f - x_min); - return lerp(x, tonemapped, step(shoulder, x)); -} -//////////////////////////////////////////////////////////////////////////////////////// -/// Piecewise linear + exponential compression to a target value starting from a specified number. -/// https://www.ea.com/frostbite/news/high-dynamic-range-color-grading-and-display-in-frostbite -#define EXPONENTIALROLLOFF_GENERATOR(T) \ - T ExponentialRollOff(T input, float rolloff_start = 0.20f, float output_max = 1.0f) { \ - T rolloff_size = output_max - rolloff_start; \ - T overage = -max((T)0, input - rolloff_start); \ - T rolloff_value = (T)1.0f - exp(overage / rolloff_size); \ - T new_overage = mad(rolloff_size, rolloff_value, overage); \ - return input + new_overage; \ - } -#define EXPONENTIALROLLOFF_CLIP_GENERATOR(T) \ - T ExponentialRollOff(T input, float rolloff_start, float output_max, float clip) { \ - T rolloff_size = output_max - rolloff_start; \ - T overage = -max((T)0, input - rolloff_start); \ - T clip_size = rolloff_start - clip; \ - T rolloff_value = (T)1.0f - exp(overage / rolloff_size); \ - T clip_value = (T)1.0f - exp(clip_size / rolloff_size); \ - T new_overage = mad(rolloff_size, rolloff_value / clip_value, overage); \ - return input + new_overage; \ - } -EXPONENTIALROLLOFF_GENERATOR(float) -EXPONENTIALROLLOFF_GENERATOR(float3) -EXPONENTIALROLLOFF_CLIP_GENERATOR(float) -EXPONENTIALROLLOFF_CLIP_GENERATOR(float3) -#undef EXPONENTIALROLLOFF_GENERATOR -#undef EXPONENTIALROLLOFF_CLIP_GENERATOR -////////////////////////////////////////////////////////////////////////////////////// -// Uchimura 2018, "Practical HDR and Wide Color Techniques in Gran Turismo SPORT" -// https://www.desmos.com/calculator/gslcdxvipg -// http://cdn2.gran-turismo.com/data/www/pdi_publications/PracticalHDRandWCGinGTS.pdf -#define GTTONEMAP_GENERATOR(T) \ - T GTTonemap(T x, \ - float P = 1.f, \ - float a = 1.f, \ - float m = 0.22f, \ - float l = 0.4f, \ - float c = 1.33f, \ - float b = 0.f) { \ - float l0 = ((P - m) * l) / a; \ - float L0 = m - (m / a); \ - float L1 = m + (1.0f - m) / a; \ - \ - T S0 = m + l0; \ - T S1 = m + a * l0; \ - T C2 = (a * P) / (P - S1); \ - T CP = -C2 / P; \ - \ - T w0 = 1.0f - smoothstep(0.0f, m, x); \ - T w2 = step(m + l0, x); \ - T w1 = 1.0f - w0 - w2; \ - \ - T T_ = m * pow(x / m, c) + b; \ - T S_ = P - (P - S1) * exp(CP * (x - S0)); \ - T L_ = m + a * (x - m); \ - \ - return T_ * w0 + L_ * w1 + S_ * w2; \ - } -GTTONEMAP_GENERATOR(float) -GTTONEMAP_GENERATOR(float3) -#undef GTTONEMAP_GENERATOR -float3 GTTonemapToe(float3 x, float m = 100/203, float c = 1.027) { - m = max(m, 0.0001f); - float3 w0 = 1.0f - smoothstep(0.0f, m, x); - float3 T_ = m * pow(x / m, c); - return T_ * w0 + x * (1.0f - w0); -} //////////////////////////////////////////////////////////////////////////////////////// float3 HDRTonemap(float3 x, float peak, float start = 0.18) { x = Neupow(x, peak, 1 * GS.WhiteClip); - // x = ExponentialRollOff(x, start, peak); - // x = ReinhardExtended(x, 10, peak); - // x = ReinhardPiecewise(x, peak, start); return x; } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl index c9da4e05..ea1438df 100644 --- a/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/mov_0xB2EAAA62.ps_5_0.hlsl @@ -44,10 +44,10 @@ void main( // Scale to scene paper white if (HDR_ENABLED) { o0.xyz = saturate(o0.xyz); // original unorm clamp - o0.xyz = sRGB_Decode(o0.xyz); + o0.xyz = gamma_sRGB_to_linear(o0.xyz); // o0.xyz = pow(o0.xyz, 2.2); o0.xyz *= HDR_INTSCALING; - o0.xyz = sRGB_Encode(o0.xyz); + o0.xyz = linear_to_sRGB_gamma(o0.xyz); } return; } \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl index 9b515bec..ad37ec96 100644 --- a/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/swapchain_hdr_0x68EABB8D.ps_5_0.hlsl @@ -53,8 +53,8 @@ void main( // game = max(game, 0); // // #if GAMMA_CORRECT_CUSTOM == 1 -// game.xyz = sRGB_Encode(game.xyz); -// game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : sRGB_Decode(game.xyz); +// game.xyz = linear_to_sRGB_gamma(game.xyz); +// game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : gamma_sRGB_to_linear(game.xyz); // #endif // // game *= HDR_INTSCALING; @@ -64,9 +64,9 @@ void main( // ui.w = saturate(ui.w); // ui.w = pow(ui.w, 2.2); // #if GAMMA_CORRECT_CUSTOM == 0 -// ui.xyz = sRGB_Decode(ui.xyz); +// ui.xyz = gamma_sRGB_to_linear(ui.xyz); // #else -// ui.xyz = ui.xyz < 1 ? pow(ui.xyz, 2.2) : sRGB_Decode(ui.xyz); +// ui.xyz = ui.xyz < 1 ? pow(ui.xyz, 2.2) : gamma_sRGB_to_linear(ui.xyz); // #endif // ui = max(ui, 0); // diff --git a/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl index dbd885ac..28b330a6 100644 --- a/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/swapchain_sdr_0x09C22C0E.ps_5_0.hlsl @@ -39,7 +39,7 @@ Texture2D Dummy; //TODO: take in MVs for dynamic RCAS? #include "./common.hlsl" #include "../Includes/RCAS.hlsl" -float3 GameGamma(float3 x) { +float3 InGameGammaSlider(float3 x) { float3 r0, r1, r2; r0.xyz = x; r0.xyz = log2(r0.xyz); @@ -85,11 +85,11 @@ void main( if (!HDR_ENABLED) { - game = sRGB_Decode(game); //decode gamma slider + game = gamma_sRGB_to_linear(game); //decode gamma slider } else { #if GAMMA_CORRECT_CUSTOM == 1 - game.xyz = sRGB_Encode(game.xyz); - game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : sRGB_Decode(game.xyz); + game.xyz = linear_to_sRGB_gamma(game.xyz); + game.xyz = game.xyz < 1 ? pow(game.xyz, 2.2) : gamma_sRGB_to_linear(game.xyz); #endif game *= HDR_INTSCALING; @@ -101,22 +101,22 @@ void main( ui.w = min(ui.w, 1); float3 uiBack = ui.xyz; - ui.xyz = sRGB_Decode(ui.xyz); + ui.xyz = gamma_sRGB_to_linear(ui.xyz); if (HDR_ENABLED) { #if GAMMA_CORRECT_CUSTOM == 1 ui.xyz = ui.xyz < 1 ? pow(uiBack, 2.2) : ui.xyz; #endif } else { - ui.xyz = GameGamma(ui.xyz); - ui.xyz = sRGB_Decode(ui.xyz); + ui.xyz = InGameGammaSlider(ui.xyz); + ui.xyz = gamma_sRGB_to_linear(ui.xyz); } //// COMBINE //// - ui.xyz = sRGB_Encode(ui.xyz); // TODO: or 2.2? prob doesnt matter - game = sRGB_Encode(game); + ui.xyz = linear_to_sRGB_gamma(ui.xyz); // TODO: or 2.2? prob doesnt matter + game = linear_to_sRGB_gamma(game); float3 x = game * (1 - ui.w) + ui.xyz; //in gamma space - x = sRGB_Decode(x); + x = gamma_sRGB_to_linear(x); if (HDR_ENABLED) x = min(HDR_PEAK * HDR_INTSCALING, x); //peak clamp //// TEST_USER_PEAK //// diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl index c666faa7..519d9a7c 100644 --- a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl @@ -41,11 +41,11 @@ float3 RenoDX_Contrast(float3 x, float contrast, float mid_gray = 0.18f) { // https://www.desmos.com/calculator/stnfdhk9t1 float Rolloff(float x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return DivideSafe(x, x * invPeak + invExposure, 0); + return safeDivision(x, x * invPeak + invExposure, 0); } float3 Rolloff(float3 x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return DivideSafe(x, x * invPeak + invExposure, 0); + return safeDivision(x, x * invPeak + invExposure, 0); } float RolloffLocalMax(float contrast, float invPeak, float invExposure) { @@ -235,7 +235,7 @@ void main( // r2.xyz = cmp(r0.xyz < float3(0.00313080009,0.00313080009,0.00313080009)); // r0.xyz = float3(12.9200001,12.9200001,12.9200001) * r0.xyz; // r0.xyz = r2.xyz ? r0.xyz : r1.xyz; -// // o0.xyz = sRGB_Encode(r0.xyz); +// // o0.xyz = linear_to_sRGB_gamma(r0.xyz); // // o0.xyz = r0.xyz; // o0.w = 1; From ce6e0e3e494ed8a8107049131d196ce3af2114ca Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 18:12:35 -0700 Subject: [PATCH 17/33] Shadow of War: Fixed edge cases for rolloff ext --- ...mapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl | 52 +++++++------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl index 519d9a7c..cb958b10 100644 --- a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl @@ -20,24 +20,6 @@ cbuffer cb3 : register(b3) #include "./common.hlsl" #include "../Includes/ColorGradingLUT.hlsl" -float3 PerceptualLerp(float3 colorA, float3 colorB, float alpha, float gamma = 2.2) -{ - float luminanceA = GetLuminance(colorA.rgb); - float luminanceB = GetLuminance(colorB.rgb); - float gammaLuminanceA = pow(max(luminanceA, 0.f), 1.0 / gamma); // Linear->Gamma - float gammaLuminanceB = pow(max(luminanceB, 0.f), 1.0 / gamma); // Linear->Gamma - float targetLuminance = pow(lerp(gammaLuminanceA, gammaLuminanceB, alpha), gamma); // Blend in gamma space - - float3 colorLerped = lerp(colorA, colorB, alpha); - float sourceLuminance = GetLuminance(colorLerped.rgb); - if (sourceLuminance != 0.f) colorLerped.rgb *= max(targetLuminance / sourceLuminance, 0.f); // If any of the two luminance is negative, clip to black - return colorLerped; -} - -float3 RenoDX_Contrast(float3 x, float contrast, float mid_gray = 0.18f) { - return pow(max(0, x / mid_gray), contrast) * mid_gray; -} - // https://www.desmos.com/calculator/stnfdhk9t1 float Rolloff(float x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); @@ -57,22 +39,31 @@ float RolloffLocalMax(float contrast, float invPeak, float invExposure) { float RolloffSlope(float x, float contrast, float invPeak, float invExposure) { return (invExposure * contrast * pow(x, contrast - 1)) / pow((invPeak * pow(x, contrast) + invExposure), 2); //1st derivative @ x } -float3 RolloffExt(float3 x, float contrast, float invPeak, float invExposure) { +float3 RolloffSDRAndHDR(float3 x, float contrast, float invPeak, float invExposure) { float3 xBack = x; + // sdr + float3 sdr = Rolloff(x, contrast, invPeak, invExposure); + if (!HDR_ENABLED) return sdr; + // extend - float thres = RolloffLocalMax(contrast, invPeak, invExposure); - float3 lower = Rolloff(x, contrast, invPeak, invExposure); - float3 higher = RolloffSlope(max(thres, 0.000001), contrast, invPeak, invExposure) * (x - thres) + Rolloff(thres, contrast, invPeak, invExposure); - x = x < thres ? lower : higher; + float thres; + if (invPeak >= 0) { + thres = RolloffLocalMax(contrast, invPeak, invExposure); + thres = max(thres, 0.000001); //just in case of undef + } else { + thres = 1; // local max is unsolvable, so fallback 1 + } + float3 higher = RolloffSlope(thres, contrast, invPeak, invExposure) * (x - thres) + Rolloff(thres, contrast, invPeak, invExposure); + + x = x < thres ? sdr : higher; // HDR per channel x = Neupow(x, HDR_PEAK, 2.2 * GS.WhiteClip); - // x = ExponentialRollOff(x, thres, HDR_PEAK, 100 / GS.WhiteClip); // correct HDR perchannel; { - float3 sdr = lower; + sdr = Neupow(sdr, 2.2, 3.3); // essentially an upgraded saturate(), really only useful for invPeak < 0 sdr = UCS_Encode(sdr); x = UCS_Encode(x); x = RestoreHueAndChrominanceUcs(x, sdr, GS.BlowoutCorrection, 0, 0); @@ -111,11 +102,7 @@ void main( float contrast = cb3[0].x; float invPeak = t1.Load(1).x; //aka white clip float invExposure = t1.Load(2).x; - if (HDR_ENABLED) { - r0.xyz = RolloffExt(r0.xyz, contrast, invPeak, invExposure); - } else { - r0.xyz = Rolloff(r0.xyz, contrast, invPeak, invExposure); - } + r0.xyz = RolloffSDRAndHDR(r0.xyz, contrast, invPeak, invExposure); // r0.xyz = t1.Load(1).x - DVS1; //debug identify invPeak // r0.xyz = t1.Load(2).x - DVS1; //debug identify invExposure @@ -128,8 +115,7 @@ void main( r0.xyz = r0.xyz / r0.www; //to 1 r0.xyz = pow(r0.xyz, cb3[0].y); //global saturation - // only use white path in SDR! this is also disabled in original HDR - if (!HDR_ENABLED) { + if (!HDR_ENABLED) { //only use white path in SDR! this is also disabled in original HDR r1.xyz = float3(1,1,1) + -r0.xyz; //SDR centric r1.w = -cb3[0].w * cb3[1].x + r0.w; r1.w = max(0, r1.w); @@ -143,7 +129,7 @@ void main( r0.xyz = max(float3(0,0,0), r0.xyz); if (!HDR_ENABLED) r0.xyz = min(cb3[1].xxx, r0.xyz); - // Modded sRGB Encode + // modified sRGB Encode if (!HDR_ENABLED) { r0.xyz = log2(r0.xyz); r0.xyz = cb3[1].yyy * r0.xyz; //user settings From 73e25998dea2e52b532b9af7e83e5dd9227f45b3 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 18:34:20 -0700 Subject: [PATCH 18/33] Shadow of War: exposed Retuned Fire settings --- .../Includes/Common.hlsl | 4 +-- .../Includes/GameCBuffers.hlsl | 2 ++ .../Middle-earth Shadow of War/common.hlsl | 10 +++---- .../Games/Middle-earth Shadow of War/main.cpp | 26 ++++++++++++++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl index e5d71355..34db7b1f 100644 --- a/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl +++ b/Shaders/Middle-earth Shadow of War/Includes/Common.hlsl @@ -12,5 +12,5 @@ #define HDR_ENABLED LumaSettings.DisplayMode == 1 #define HDR_PEAK PeakWhiteNits / GamePaperWhiteNits #define HDR_INTSCALING GamePaperWhiteNits / UIPaperWhiteNits -#define HDR_SHOULDERSTART GS.TonemapperRolloffStart / GamePaperWhiteNits -#define HDR_MAXEXPECTED GS.TonemapperMaxExpected / GamePaperWhiteNits \ No newline at end of file +// #define HDR_SHOULDERSTART GS.TonemapperRolloffStart / GamePaperWhiteNits +// #define HDR_MAXEXPECTED GS.TonemapperMaxExpected / GamePaperWhiteNits \ No newline at end of file diff --git a/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl b/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl index 6d25e8b5..c9f61560 100644 --- a/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl +++ b/Shaders/Middle-earth Shadow of War/Includes/GameCBuffers.hlsl @@ -11,6 +11,8 @@ namespace CB { float WhiteClip; float BlowoutCorrection; + float RetunedFirePeak; + float RetunedFireBoost; float GodRays; float Bloom; float RCAS; diff --git a/Shaders/Middle-earth Shadow of War/common.hlsl b/Shaders/Middle-earth Shadow of War/common.hlsl index b9264009..d555cf30 100644 --- a/Shaders/Middle-earth Shadow of War/common.hlsl +++ b/Shaders/Middle-earth Shadow of War/common.hlsl @@ -2,8 +2,8 @@ // #include "./Includes/HermiteSpline_portable.hlsl" #include "./Includes/ictcp_portable.hlsl" -#define FIRE_PEAK 1.26 -#define FIRE_BOOST 2.6 +#define FIRE_PEAK GS.RetunedFirePeak /* 1.26 */ +#define FIRE_BOOST GS.RetunedFireBoost /* 2.6 */ ///////////////////////////////////////////////////////////////////////////////////////// // rect is top left (x,y), bottom right (x,y) @@ -177,17 +177,17 @@ float3 HDRTonemap(float3 x, float peak, float start = 0.18) { return x; } //////////////////////////////////////////////////////////////////////////////////////// -float FireTonemap(float x, float clip = FIRE_PEAK, float output_max = 1.0f) { +float FireTonemap(float x, float clip, float output_max = 1.0f) { x = min(x, clip); x = Neutwo(x, output_max, clip); return x; } -float2 FireTonemap(float2 x, float clip = FIRE_PEAK, float output_max = 1.0f) { +float2 FireTonemap(float2 x, float clip, float output_max = 1.0f) { x = min(x, clip); x = Neutwo(x, output_max, clip); return x; } -float3 FireTonemap(float3 x, float clip = FIRE_PEAK, float output_max = 1.0f) { +float3 FireTonemap(float3 x, float clip, float output_max = 1.0f) { x = min(x, clip); x = Neutwo(x, output_max, clip); return x; diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 4ba18e10..4638edc0 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -370,6 +370,8 @@ class MiddleEarthShadowOfWar final : public Game // CB init default values default_luma_global_game_settings.WhiteClip = cb_luma_global_settings.GameSettings.WhiteClip = 1.; default_luma_global_game_settings.BlowoutCorrection = cb_luma_global_settings.GameSettings.BlowoutCorrection = 0.3; + default_luma_global_game_settings.RetunedFirePeak = cb_luma_global_settings.GameSettings.RetunedFirePeak = 1.26; + default_luma_global_game_settings.RetunedFireBoost = cb_luma_global_settings.GameSettings.RetunedFireBoost = 2.6; default_luma_global_game_settings.GodRays = cb_luma_global_settings.GameSettings.GodRays = 1.; default_luma_global_game_settings.Bloom = cb_luma_global_settings.GameSettings.Bloom = 1.; default_luma_global_game_settings.RCAS = cb_luma_global_settings.GameSettings.RCAS = 0.; @@ -573,6 +575,8 @@ class MiddleEarthShadowOfWar final : public Game // CB load user reshade::get_config_value(runtime, NAME, "WhiteClip", cb_luma_global_settings.GameSettings.WhiteClip); reshade::get_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); + reshade::get_config_value(runtime, NAME, "RetunedFirePeak", cb_luma_global_settings.GameSettings.RetunedFirePeak); + reshade::get_config_value(runtime, NAME, "RetunedFireBoost", cb_luma_global_settings.GameSettings.RetunedFireBoost); reshade::get_config_value(runtime, NAME, "GodRays", cb_luma_global_settings.GameSettings.GodRays); reshade::get_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); @@ -741,7 +745,27 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("If off, shaders will intentionally break, so just ignore the warning. Thanks!"); - ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning (Read Tooltips)", "\"Pick your poison...\"\n\nThe devs allowed their artists to tune the brightness curve of their fire sprites.\nHowever, they're boosted so high that the brightness -> color look up is clipped!\nIt is rather apparent for HDR, though not as much for SDR.\n\nEnabling this will reduces the clipping, but also makes them more orange.\nUnintended, but more preferable?"); + bool is_on = ShaderDefines::UIToggleCheckmark(FIRE_RETUNED, "Enable Retuning (Read Tooltips)", "\"Pick your poison...\"\n\nThe devs allowed their artists to tune the brightness curve of their fire sprites.\nHowever, they're boosted so high that the brightness -> color look up is clipped!\nIt is rather apparent for HDR, though not as much for SDR.\n\nEnabling this will reduces the clipping, but also makes them more orange.\nUnintended, but more preferable?"); + + if (!is_on) ImGui::BeginDisabled(); + + ImGui::PushID("Retuned Fire: RetunedFirePeak"); + if (ImGui::SliderFloat("Reduction Strength", &cb_luma_global_settings.GameSettings.RetunedFirePeak, 1.01f, 2.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "RetunedFirePeak", cb_luma_global_settings.GameSettings.RetunedFirePeak); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Increase to further reduce the clipping of fire sprites, but also make them more orange."); + DrawResetButton(cb_luma_global_settings.GameSettings.RetunedFirePeak, default_luma_global_game_settings.RetunedFirePeak, "RetunedFirePeak", runtime); + + ImGui::PushID("Retuned Fire: RetunedFireBoost"); + if (ImGui::SliderFloat("Brightness Makeup", &cb_luma_global_settings.GameSettings.RetunedFireBoost, 1.f, 4.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "RetunedFireBoost", cb_luma_global_settings.GameSettings.RetunedFireBoost); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("After reduction, we need a boost in brightness to makeup loss."); + DrawResetButton(cb_luma_global_settings.GameSettings.RetunedFireBoost, default_luma_global_game_settings.RetunedFireBoost, "RetunedFireBoost", runtime); + + if (!is_on) ImGui::EndDisabled(); } #if DEVELOPMENT From 0795776c35a5270857cac2be63f84eb12a0de1a4 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 19:50:59 -0700 Subject: [PATCH 19/33] Shadow of War: SR in Photo Mode (when TAA w/o MVs) --- .../Games/Middle-earth Shadow of War/main.cpp | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 4638edc0..3176c9b3 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -14,7 +14,9 @@ namespace { // Shader Hashes const ShaderHashesList shader_hashes_linearize_depth_and_generate_mvs = {.compute_shaders = {0x0E095BB1}}; - const ShaderHashesList shader_hashes_TAA = {.pixel_shaders = {0x8D06D556}}; + constexpr uint32_t shader_hash_TAA = 0x8D06D556; + constexpr uint32_t shader_hash_TAA_no_velocity = 0x75F11673; + const ShaderHashesList shader_hashes_TAA = {.pixel_shaders = {shader_hash_TAA, shader_hash_TAA_no_velocity}}; const ShaderHashesList shader_hashes_tonemap = {.pixel_shaders = {0xA4592384, 0xFD32C367}}; const ShaderHashesList shader_hashes_photomode_exposure = {.pixel_shaders = {0xF4316866}}; const ShaderHashesList shader_hashes_swapchain = {.pixel_shaders = {0x68EABB8D, 0x09C22C0E}}; @@ -33,7 +35,6 @@ namespace SR::Type sr_type_copy = SR::Type::None; bool is_ui = true; // User toggle for UI skip draw - bool sr_copy_resource = false; // User toggle to exec CopyResource() to fix missing bloom bool sr_user_allow_upgraded_samplers = false; // Let user control ignore_upgraded_samplers } @@ -434,12 +435,19 @@ class MiddleEarthShadowOfWar final : public Game auto& managed_resources = game_device_data.managed_resources; // Depth & Motion Vectors (SR) + static bool get_mvs_from_uav_token = false; if (device_data.sr_type != SR::Type::None && original_shader_hashes.Contains(shader_hashes_linearize_depth_and_generate_mvs)) { - // Take depth + // Take depth (SRV 1) ComPtr srv; native_device_context->CSGetShaderResources(1, 1, srv.put()); srv->GetResource(managed_resources.resources["depth"_h].put()); + + // Take motion vectors (UAV 1) //TODO: also hitting UAV is prob worse perf than the SRV array later, but this is might be the only way to account for photomode. + ComPtr uav; + native_device_context->CSGetUnorderedAccessViews(1, 1, uav.put()); + uav->GetResource(managed_resources.resources["motion_vectors"_h].put()); + return DrawOrDispatchOverrideType::None; } @@ -451,7 +459,11 @@ class MiddleEarthShadowOfWar final : public Game // DLSS requires an immediate context for execution! ASSERT_ONCE(native_device_context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - // Settings + // With vel or without vel? + const bool is_has_vel = original_shader_hashes.pixel_shaders[0] == shader_hash_TAA; + if (!is_has_vel) get_mvs_from_uav_token = true; + + // SettingsData auto* sr_instance_data = device_data.GetSRInstanceData(); ASSERT_ONCE(sr_instance_data); @@ -474,45 +486,39 @@ class MiddleEarthShadowOfWar final : public Game sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); - // Get resources - std::array srvs; - native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); - - ComPtr resource_mvs; - srvs[0]->GetResource(resource_mvs.put()); + // Get color SRV + ID3D11ShaderResourceView* srv_scene = nullptr; + native_device_context->PSGetShaderResources(is_has_vel ? 1 : 0, 1, &srv_scene); ComPtr resource_scene; - srvs[1]->GetResource(resource_scene.put()); + srv_scene->GetResource(resource_scene.put()); + // Get output RTV ComPtr rtv; native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); ComPtr resource_rt; rtv->GetResource(resource_rt.put()); + // DrawData: resources SR::SuperResolutionImpl::DrawData draw_data; draw_data.source_color = resource_scene.get(); draw_data.output_color = resource_rt.get(); - draw_data.motion_vectors = resource_mvs.get(); + draw_data.motion_vectors = managed_resources.resources["motion_vectors"_h].get(); draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); - // Jitters are in range [-1, 1]. + // DrawData: Jitters are in range [-1, 1]. draw_data.jitter_x = g_jitter_x * -0.5f; draw_data.jitter_y = g_jitter_y * 0.5f; #if DEVELOPMENT JitterHistory::OnSRDraw({draw_data.jitter_x, draw_data.jitter_y}); #endif + // DrawData: resolution draw_data.render_width = device_data.render_resolution.x; draw_data.render_height = device_data.render_resolution.y; // DRAW device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); - // Copy back to input, fixing missing transparency FXs. - if (sr_copy_resource) native_device_context->CopyResource(resource_scene.get(), resource_rt.get()); - - // Reset pointers - ResetCOMArray(srvs); - return DrawOrDispatchOverrideType::Replaced; } @@ -582,7 +588,6 @@ class MiddleEarthShadowOfWar final : public Game reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); // SRUser - reshade::get_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); reshade::get_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; } @@ -661,20 +666,11 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Only 100%% internal/render resolution is supported."); - - ImGui::NewLine(); - - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); - ImGui::TextWrapped("[Super Resolution: Bloom & Transparency Missing Fix]"); - ImGui::PopStyleColor(); - - ImGui::PushID("SR: copy_resource"); - if (ImGui::Checkbox("Enable Fix", &sr_copy_resource)) - reshade::set_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); - ImGui::PopID(); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("In Photo Mode, there is no motion vector data. Expect smearing."); + + if (ImGui::Button("Force Reset")) device_data.force_reset_sr = true; if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("For some reason (Motion Blur + Depth of Field?) bloom and other transparency effects may go missing after Super Resolution draws.\nEnable this to copy the output back to the input, somehow fixing the issue."); - DrawResetButton(sr_copy_resource, false, "sr_copy_resource", runtime); + ImGui::SetTooltip("Force clearing of history so that aggregation begins anew."); } ImGui::NewLine(); From 7ebcc119367b3c51c1c26c31459cab8bc6d65cdb Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 20:11:44 -0700 Subject: [PATCH 20/33] Shadow of War: Exposed Mip LOD bias for user to boost past SR recommended --- .../Games/Middle-earth Shadow of War/main.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 3176c9b3..c10d3f96 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -35,7 +35,8 @@ namespace SR::Type sr_type_copy = SR::Type::None; bool is_ui = true; // User toggle for UI skip draw - bool sr_user_allow_upgraded_samplers = false; // Let user control ignore_upgraded_samplers + bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers + float sr_user_mip_bias_offset = 0.f; // Let user control mip bias offset, where 0 is SR recommended. } struct GameDeviceDataMiddleEarthShadowOfWar final : GameDeviceData @@ -562,14 +563,11 @@ class MiddleEarthShadowOfWar final : public Game if (!custom_texture_mip_lod_bias_offset) { std::shared_lock shared_lock_samplers(s_mutex_samplers); + if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !ignore_upgraded_samplers) - { - device_data.texture_mip_lod_bias_offset = SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); // This results in -1 at output res - } + device_data.texture_mip_lod_bias_offset = sr_user_mip_bias_offset < 0 ? sr_user_mip_bias_offset : SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); else - { device_data.texture_mip_lod_bias_offset = 0.0f; - } } } @@ -680,15 +678,26 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("SR: sr_user_allow_upgraded_samplers"); - if (ImGui::Checkbox("Allow Sampler Upgrades (Read Tooltip)", &sr_user_allow_upgraded_samplers)) + if (ImGui::Checkbox("Allow Sampler Upgrades", &sr_user_allow_upgraded_samplers)) { reshade::set_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; } ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance, though unnoticeable?\nMay change more than just texture detail.\nWill costs some performance."); - DrawResetButton(sr_user_allow_upgraded_samplers, false, "sr_user_allow_upgraded_samplers", runtime); + ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance\nMay change more than just texture detail.\nMay also cost some performance."); + DrawResetButton(sr_user_allow_upgraded_samplers, true, "sr_user_allow_upgraded_samplers", runtime); + + //sr_user_mip_bias_offset slider + if (ignore_upgraded_samplers) ImGui::BeginDisabled(); + ImGui::PushID("SR: sr_user_mip_bias_offset"); + if (ImGui::SliderFloat("Mip LOD Bias Offset", &sr_user_mip_bias_offset, 0.f, -10.f, "%.3f")) + reshade::set_config_value(runtime, NAME, "sr_user_mip_bias_offset", sr_user_mip_bias_offset); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("Negative bias offset increases texture detail at a distance.\n\nSet 0 for Super Resolution recommendation.\nOtherwise, you can override."); + if (ignore_upgraded_samplers) ImGui::EndDisabled(); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Effective: %.3f", device_data.texture_mip_lod_bias_offset); } // SECTION: Miscellaneous From 007e9c7f4344960d1d94ed7efc579b8a693985db Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 20:12:01 -0700 Subject: [PATCH 21/33] Shadow of War: removed Photo Mode warning --- Source/Games/Middle-earth Shadow of War/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index c10d3f96..91216759 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -664,7 +664,6 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Only 100%% internal/render resolution is supported."); - ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("In Photo Mode, there is no motion vector data. Expect smearing."); if (ImGui::Button("Force Reset")) device_data.force_reset_sr = true; if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) From e521a2efeedaac68ade8c8bdcd1912770e1c61f7 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 20:44:25 -0700 Subject: [PATCH 22/33] Shadow of War: typo --- Source/Games/Middle-earth Shadow of War/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 91216759..89089f09 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -638,7 +638,7 @@ class MiddleEarthShadowOfWar final : public Game reshade::set_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("By extending/straighting the rolloff curve to HDR, we lose the blowout originally intended by the SDR short curve.\nSo, increase to correct the hues of the new HDR highlights using the results from SDR."); + ImGui::SetTooltip("By extending/straighting the rolloff curve to HDR, we lose the blowout originally intended by the SDR low curve.\nSo, increase to correct the hues of the new HDR highlights using the results from SDR."); DrawResetButton(cb_luma_global_settings.GameSettings.BlowoutCorrection, default_luma_global_game_settings.BlowoutCorrection, "BlowoutCorrection", runtime); if (ImGui::Button("Extended Tonemap (Desmos)")) From 28b127b0ee8083a45d84d5e8fd19901ae2f8576d Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 20:52:01 -0700 Subject: [PATCH 23/33] Shadow of War: Re-added the CopyResource() fix --- .../Games/Middle-earth Shadow of War/main.cpp | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 89089f09..dcc4ac9e 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -33,9 +33,12 @@ namespace // A copy of device_data.sr_type SR::Type sr_type_copy = SR::Type::None; + + // User toggle for UI skip draw + bool is_ui = true; - bool is_ui = true; // User toggle for UI skip draw - bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers + bool sr_copy_resource = false; // Bloom missing fix by copying output back to input. + bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers. float sr_user_mip_bias_offset = 0.f; // Let user control mip bias offset, where 0 is SR recommended. } @@ -520,7 +523,10 @@ class MiddleEarthShadowOfWar final : public Game // DRAW device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data); - return DrawOrDispatchOverrideType::Replaced; + // For missing bloom and other transparent FXs... somehow + if (device_data.has_drawn_sr && sr_copy_resource) native_device_context->CopyResource(draw_data.source_color, draw_data.output_color); + + return device_data.has_drawn_sr ? DrawOrDispatchOverrideType::Replaced : DrawOrDispatchOverrideType::None; } // Tonemap @@ -585,9 +591,11 @@ class MiddleEarthShadowOfWar final : public Game reshade::get_config_value(runtime, NAME, "Bloom", cb_luma_global_settings.GameSettings.Bloom); reshade::get_config_value(runtime, NAME, "RCAS", cb_luma_global_settings.GameSettings.RCAS); - // SRUser + // SR User settings + reshade::get_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); reshade::get_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; + reshade::get_config_value(runtime, NAME, "sr_user_mip_bias_offset", sr_user_mip_bias_offset); } void DrawImGuiSettings(DeviceData& device_data) override @@ -668,6 +676,20 @@ class MiddleEarthShadowOfWar final : public Game if (ImGui::Button("Force Reset")) device_data.force_reset_sr = true; if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Force clearing of history so that aggregation begins anew."); + + ImGui::NewLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.75f, 1.f, 1.f, 1.f)); + ImGui::TextWrapped("[Super Resolution: Bloom & Transparency Missing Fix]"); + ImGui::PopStyleColor(); + + ImGui::PushID("SR: copy_resource"); + if (ImGui::Checkbox("Enable Fix", &sr_copy_resource)) + reshade::set_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); + ImGui::PopID(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + ImGui::SetTooltip("For some reason (Motion Blur + Depth of Field?) bloom and other transparency effects may go missing after Super Resolution draws.\nEnable this to copy the output back to the input, somehow fixing the issue."); + DrawResetButton(sr_copy_resource, false, "sr_copy_resource", runtime); } ImGui::NewLine(); From cc372f55f9ab0718784b241b66e7aacc9a3e4d79 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 21:47:44 -0700 Subject: [PATCH 24/33] Shadow of War: No more UAV access for SR. Pass in dummy resource for SR in Photo Mode. --- .../Games/Middle-earth Shadow of War/main.cpp | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index dcc4ac9e..08f27b29 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -35,7 +35,29 @@ namespace SR::Type sr_type_copy = SR::Type::None; // User toggle for UI skip draw - bool is_ui = true; + bool is_ui = true; + + // SR dummy black motion vector resource + ComPtr sr_dummy_black_mvs_texture; + ComPtr sr_dummy_black_mvs_resource; + void CreateDummyBlackMVSResource(ID3D11Device* device) + { + if (!sr_dummy_black_mvs_texture) + { + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = 1; + desc.Height = 1; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8_SNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + device->CreateTexture2D(&desc, nullptr, sr_dummy_black_mvs_texture.put()); + sr_dummy_black_mvs_texture->QueryInterface(sr_dummy_black_mvs_resource.put()); + } + } bool sr_copy_resource = false; // Bloom missing fix by copying output back to input. bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers. @@ -446,11 +468,6 @@ class MiddleEarthShadowOfWar final : public Game ComPtr srv; native_device_context->CSGetShaderResources(1, 1, srv.put()); srv->GetResource(managed_resources.resources["depth"_h].put()); - - // Take motion vectors (UAV 1) //TODO: also hitting UAV is prob worse perf than the SRV array later, but this is might be the only way to account for photomode. - ComPtr uav; - native_device_context->CSGetUnorderedAccessViews(1, 1, uav.put()); - uav->GetResource(managed_resources.resources["motion_vectors"_h].put()); return DrawOrDispatchOverrideType::None; } @@ -490,13 +507,25 @@ class MiddleEarthShadowOfWar final : public Game sr_implementations[device_data.sr_type]->UpdateSettings(sr_instance_data, native_device_context, settings_data); - // Get color SRV - ID3D11ShaderResourceView* srv_scene = nullptr; - native_device_context->PSGetShaderResources(is_has_vel ? 1 : 0, 1, &srv_scene); + // Get SRVs + std::array srvs; + native_device_context->PSGetShaderResources(0, srvs.size(), srvs.data()); + ComPtr resource_scene; - srv_scene->GetResource(resource_scene.put()); + ComPtr resource_mvs; + if (is_has_vel) + { + srvs[0]->GetResource(resource_mvs.put()); + srvs[1]->GetResource(resource_scene.put()); + } + else + { + srvs[0]->GetResource(resource_scene.put()); + CreateDummyBlackMVSResource(native_device); + } + ResetCOMArray(srvs); - // Get output RTV + // Get RTV ComPtr rtv; native_device_context->OMGetRenderTargets(1, rtv.put(), nullptr); ComPtr resource_rt; @@ -506,7 +535,7 @@ class MiddleEarthShadowOfWar final : public Game SR::SuperResolutionImpl::DrawData draw_data; draw_data.source_color = resource_scene.get(); draw_data.output_color = resource_rt.get(); - draw_data.motion_vectors = managed_resources.resources["motion_vectors"_h].get(); + draw_data.motion_vectors = is_has_vel ? resource_mvs.get() : sr_dummy_black_mvs_resource.get(); draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); // DrawData: Jitters are in range [-1, 1]. @@ -525,7 +554,7 @@ class MiddleEarthShadowOfWar final : public Game // For missing bloom and other transparent FXs... somehow if (device_data.has_drawn_sr && sr_copy_resource) native_device_context->CopyResource(draw_data.source_color, draw_data.output_color); - + return device_data.has_drawn_sr ? DrawOrDispatchOverrideType::Replaced : DrawOrDispatchOverrideType::None; } @@ -672,6 +701,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Requires TAA!"); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Only 100%% internal/render resolution is supported."); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Photo Mode works, but doesn't have motion data, so camera movement smears."); if (ImGui::Button("Force Reset")) device_data.force_reset_sr = true; if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) From 89d569ad63cb682dcba539000a0b86dba2aee12d Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 21:48:07 -0700 Subject: [PATCH 25/33] Shadow of War: draw_data.reset --- Source/Games/Middle-earth Shadow of War/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 08f27b29..90c4de81 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -537,6 +537,7 @@ class MiddleEarthShadowOfWar final : public Game draw_data.output_color = resource_rt.get(); draw_data.motion_vectors = is_has_vel ? resource_mvs.get() : sr_dummy_black_mvs_resource.get(); draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); + draw_data.reset = !device_data.has_drawn_sr; // DrawData: Jitters are in range [-1, 1]. draw_data.jitter_x = g_jitter_x * -0.5f; From f0bd15039ee0ca038d57d6ea25927542ee21cc7d Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 20 Jul 2026 21:49:42 -0700 Subject: [PATCH 26/33] Shadow of War: typo --- Source/Games/Middle-earth Shadow of War/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 90c4de81..e7dd3ece 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -676,7 +676,7 @@ class MiddleEarthShadowOfWar final : public Game reshade::set_config_value(runtime, NAME, "BlowoutCorrection", cb_luma_global_settings.GameSettings.BlowoutCorrection); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("By extending/straighting the rolloff curve to HDR, we lose the blowout originally intended by the SDR low curve.\nSo, increase to correct the hues of the new HDR highlights using the results from SDR."); + ImGui::SetTooltip("By extending/straightening the rolloff curve to HDR, we lose the blowout originally intended by the SDR low curve.\nSo, increase to correct the hues of the new HDR highlights using the results from SDR."); DrawResetButton(cb_luma_global_settings.GameSettings.BlowoutCorrection, default_luma_global_game_settings.BlowoutCorrection, "BlowoutCorrection", runtime); if (ImGui::Button("Extended Tonemap (Desmos)")) From 3a1241298ba4634317e765563af3ca197c53b9d4 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 09:36:08 -0700 Subject: [PATCH 27/33] Shadow of War: JitterHistory shows raw from CB --- Source/Games/Middle-earth Shadow of War/main.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index e7dd3ece..b7510eb3 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -316,10 +316,10 @@ namespace Website namespace JitterHistory { //list - static std::vector history; + static std::vector history; static bool is_scan = false; - static void OnSRDraw(float2 jitter) + static void AddNewToHistory(float2 jitter, float2 jitter_raw) { // looped? for (const auto& j : history) @@ -332,7 +332,7 @@ namespace JitterHistory } // add new - history.push_back(jitter); + history.push_back(float4{jitter.x, jitter.y, jitter_raw.x, jitter_raw.y}); } static void DrawImGuiSettings() @@ -347,9 +347,10 @@ namespace JitterHistory // list ImGui::Text("Count: %d", static_cast(history.size())); + ImGui::Text("(Effective) | (Raw from CB)", static_cast(history.size())); for (const auto& jitter : history) { - ImGui::Text("(%f, %f)", jitter.x, jitter.y); + ImGui::Text("(%f, %f) | (%f, %f)", jitter.x, jitter.y, jitter.z, jitter.w); } } } @@ -543,7 +544,7 @@ class MiddleEarthShadowOfWar final : public Game draw_data.jitter_x = g_jitter_x * -0.5f; draw_data.jitter_y = g_jitter_y * 0.5f; #if DEVELOPMENT - JitterHistory::OnSRDraw({draw_data.jitter_x, draw_data.jitter_y}); + JitterHistory::AddNewToHistory({draw_data.jitter_x, draw_data.jitter_y}, {g_jitter_x, g_jitter_y}); #endif // DrawData: resolution From 1897e9cf6eac89ea3fd8b1161388da1e9491f293 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 13:45:53 -0700 Subject: [PATCH 28/33] Shadow of War: tonemap safer which fixed TAA black --- .../tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl | 12 +++++++----- Source/Games/Middle-earth Shadow of War/main.cpp | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl index cb958b10..510c8a80 100644 --- a/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl +++ b/Shaders/Middle-earth Shadow of War/tonemapwithexposure_sdr_0xFD32C367.ps_5_0.hlsl @@ -23,11 +23,13 @@ cbuffer cb3 : register(b3) // https://www.desmos.com/calculator/stnfdhk9t1 float Rolloff(float x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return safeDivision(x, x * invPeak + invExposure, 0); + // return safeDivision(x, x * invPeak + invExposure, 0); + return x / max(9.99999975e-006, x * invPeak + invExposure); } float3 Rolloff(float3 x, float contrast, float invPeak, float invExposure) { x = pow(x, contrast); - return safeDivision(x, x * invPeak + invExposure, 0); + // return safeDivision(x, x * invPeak + invExposure, 0); + return x / max(9.99999975e-006, x * invPeak + invExposure); } float RolloffLocalMax(float contrast, float invPeak, float invExposure) { @@ -50,7 +52,7 @@ float3 RolloffSDRAndHDR(float3 x, float contrast, float invPeak, float invExposu float thres; if (invPeak >= 0) { thres = RolloffLocalMax(contrast, invPeak, invExposure); - thres = max(thres, 0.000001); //just in case of undef + thres = max(thres, 9.99999975e-006); //just in case of undef } else { thres = 1; // local max is unsolvable, so fallback 1 } @@ -92,6 +94,7 @@ void main( r0.xy = v1.xy / v1.ww; r0.xy = min(cb2[22].zw, r0.xy); r0.xyz = t0.Sample(s0_s, r0.xy).xyz; + r0.xyz = max(r0.xyz, 0); //NEEDED! rare cases, like in map // idk mask r1.xyz = (int3)r0.xyz & int3(0x7f800000,0x7f800000,0x7f800000); @@ -108,8 +111,7 @@ void main( // r0.xyz = t1.Load(2).x - DVS1; //debug identify invExposure // max channel saturation / white path - r0.w = max(r0.y, r0.z); - r0.w = max(r0.x, r0.w); + r0.w = max3(r0.x, r0.y, r0.z); r0.w = max(9.99999975e-006, r0.w); r0.xyz = r0.xyz / r0.www; //to 1 diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index b7510eb3..d026e729 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -693,7 +693,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::TextWrapped("[Super Resolution: Disabled]"); ImGui::PopStyleColor(); - ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Vanilla TAA is pending a fix.\nIt'll artefact to black for extremely bright highlights."); + ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Enable above for more..."); } else { From bae964a93346a8b62fc8c30754eb31330ad7a443 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 20:29:30 -0700 Subject: [PATCH 29/33] Shadow of War: Removed "needs testing" comment for jitter since it works! --- Source/Games/Middle-earth Shadow of War/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index d026e729..208f805d 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -445,7 +445,6 @@ class MiddleEarthShadowOfWar final : public Game D3D11_BUFFER_DESC desc; buffer->GetDesc(&desc); - // This alone should be reliable? Needs testing! if (desc.BindFlags == D3D11_BIND_CONSTANT_BUFFER && desc.ByteWidth == 544) { // cb0[31].xy in PS TAA 0x8D06D556. From 348809ffabc8895c17c3b1686d5d6997162fa1ff Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 22:21:58 -0700 Subject: [PATCH 30/33] Shadow of War: Sampler upgrades default off again. Tooltip to warn user. --- .../Games/Middle-earth Shadow of War/main.cpp | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 208f805d..cbf7d435 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -60,7 +60,7 @@ namespace } bool sr_copy_resource = false; // Bloom missing fix by copying output back to input. - bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers. + bool sr_user_allow_upgraded_samplers = true; // Let user control ignore_upgraded_samplers. //TODO: Find and only enable when it is safe in pipeline for upgrade. float sr_user_mip_bias_offset = 0.f; // Let user control mip bias offset, where 0 is SR recommended. } @@ -600,8 +600,9 @@ class MiddleEarthShadowOfWar final : public Game { std::shared_lock shared_lock_samplers(s_mutex_samplers); - if (device_data.sr_type != SR::Type::None && !device_data.sr_suppressed && !ignore_upgraded_samplers) - device_data.texture_mip_lod_bias_offset = sr_user_mip_bias_offset < 0 ? sr_user_mip_bias_offset : SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y); + if (!ignore_upgraded_samplers) + device_data.texture_mip_lod_bias_offset = sr_user_mip_bias_offset == 0 && device_data.sr_type != SR::Type::None ? //if SR on and not overriden, use SR's recommended + SR::GetMipLODBias(device_data.render_resolution.y, device_data.output_resolution.y) : sr_user_mip_bias_offset; else device_data.texture_mip_lod_bias_offset = 0.0f; } @@ -624,7 +625,7 @@ class MiddleEarthShadowOfWar final : public Game // SR User settings reshade::get_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); reshade::get_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); - ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; + ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; //TODO: Find and only enable when it is safe in pipeline for upgrade. reshade::get_config_value(runtime, NAME, "sr_user_mip_bias_offset", sr_user_mip_bias_offset); } @@ -715,7 +716,7 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("SR: copy_resource"); - if (ImGui::Checkbox("Enable Fix", &sr_copy_resource)) + if (ImGui::Checkbox("Enable Fix (Read Tooltip)", &sr_copy_resource)) reshade::set_config_value(runtime, NAME, "sr_copy_resource", sr_copy_resource); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) @@ -730,16 +731,14 @@ class MiddleEarthShadowOfWar final : public Game ImGui::PopStyleColor(); ImGui::PushID("SR: sr_user_allow_upgraded_samplers"); - if (ImGui::Checkbox("Allow Sampler Upgrades", &sr_user_allow_upgraded_samplers)) - { + if (ImGui::Checkbox("Enable Upgrade (Read Tooltip)", &sr_user_allow_upgraded_samplers)) reshade::set_config_value(runtime, NAME, "sr_user_allow_upgraded_samplers", sr_user_allow_upgraded_samplers); - ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; - } ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance\nMay change more than just texture detail.\nMay also cost some performance."); - DrawResetButton(sr_user_allow_upgraded_samplers, true, "sr_user_allow_upgraded_samplers", runtime); - + ImGui::SetTooltip("Upgrade texture samplers to retain detail at a distance\n\nShould be on, but it's weird in this game:\n- Increased LOD, but texture color gets darker.\n- Broken metallic armor in rain.\n- Maybe more that idk of.\n\nUse at your own risk..."); + DrawResetButton(sr_user_allow_upgraded_samplers, false, "sr_user_allow_upgraded_samplers", runtime); + ignore_upgraded_samplers = !sr_user_allow_upgraded_samplers; //TODO: Find and only enable when it is safe in pipeline for upgrade. + //sr_user_mip_bias_offset slider if (ignore_upgraded_samplers) ImGui::BeginDisabled(); ImGui::PushID("SR: sr_user_mip_bias_offset"); @@ -747,7 +746,7 @@ class MiddleEarthShadowOfWar final : public Game reshade::set_config_value(runtime, NAME, "sr_user_mip_bias_offset", sr_user_mip_bias_offset); ImGui::PopID(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - ImGui::SetTooltip("Negative bias offset increases texture detail at a distance.\n\nSet 0 for Super Resolution recommendation.\nOtherwise, you can override."); + ImGui::SetTooltip("Negative offset increases detail.\nSet 0 for Super Resolution recommendation."); if (ignore_upgraded_samplers) ImGui::EndDisabled(); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextWrapped("Effective: %.3f", device_data.texture_mip_lod_bias_offset); } From 9a9ab6b948c91432d2661b7f68ea822c52118e04 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 22:23:41 -0700 Subject: [PATCH 31/33] Shadow of War: force DEVELOPMENT Shader Define off --- Source/Games/Middle-earth Shadow of War/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index cbf7d435..1b567d86 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -388,6 +388,8 @@ class MiddleEarthShadowOfWar final : public Game shader_defines_data.append_range(game_shader_defines_data); // Shader Defines: change defaults + GetShaderDefineData(DEVELOPMENT_HASH).SetDefaultValue(DEVELOPMENT ? '1' : '0'); //TODO: idk why i have to force it for PUBLISHING builds + GetShaderDefineData(DEVELOPMENT_HASH).SetValue(DEVELOPMENT ? '1' : '0'); //TODO: idk why i have to force it for PUBLISHING builds GetShaderDefineData(POST_PROCESS_SPACE_TYPE_HASH).SetDefaultValue('1'); // linear GetShaderDefineData(GAMMA_CORRECTION_TYPE_HASH).SetDefaultValue('0'); // don't use built in gamma correction GetShaderDefineData(UI_DRAW_TYPE_HASH).SetDefaultValue('2'); // Direct (inverse scene brightness draws) From a68819552f9fc6d8e1b1d82bb41940d37db9d960 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 22:24:27 -0700 Subject: [PATCH 32/33] Shadow of War: retuned Fire Retuning --- Source/Games/Middle-earth Shadow of War/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 1b567d86..75aabfa0 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -400,8 +400,8 @@ class MiddleEarthShadowOfWar final : public Game // CB init default values default_luma_global_game_settings.WhiteClip = cb_luma_global_settings.GameSettings.WhiteClip = 1.; default_luma_global_game_settings.BlowoutCorrection = cb_luma_global_settings.GameSettings.BlowoutCorrection = 0.3; - default_luma_global_game_settings.RetunedFirePeak = cb_luma_global_settings.GameSettings.RetunedFirePeak = 1.26; - default_luma_global_game_settings.RetunedFireBoost = cb_luma_global_settings.GameSettings.RetunedFireBoost = 2.6; + default_luma_global_game_settings.RetunedFirePeak = cb_luma_global_settings.GameSettings.RetunedFirePeak = 1.2; + default_luma_global_game_settings.RetunedFireBoost = cb_luma_global_settings.GameSettings.RetunedFireBoost = 2.2; default_luma_global_game_settings.GodRays = cb_luma_global_settings.GameSettings.GodRays = 1.; default_luma_global_game_settings.Bloom = cb_luma_global_settings.GameSettings.Bloom = 1.; default_luma_global_game_settings.RCAS = cb_luma_global_settings.GameSettings.RCAS = 0.; From 31279ce6b81333c07ad458cbdc661db85027b80a Mon Sep 17 00:00:00 2001 From: David Huynh Date: Tue, 21 Jul 2026 22:51:35 -0700 Subject: [PATCH 33/33] Shadow of War: FSR --- Source/Games/Middle-earth Shadow of War/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Games/Middle-earth Shadow of War/main.cpp b/Source/Games/Middle-earth Shadow of War/main.cpp index 75aabfa0..623011ff 100644 --- a/Source/Games/Middle-earth Shadow of War/main.cpp +++ b/Source/Games/Middle-earth Shadow of War/main.cpp @@ -1,6 +1,7 @@ #define MIDDLE_EARTH_SHADOW_OF_WAR 1 #define ENABLE_NGX 1 +#define ENABLE_FIDELITY_SK 1 #define DISABLE_AUTO_DEBUGGER 1 @@ -539,7 +540,6 @@ class MiddleEarthShadowOfWar final : public Game draw_data.output_color = resource_rt.get(); draw_data.motion_vectors = is_has_vel ? resource_mvs.get() : sr_dummy_black_mvs_resource.get(); draw_data.depth_buffer = managed_resources.resources["depth"_h].get(); - draw_data.reset = !device_data.has_drawn_sr; // DrawData: Jitters are in range [-1, 1]. draw_data.jitter_x = g_jitter_x * -0.5f; @@ -551,6 +551,11 @@ class MiddleEarthShadowOfWar final : public Game // DrawData: resolution draw_data.render_width = device_data.render_resolution.x; draw_data.render_height = device_data.render_resolution.y; + + // DrawData: Misc. + constexpr float fov_rad = 60.f * (3.14f / 180.f); + draw_data.vert_fov = device_data.sr_type == SR::Type::FSR ? fov_rad : 0.f; //FSR fails w/o fov + draw_data.reset = !device_data.has_drawn_sr; // DRAW device_data.has_drawn_sr = sr_implementations[device_data.sr_type]->Draw(sr_instance_data, native_device_context, draw_data);