From 4915560ef430df539b1188b9f6b4dc2af257ae1f Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sat, 27 Jun 2026 21:43:49 -0400 Subject: SSLR fixes and tests Signed-off-by: Andrew Opalach --- Plugin.cs | 100 +++++++++++++++++++++----- Shaders/sslr_resolve.diff | 14 +++- Shaders/sslr_resolve_no_dither.diff | 14 +++- Shaders/sslr_resolve_no_jitter.diff | 14 +++- Shaders/sslr_resolve_no_jitter_min_only.diff | 11 +++ Shaders/sslr_resolve_no_jitter_no_dither.diff | 14 +++- 6 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 Shaders/sslr_resolve_no_jitter_min_only.diff diff --git a/Plugin.cs b/Plugin.cs index 2dfda8b..412d1b8 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -16,9 +16,7 @@ using System.Diagnostics; using ImGuiNET; using SharpPluginLoader.Core; -#if SHADER_FEATURES using SharpPluginLoader.Core.Rendering; -#endif #if RESOURCE_ADJUSTMENT using SharpPluginLoader.Core.Resources; #endif @@ -1562,11 +1560,11 @@ namespace WorldTuningTool private delegate void UpdateSSLRParams(nint stackOffset); private Hook? updateSSLRParams; private static Parameter[] sslrParameters = { - newParameter("SSLR Loop Count", 0xE628, ParameterType.INT), + newParameter("SSLR Loop Count", 0xE628, ParameterType.INT, pStep(1)), newParameter("SSLR Loop Count Factor for CBR", 0xE62C, ParameterType.FLOAT), newParameter("SSLR Eliminate Depth", 0xE630, ParameterType.FLOAT), - newParameter("SSLR Accurate Threshold", 0xE644, ParameterType.FLOAT), - newParameter("SSLR Accurate Threshold (HQ)", 0xE64C, ParameterType.FLOAT), + newParameter("SSLR Accurate Threshold", 0xE644, ParameterType.FLOAT, pStep(0.001f)), + newParameter("SSLR Accurate Threshold (HQ)", 0xE64C, ParameterType.FLOAT, pStep(0.001f)), newParameter("SSLR Dither Radius", 0xE634, ParameterType.FLOAT), newParameter("SSLR Importance Bias", 0xE638, ParameterType.FLOAT), newParameter("SSLR Mip Scale", 0xE63C, ParameterType.FLOAT), @@ -1815,11 +1813,11 @@ namespace WorldTuningTool private static void shadowResEnable(int multiplier) { + Assert(multiplier != 1); if (multiplier == currentShadowResMultiplier) { return; } - Assert(multiplier != 1); switch (currentShadowResMultiplier) { case 1: @@ -1912,6 +1910,7 @@ namespace WorldTuningTool private Patch ssrRes1; private Patch ssrRes2; private Patch ssrRes3; + private Patch ssrRes4; private Patch ssrShr1; private Patch ssrShr2; private Patch ssrShr3; @@ -1947,6 +1946,11 @@ namespace WorldTuningTool private Patch ssrSars25; private Patch ssrSars26; + private bool skipSSLRMipMapping = false; + private bool unknownFullResPath = false; + private bool continousSSLRTemporalReset = false; + private Patch forceSSLRTemporalReset; + private bool fullResVolumeBlur = false; private Patch volumeSars1; private Patch volumeSars2; @@ -2361,16 +2365,21 @@ namespace WorldTuningTool ssrSars8 = new Patch(new IntPtr(0x1422838E7) + 0x3, [0x03]); ssrSars9 = new Patch(new IntPtr(0x1422838F0) + 0x2, [0x03]); ssrSars10 = new Patch(new IntPtr(0x1422838FC) + 0x2, [0x03]); + // Mips blur dispatch. ssrSars11 = new Patch(new IntPtr(0x1422839B0), [0x8D, 0x0E, 0x44, 0x8D, 0x76, 0x01, 0x90]); - // RayAppendBuffer dispatch dimensions. - ssrSars12 = new Patch(new IntPtr(0x14228C323) + 0x3, [0x3]); // 4 -> 3 - ssrSars13 = new Patch(new IntPtr(0x14228C32D) + 0x2, [0x3]); - ssrSars14 = new Patch(new IntPtr(0x14228C3F4) + 0x2, [0x7]); // 8 -> 7 + // RayAppendBuffer dispatch dimensions, 4 -> 3 wasteful. + //ssrSars12 = new Patch(new IntPtr(0x14228C323) + 0x3, [0x3]); // 4 -> 3 + //ssrSars13 = new Patch(new IntPtr(0x14228C32D) + 0x2, [0x3]); + // Clear trace buffer, 8 -> 7 wasteful + //ssrSars14 = new Patch(new IntPtr(0x14228C3F4) + 0x2, [0x7]); // 8 -> 7 // Enable FULL_RES path for buffer only. Not sure exactly what this does yet. // Probably increases buffer size if anything. (Maybe allows higher mip0 threshold to work?) ssrRes3 = new Patch(new IntPtr(0x14228C19D), [0x31, 0xC0, 0x90, 0x90, 0x90]); + // Skip mip mapping pass (part of _FULL_RES). + ssrRes4 = new Patch(new IntPtr(0x142282B53), [0x31, 0xC0, 0x90, 0x90, 0x90]); + // Depth mip texture resolution. ssrShr3 = new Patch(new IntPtr(0x14269DE47), [0x90, 0x90]); ssrShr4 = new Patch(new IntPtr(0x14269DE54), [0x90, 0x90]); @@ -2391,9 +2400,11 @@ namespace WorldTuningTool ssrSars23 = new Patch(new IntPtr(0x1422832BC) + 0x2, [0x3]); ssrSars24 = new Patch(new IntPtr(0x1422832C8) + 0x2, [0x3]); - // Idk yet. - ssrSars25 = new Patch(new IntPtr(0x14228686D) + 0x3, [0x3]); - ssrSars26 = new Patch(new IntPtr(0x142286877) + 0x2, [0x3]); + // Resolve pass, 4 -> 3 wasteful. + //ssrSars25 = new Patch(new IntPtr(0x14228686D) + 0x3, [0x3]); + //ssrSars26 = new Patch(new IntPtr(0x142286877) + 0x2, [0x3]); + + forceSSLRTemporalReset = new Patch(new IntPtr(0x14228CE53), [0xB9, 0x01, 0x00, 0x00, 0x00, 0x90, 0x90]); createLight = new NativeFunction(0x1418A3EF0); //createLightObject = Hook.Create(0x1418A3EF0, CreateLightObjectHook); @@ -2415,7 +2426,7 @@ namespace WorldTuningTool { ssrRes1.Enable(); ssrRes2.Enable(); - ssrRes3.Enable(); + //ssrRes3.Enable(); ssrShr1.Enable(); ssrShr2.Enable(); ssrShr3.Enable(); @@ -2437,8 +2448,7 @@ namespace WorldTuningTool ssrSars11.Enable(); //ssrSars12.Enable(); //ssrSars13.Enable(); - ssrSars24.Enable(); - ssrSars14.Enable(); + //ssrSars14.Enable(); ssrSars15.Enable(); ssrSars16.Enable(); ssrSars17.Enable(); @@ -2448,8 +2458,9 @@ namespace WorldTuningTool ssrSars21.Enable(); ssrSars22.Enable(); ssrSars23.Enable(); - ssrSars25.Enable(); - ssrSars26.Enable(); + ssrSars24.Enable(); + //ssrSars25.Enable(); + //ssrSars26.Enable(); } #endif fullResVolumeBlur = patches.FullResolutionVolumeBlur; @@ -4010,6 +4021,48 @@ namespace WorldTuningTool ImGui.Text("Some min/max values are set to avoid crashes, so be warned."); ImGui.EndTooltip(); } + + if (ImGui.Checkbox("Continous SSLR Temporal Reset", ref continousSSLRTemporalReset)) + { + if (continousSSLRTemporalReset) + { + forceSSLRTemporalReset.Enable(); + } + else + { + forceSSLRTemporalReset.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Don't reference tBlendMap in SSLR resolve."); + ImGui.EndTooltip(); + } + + if (ImGui.Checkbox("Skip SSLR Mip Mapping", ref skipSSLRMipMapping)) + { + if (skipSSLRMipMapping) + { + ssrRes4.Enable(); + } + else + { + ssrRes4.Disable(); + } + } + + if (ImGui.Checkbox("Force unknown _FULL_RES (Probably Useless)", ref unknownFullResPath)) + { + if (unknownFullResPath) + { + ssrRes3.Enable(); + } + else + { + ssrRes3.Disable(); + } + } + ImGui.PushItemWidth(width * 0.15f); ImGui.Text($"FPS: {MemoryUtil.GetRef(sMain!.Instance + 0x68)}"); ImGui.Text($"Delta Time: {MemoryUtil.GetRef(sMain!.Instance + 0x94)}"); @@ -4182,6 +4235,17 @@ namespace WorldTuningTool } } } + else + { + if (hash == "8703f55f-6c22fba7-1ef876f1-4767379e") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter_min_only.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR resolve no jitter shader replaced."); + } + } + } } #endif } diff --git a/Shaders/sslr_resolve.diff b/Shaders/sslr_resolve.diff index c1128f3..71712e6 100644 --- a/Shaders/sslr_resolve.diff +++ b/Shaders/sslr_resolve.diff @@ -1,5 +1,5 @@ --- a/sslr_resolve.asm 2026-06-24 10:47:30.332174347 -0400 -+++ b/sslr_resolve.asm 2026-06-24 10:51:54.676142355 -0400 ++++ b/sslr_resolve.asm 2026-06-27 20:33:43.127066465 -0400 @@ -202,14 +202,14 @@ dcl_thread_group 16, 16, 1 imad [precise(x)] r0.x, vThreadIDInGroup.y, l(16), vThreadIDInGroup.x @@ -7,8 +7,9 @@ -ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 1, 1, 0) +ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 0, 0, 0) iadd [precise(yz)] r0.yz, r0.yyzy, vThreadIDInGroup.xxyx - iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) +-iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) -ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 1, 1, 0) ++iadd [precise(xy)] r1.xy, r0.yzyy, l(-0, -0, 0, 0) +ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 0, 0, 0) ige [precise(yz)] r0.yz, r1.xxyx, r0.yyzy and [precise(y)] r0.y, r0.z, r0.y @@ -27,3 +28,12 @@ ishl [precise(w)] r7.w, r10.y, l(4) iadd [precise(w)] r7.w, r7.w, r10.x ld_structured [precise(w)] r8.w, r7.w, l(12), g0.xxxx +@@ -433,7 +431,7 @@ + f16tof32 r11.x, r8.w + ushr r8.w, r8.w, l(16) + f16tof32 r11.y, r8.w +- sample_l_indexable(texture2d)(float,float,float,float) r11.xzw, r11.xyxx, t10.xwyz, s0, r7.w ++ sample_l_indexable(texture2d)(float,float,float,float) r11.xzw, r11.xyxx, t10.xwyz, s0, l(0.000000) + add r7.w, r11.y, l(-0.500000) + mad r7.w, -|r7.w|, l(2.000000), l(1.000000) + mul_sat r7.w, r7.w, cb3[4].x diff --git a/Shaders/sslr_resolve_no_dither.diff b/Shaders/sslr_resolve_no_dither.diff index 756d85c..6cb03ca 100644 --- a/Shaders/sslr_resolve_no_dither.diff +++ b/Shaders/sslr_resolve_no_dither.diff @@ -1,5 +1,5 @@ --- a/sslr_resolve_no_dither.asm 2026-06-24 10:47:30.333700495 -0400 -+++ b/sslr_resolve_no_dither.asm 2026-06-23 16:13:51.616100220 -0400 ++++ b/sslr_resolve_no_dither.asm 2026-06-27 20:33:57.579056746 -0400 @@ -202,14 +202,14 @@ dcl_thread_group 16, 16, 1 imad [precise(x)] r0.x, vThreadIDInGroup.y, l(16), vThreadIDInGroup.x @@ -7,8 +7,9 @@ -ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 1, 1, 0) +ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 0, 0, 0) iadd [precise(yz)] r0.yz, r0.yyzy, vThreadIDInGroup.xxyx - iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) +-iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) -ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 1, 1, 0) ++iadd [precise(xy)] r1.xy, r0.yzyy, l(0, 0, 0, 0) +ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 0, 0, 0) ige [precise(yz)] r0.yz, r1.xxyx, r0.yyzy and [precise(y)] r0.y, r0.z, r0.y @@ -28,3 +29,12 @@ imad [precise(w)] r3.w, r7.y, l(16), r7.x ld_structured [precise] r7.xyzw, r3.w, l(0), g0.xyzw and [precise(w)] r3.w, r7.w, l(0x80000000) +@@ -403,7 +402,7 @@ + if_z r3.w + if_nz r6.w + mad r9.z, r9.x, r4.w, cb3[3].x +- sample_l_indexable(texture2d)(float,float,float,float) r11.xyz, r7.xyxx, t10.xyzw, s0, r9.z ++ sample_l_indexable(texture2d)(float,float,float,float) r11.xyz, r7.xyxx, t10.xyzw, s0, l(0.000000) + mul r11.xyz, r7.zzzz, r11.xyzx + mul r10.w, r7.z, r10.w + add [precise(z)] r9.z, -r9.y, l(1.000000) diff --git a/Shaders/sslr_resolve_no_jitter.diff b/Shaders/sslr_resolve_no_jitter.diff index e3e8f9f..22d9163 100644 --- a/Shaders/sslr_resolve_no_jitter.diff +++ b/Shaders/sslr_resolve_no_jitter.diff @@ -1,5 +1,5 @@ --- a/sslr_resolve_no_jitter.asm 2026-06-24 10:47:30.335375123 -0400 -+++ b/sslr_resolve_no_jitter.asm 2026-06-23 16:14:11.607385425 -0400 ++++ b/sslr_resolve_no_jitter.asm 2026-06-27 20:31:53.276024705 -0400 @@ -202,14 +202,14 @@ dcl_thread_group 16, 16, 1 imad [precise(x)] r0.x, vThreadIDInGroup.y, l(16), vThreadIDInGroup.x @@ -7,8 +7,9 @@ -ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 1, 1, 0) +ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 0, 0, 0) iadd [precise(yz)] r0.yz, r0.yyzy, vThreadIDInGroup.xxyx - iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) +-iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) -ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 1, 1, 0) ++iadd [precise(xy)] r1.xy, r0.yzyy, l(0, 0, 0, 0) +ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 0, 0, 0) ige [precise(yz)] r0.yz, r1.xxyx, r0.yyzy and [precise(y)] r0.y, r0.z, r0.y @@ -27,3 +28,12 @@ ishl [precise(w)] r7.w, r10.y, l(4) iadd [precise(w)] r7.w, r7.w, r10.x ld_structured [precise(w)] r8.w, r7.w, l(12), g0.xxxx +@@ -422,7 +420,7 @@ + f16tof32 r11.x, r8.w + ushr r8.w, r8.w, l(16) + f16tof32 r11.y, r8.w +- sample_l_indexable(texture2d)(float,float,float,float) r11.xzw, r11.xyxx, t10.xwyz, s0, r7.w ++ sample_l_indexable(texture2d)(float,float,float,float) r11.xzw, r11.xyxx, t10.xwyz, s0, l(0.000000) + add r7.w, r11.y, l(-0.500000) + mad r7.w, -|r7.w|, l(2.000000), l(1.000000) + mul_sat r7.w, r7.w, cb3[4].x diff --git a/Shaders/sslr_resolve_no_jitter_min_only.diff b/Shaders/sslr_resolve_no_jitter_min_only.diff new file mode 100644 index 0000000..2a2577f --- /dev/null +++ b/Shaders/sslr_resolve_no_jitter_min_only.diff @@ -0,0 +1,11 @@ +--- a/sslr_resolve_no_jitter.asm 2026-06-24 10:47:30.335375123 -0400 ++++ b/sslr_resolve_no_jitter.asm 2026-06-26 15:45:29.835286175 -0400 +@@ -353,7 +353,7 @@ + mul r2.w, r2.w, cb3[2].w + mul [precise(w)] r3.w, r2.x, r2.x + mul [precise(w)] r3.w, r3.w, l(0.500000) +- min [precise(w)] r4.w, cb3[2].y, l(8.000000) ++ min [precise(w)] r4.w, cb3[2].y, l(16.000000) + mov r7.xyz, l(0,0,0,0) + mov [precise(x)] r8.x, r1.w + mov r8.y, r2.w diff --git a/Shaders/sslr_resolve_no_jitter_no_dither.diff b/Shaders/sslr_resolve_no_jitter_no_dither.diff index ebcdb47..ec08ced 100644 --- a/Shaders/sslr_resolve_no_jitter_no_dither.diff +++ b/Shaders/sslr_resolve_no_jitter_no_dither.diff @@ -1,5 +1,5 @@ --- a/sslr_resolve_no_jitter_no_dither.asm 2026-06-24 10:47:30.336853482 -0400 -+++ b/sslr_resolve_no_jitter_no_dither.asm 2026-06-23 16:16:47.490979883 -0400 ++++ b/sslr_resolve_no_jitter_no_dither.asm 2026-06-27 20:34:13.469354714 -0400 @@ -171,14 +171,14 @@ dcl_thread_group 16, 16, 1 imad [precise(x)] r0.x, vThreadIDInGroup.y, l(16), vThreadIDInGroup.x @@ -7,8 +7,9 @@ -ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 1, 1, 0) +ushr [precise(yz)] r0.yz, r0.yyzy, l(0, 0, 0, 0) iadd [precise(yz)] r0.yz, r0.yyzy, vThreadIDInGroup.xxyx - iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) +-iadd [precise(xy)] r1.xy, r0.yzyy, l(-4, -4, 0, 0) -ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 1, 1, 0) ++iadd [precise(xy)] r1.xy, r0.yzyy, l(0, 0, 0, 0) +ushr [precise(yz)] r0.yz, cb1[2].xxyx, l(0, 0, 0, 0) ige [precise(yz)] r0.yz, r1.xxyx, r0.yyzy and [precise(y)] r0.y, r0.z, r0.y @@ -28,3 +29,12 @@ imad [precise(w)] r3.w, r7.y, l(16), r7.x ld_structured [precise] r7.xyzw, r3.w, l(0), g0.xyzw and [precise(w)] r3.w, r7.w, l(0x80000000) +@@ -361,7 +360,7 @@ + if_z r3.w + if_nz r6.w + mad r9.z, r9.x, r4.w, cb3[3].x +- sample_l_indexable(texture2d)(float,float,float,float) r11.xyz, r7.xyxx, t10.xyzw, s0, r9.z ++ sample_l_indexable(texture2d)(float,float,float,float) r11.xyz, r7.xyxx, t10.xyzw, s0, l(0.000000) + mul r11.xyz, r7.zzzz, r11.xyzx + mul r10.w, r7.z, r10.w + add [precise(z)] r9.z, -r9.y, l(1.000000) -- cgit v1.2.3-101-g0448