From 2fca589444c29b383c00576fe46cf50cc3971cba Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 24 Jun 2026 13:22:48 -0400 Subject: Progress on full res SSR Signed-off-by: Andrew Opalach --- Plugin.cs | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 241 insertions(+), 56 deletions(-) (limited to 'Plugin.cs') diff --git a/Plugin.cs b/Plugin.cs index 99d9bbc..663ddd1 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -7,6 +7,9 @@ using System.Numerics; using System.Globalization; using System.Runtime.CompilerServices; +#if SHADER_FEATURES +using System.Runtime.InteropServices; +#endif #if ENABLE_ASSERTS using System.Diagnostics; #endif @@ -25,6 +28,7 @@ using SharpPluginLoader.Core.Entities; // @TODO: // - Configurable Broad Area Shadow Resolution. +// - Hook sMhScene constructor to set hqMode. // - Optimized update logic. // - Only update non-override values when ui is shown. // - Map sky params. @@ -1880,6 +1884,45 @@ namespace WorldTuningTool setShadowQuality.Invoke(MemoryUtil.Read(sMhScene!.Instance + 0x5530) + 1); } + private bool fullResSSLR = false; + private Patch ssrRes1; + private Patch ssrRes2; + private Patch ssrRes3; + private Patch ssrSars1; + private Patch ssrSars2; + private Patch ssrSars3; + private Patch ssrSars4; + private Patch ssrSars5; + private Patch ssrSars6; + private Patch ssrSars7; + private Patch ssrSars8; + private Patch ssrSars9; + private Patch ssrSars10; + private Patch ssrSars11; + private Patch ssrSars12; + private Patch ssrSars13; + private Patch ssrSars14; + private Patch ssrSars15; + private Patch ssrSars16; + private Patch ssrSars17; + private Patch ssrSars18; + private Patch ssrSars19; + private Patch ssrSars20; + private Patch ssrSars21; + private Patch ssrSars22; + private Patch ssrSars23; + private Patch ssrSars24; + private Patch ssrSars25; + private Patch ssrSars26; + private Patch ssrShr1; + private Patch ssrShr2; + private Patch ssrShr3; + private Patch ssrShr4; + private Patch ssrShr5; + private Patch ssrShr6; + private Patch ssrShr7; + private Patch ssrShr8; + private bool fullResVolumeBlur = false; private Patch volumeSars1; private Patch volumeSars2; @@ -2256,36 +2299,72 @@ namespace WorldTuningTool zeroFrameSkip = new Patch(new IntPtr(0x142246948), [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]); // The game will crash when trying to switch to the FULL_RES path for SSR. It's likley because - // it tries to access resources (shader, buffer, texture, etc.) that are not loaded. - // Ex: MonsterHunterWorld.exe+228C4A7 - mov rdi,[rdi+00000120] # Attempted read. - // MonsterHunterWorld.exe+259329B - lea rcx,[rdi+00000120] # Zero. + // it tries to access resources that are not available in the game files. + // Ex: MonsterHunterWorld.exe+259329B - lea rcx,[rdi+00000120] # Zero. + // MonsterHunterWorld.exe+228C4A7 - mov rdi,[rdi+00000120] # Attempted read. // The code that zero's these addresses looks like a shell of where they would be loaded. My assumption // is that it's compiled out and that this method of increasing the SSR resolution can't work. - // Though, it may still be possible by finagling the parameters of the half res case. /* // Attempt to forcefully enable FULL_RES path for SSR. - ssrRes1 = new Patch((nint)0x14228894D, [0x0F, 0x85, 0xB9, 0xAA, 0x30, 0x00]); - ssrRes1_1 = new Patch((nint)0x14259340C, [0xC6, 0x81, 0x28, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrRes2 = new Patch((nint)0x14228897D, [0x0F, 0x85, 0x99, 0xAA, 0x30, 0x00]); - ssrRes2_1 = new Patch((nint)0x14259341C, [0xC6, 0x81, 0x30, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrRes3 = new Patch((nint)0x1422889AD, [0x0F, 0x85, 0x79, 0xAA, 0x30, 0x00]); - ssrRes3_1 = new Patch((nint)0x14259342C, [0xC6, 0x81, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrRes4 = new Patch((nint)0x14259268C, [0x41, 0xC7, 0x86, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x34, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0xC7, 0x86, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x41, 0xC6, 0x86, 0x3C, 0x02, 0x00, 0x00, 0x01]); + ssrFullRes1 = new Patch((nint)0x14228894D, [0x0F, 0x85, 0xB9, 0xAA, 0x30, 0x00]); + ssrFullRes1_1 = new Patch((nint)0x14259340C, [0xC6, 0x81, 0x28, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes2 = new Patch((nint)0x14228897D, [0x0F, 0x85, 0x99, 0xAA, 0x30, 0x00]); + ssrFullRes2_1 = new Patch((nint)0x14259341C, [0xC6, 0x81, 0x30, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes3 = new Patch((nint)0x1422889AD, [0x0F, 0x85, 0x79, 0xAA, 0x30, 0x00]); + ssrFullRes3_1 = new Patch((nint)0x14259342C, [0xC6, 0x81, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes4 = new Patch((nint)0x14259268C, [0x41, 0xC7, 0x86, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xC7, 0x86, 0x34, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0xC7, 0x86, 0x38, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x41, 0xC6, 0x86, 0x3C, 0x02, 0x00, 0x00, 0x01]); */ - // None of these work either. - /* - // Don't scale resolution by SSR Factor. - ssrRes10 = new Patch((nint)0x142592DEF, [0x90, 0x90, 0x90, 0x90]); - ssrRes11 = new Patch((nint)0x142592E00, [0x90, 0x90, 0x90, 0x90]); - // Make SSR Factor 1.0. - ssrRes12 = new Patch((nint)0x1425926B8 + 0x7, [0x00, 0x00, 0x80, 0x3F]); - */ - /* Double width and height (3rd and 4th parameter). - initSSRHook = Hook.Create(0x1425924D5, InitSSRHook); // nint, nint, int, int - increaseSSRMipSize1 = new Patch((nint)0x142592EBA + 0x2, [0x2]); - increaseSSRMipSize2 = new Patch((nint)0x142592ED0 + 0x2, [0x2]); - */ + // SSLR resolution factor 0.5 -> 1.0 (not related to fSSLRFactor or fSSLRScale). + ssrRes1 = new Patch(new IntPtr(0x1425926B8) + 0x9, [0x80]); + ssrRes2 = new Patch(new IntPtr(0x1425934C0) + 0x8, [0x80]); + // Approximate mip resolution. + ssrShr1 = new Patch(new IntPtr(0x142592EBA) + 0x2, [0x3]); // 4 -> 3 + ssrShr2 = new Patch(new IntPtr(0x142592ED0) + 0x2, [0x3]); + // Compute dispatch dimensions. + ssrSars1 = new Patch(new IntPtr(0x142283626) + 0x3, [0x03]); // 4 -> 3 + ssrSars2 = new Patch(new IntPtr(0x142283633) + 0x2, [0x03]); + ssrSars3 = new Patch(new IntPtr(0x142283667) + 0x2, [0x03]); + ssrSars4 = new Patch(new IntPtr(0x14228366A) + 0x3, [0x03]); + ssrSars5 = new Patch(new IntPtr(0x14228366E) + 0x3, [0x03]); + ssrSars6 = new Patch(new IntPtr(0x142283672) + 0x3, [0x03]); + ssrSars7 = new Patch(new IntPtr(0x1422838D5) + 0x2, [0x03]); + ssrSars8 = new Patch(new IntPtr(0x1422838E7) + 0x3, [0x03]); + ssrSars9 = new Patch(new IntPtr(0x1422838F0) + 0x2, [0x03]); + ssrSars10 = new Patch(new IntPtr(0x1422838FC) + 0x2, [0x03]); + 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 + // 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]); + + // Depth mip texture resolution. + ssrShr3 = new Patch(new IntPtr(0x14269DE47), [0x90, 0x90]); + ssrShr4 = new Patch(new IntPtr(0x14269DE54), [0x90, 0x90]); + ssrShr5 = new Patch(new IntPtr(0x14269E07A), [0x90, 0x90]); + ssrShr6 = new Patch(new IntPtr(0x14269E080), [0x90, 0x90]); + // Approximate mip resolution. + ssrShr7 = new Patch(new IntPtr(0x14269DED3) + 0x2, [0x3]); + ssrShr8 = new Patch(new IntPtr(0x14269DEDA) + 0x3, [0x3]); + // Compute dispatch dimensions. + ssrSars15 = new Patch(new IntPtr(0x142282FD8) + 0x3, [0x3]); // 4 -> 3 + ssrSars16 = new Patch(new IntPtr(0x142282FE5) + 0x2, [0x3]); + ssrSars17 = new Patch(new IntPtr(0x142283014) + 0x3, [0x3]); + ssrSars18 = new Patch(new IntPtr(0x142283018) + 0x3, [0x3]); + ssrSars19 = new Patch(new IntPtr(0x14228301C) + 0x3, [0x3]); + ssrSars20 = new Patch(new IntPtr(0x142283020) + 0x2, [0x3]); + ssrSars21 = new Patch(new IntPtr(0x14228329D) + 0x2, [0x3]); + ssrSars22 = new Patch(new IntPtr(0x1422832B3) + 0x3, [0x3]); + 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]); createLight = new NativeFunction(0x1418A3EF0); //createLightObject = Hook.Create(0x1418A3EF0, CreateLightObjectHook); @@ -2301,6 +2380,49 @@ namespace WorldTuningTool { Config config = getConfig(); Config.PatchConfig patches = config.Patches; + fullResSSLR = patches.FullResolutionSSLR; +#if SHADER_FEATURES + if (fullResSSLR) + { + ssrRes1.Enable(); + ssrRes2.Enable(); + ssrRes3.Enable(); + ssrShr1.Enable(); + ssrShr2.Enable(); + ssrShr3.Enable(); + ssrShr4.Enable(); + ssrShr5.Enable(); + ssrShr6.Enable(); + ssrShr7.Enable(); + ssrShr8.Enable(); + ssrSars1.Enable(); + ssrSars2.Enable(); + ssrSars3.Enable(); + ssrSars4.Enable(); + ssrSars5.Enable(); + ssrSars6.Enable(); + ssrSars7.Enable(); + ssrSars8.Enable(); + ssrSars9.Enable(); + ssrSars10.Enable(); + ssrSars11.Enable(); + //ssrSars12.Enable(); + //ssrSars13.Enable(); + ssrSars24.Enable(); + ssrSars14.Enable(); + ssrSars15.Enable(); + ssrSars16.Enable(); + ssrSars17.Enable(); + ssrSars18.Enable(); + ssrSars19.Enable(); + ssrSars20.Enable(); + ssrSars21.Enable(); + ssrSars22.Enable(); + ssrSars23.Enable(); + ssrSars25.Enable(); + ssrSars26.Enable(); + } +#endif fullResVolumeBlur = patches.FullResolutionVolumeBlur; if (fullResVolumeBlur) { @@ -3332,6 +3454,18 @@ namespace WorldTuningTool { Config.PatchConfig patches = config.Patches; + if (ImGui.Checkbox("Full Resolution Screen Space Reflections (Requires Restart)", ref fullResSSLR)) + { + patches.FullResolutionSSLR = fullResSSLR; + config.Patches = patches; + saveConfig(config); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Restart Required"); + ImGui.EndTooltip(); + } + if (ImGui.Checkbox("Volume Rendering Full Resolution Blur Pass (Requires Area Change)", ref fullResVolumeBlur)) { if (fullResVolumeBlur) @@ -3780,67 +3914,59 @@ namespace WorldTuningTool public unsafe void OnCreateShader(ShaderInfo *info) { string hash = new string(info->DxbcHash); - if (!shadersLoadedOnce && hash == "2e4e18fd-6ea5eeae-2de3d65c-26ab36dd") + if (hash == "9ff245fb-4fd555e0-04d0ef15-84609fe1") { - if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample1.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/fxaa_max_quality.hlsl")) + { + info->Replacement.Type = ShaderSourceType.HLSL; + Log.Info("FXAA shader replaced."); + } + } + else if (!shadersLoadedOnce && hash == "2e4e18fd-6ea5eeae-2de3d65c-26ab36dd") + { + if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample1.shdr")) + { info->Replacement.Type = ShaderSourceType.Binary; Log.Info("Volume upsample shader 1 replaced."); } } else if (!shadersLoadedOnce && hash == "e2c8c13e-45bc99b2-4c3d7699-3d66188e") { - if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample2.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample2.shdr")) + { info->Replacement.Type = ShaderSourceType.Binary; Log.Info("Volume upsample shader 2 replaced."); } // This allows us to A/B using the volume rendering value 2 switch. //shadersLoadedOnce = true; } + /* else if (hash == "8cf2a107-ecde214b-9939b350-7b2af1a7") { - if (replaceShaderFromFile(info, $"{shaderPath}/cube_only.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/cube_only.shdr")) + { info->Replacement.Type = ShaderSourceType.Binary; Log.Info("Cube Only shader replaced."); } } - else if (hash == "b21dd223-98ab56ae-918264e6-eb6e8ee4") - { - if (replaceShaderFromFile(info, $"{shaderPath}/sslr.shdr")) { - info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("SSLR shader replaced."); - } - } - else if (hash == "9ff245fb-4fd555e0-04d0ef15-84609fe1") - { - if (replaceShaderFromFile(info, $"{shaderPath}/fxaa_max_quality.hlsl")) { - info->Replacement.Type = ShaderSourceType.HLSL; - Log.Info("FXAA shader replaced."); - } - } + */ else if (hash == "2eed1f00-e24d1b19-9d521064-17b9a586") { - if (replaceShaderFromFile(info, $"{shaderPath}/body_skin.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/body_skin.shdr")) + { info->Replacement.Type = ShaderSourceType.Binary; Log.Info("Body skin shader replaced."); } } else if (hash == "8e5e3c09-ebe77ee4-ba1cb659-d25bc7bf") { - if (replaceShaderFromFile(info, $"{shaderPath}/face.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/face.shdr")) + { info->Replacement.Type = ShaderSourceType.Binary; Log.Info("Face shader replaced."); } } /* - else if (hash == "ca33bab6-2119df84-41786a69-404471cd") - { - if (replaceShaderFromFile(info, $"{shaderPath}/color_grading.shdr")) { - info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("Color grading shader replaced."); - } - } - */ - /* else if (hash == "18a797dc-9458d333-59e6dff0-9790fcea") { if (replaceShaderFromFile(info, $"{shaderPath}/sssss.shdr")) { @@ -3850,14 +3976,73 @@ namespace WorldTuningTool } */ /* - else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91") + else if (hash == "ca33bab6-2119df84-41786a69-404471cd") { - if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) { + if (replaceShaderFromFile(info, $"{shaderPath}/color_grading.shdr")) { info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("SSLR mips shader replaced."); + Log.Info("Color grading shader replaced."); } } */ + if (fullResSSLR) + { + if (hash == "4b722c0e-8e787cd5-5eaf5e6c-09782f91") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_depth_mips.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR depth mips shader replaced."); + } + } + else if (hash == "5abc7a51-f182e7d6-14d2f897-6f851c0b") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_trace.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR trace shader replaced."); + } + } + else if (hash == "d7e47ffe-82572c64-795c4698-341e5b91") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR mips shader replaced."); + } + } + else if (hash == "b21dd223-98ab56ae-918264e6-eb6e8ee4") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR resolve shader replaced."); + } + } + else if (hash == "8703f55f-6c22fba7-1ef876f1-4767379e") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR resolve no jitter shader replaced."); + } + } + else if (hash == "a9372f22-05154267-13f583e1-b08ffd75") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_dither.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR resolve no dither shader replaced."); + } + } + else if (hash == "77e20ce4-0538a5f1-908ba0a3-55821b0f") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter_no_dither.shdr")) + { + info->Replacement.Type = ShaderSourceType.Binary; + Log.Info("SSLR resolve no jitter or dither shader replaced."); + } + } + } } #endif } -- cgit v1.2.3-101-g0448