Skip to content

Shader replacement#60

Draft
Pizzabelly wants to merge 3 commits into
Fexty12573:masterfrom
Pizzabelly:shader-replacement
Draft

Shader replacement#60
Pizzabelly wants to merge 3 commits into
Fexty12573:masterfrom
Pizzabelly:shader-replacement

Conversation

@Pizzabelly
Copy link
Copy Markdown
Contributor

@Pizzabelly Pizzabelly commented Mar 17, 2026

The biggest functional change to D3DModule is that it now initializes at an earlier part of the game startup. This was necessary to catch the point at which the game initially loads shaders. I tested it a lot but I'm not sure if I missed any quirks related to loading the GUI so early.

The AutoSteamworks fix is currently commented out because I wanted to see if we could work out a better solution.

Also, the shader replacement/OnCreateShader() API is up for discussion, this was just the first working version.

Example of usage: https://codeberg.org/pizzabelly/WorldTuningTool/src/commit/47ba7138ae1fc3f090905a0a3feee3b5ae36cbf2/Plugin.cs#L2344

@Pizzabelly
Copy link
Copy Markdown
Contributor Author

I should also note it seems shader loading is multi-threaded. Just based on the console output getting clobbered if you were to log each shader hash, for instance. That can be avoided by locking in the create shader hooks. I'm not sure if it's a problem or not though, particularly when calling out to the c# code.

@Narugakuruga
Copy link
Copy Markdown

Hi pizzabelly. Your new feature of SPL seems very useful! Is it possible that you could provide a preview build of shader replacement and the plugin itself?
Because I couldn't figure out how to build and test it. Because nuget package doesn't have the feature yet.

@Pizzabelly Pizzabelly force-pushed the shader-replacement branch from d8ebc6e to a9e09cf Compare May 23, 2026 01:33
@Pizzabelly Pizzabelly force-pushed the shader-replacement branch from a9e09cf to 507bbc1 Compare May 23, 2026 02:08
@Fexty12573
Copy link
Copy Markdown
Owner

@Narugakuruga Check the actions artifacts in this PR, there should be builds available there now.

@Pizzabelly
Copy link
Copy Markdown
Contributor Author

I'm trying to understand the purpose of m_is_inside_present, would this satisfy it? Or is it related to the call to the original function?

HRESULT D3DModule::d3d12_present_hook(IDXGISwapChain* swap_chain, UINT sync_interval, UINT flags) {
    const auto self = NativePluginFramework::get_module<D3DModule>();
    const auto prm = NativePluginFramework::get_module<PrimitiveRenderingModule>();
    const auto& config = preloader::LoaderConfig::get();

    if (swap_chain == self->m_swap_chain && !self->m_is_inside_present) {
        self->m_is_inside_present = true;

        if (!self->m_is_initialized) {
            self->d3d12_initialize_imgui(swap_chain);

            if (!self->m_texture_manager) {
                self->m_texture_manager = std::make_unique<TextureManager>(
                    self->m_d3d12_device,
                    self->m_d3d12_command_queue,
                    self->m_d3d12_srv_heap
                );
            }

            if (config.get_primitive_rendering_enabled()) {
                prm->late_init(self.get(), swap_chain);
            }
        }

        if (self->m_d3d12_command_queue) {
            self->d3d12_present_hook_core(swap_chain, prm);
        }

        self->m_is_inside_present = false;
    }

    return self->m_d3d_present_hook.call<HRESULT>(swap_chain, sync_interval, flags);
}

Also, with these changes d3d11 and d3d12 are more symmetrical so I could easily add a check for if swap_chain == self->m_swap_chain in d3d11_present_hook() as well, if that would make sense.

@Narugakuruga
Copy link
Copy Markdown

I test the plugin and it works as expected.
I found two bugs.
First Patches is not saved into config. This is relatively easy to fix. I noticed that 3x shadow res need to reset shadow quality.
Second bug is that some parameters have duplicated names. Bloom enable and DOF enable are both "Enable"
"Color": Bloom color and shadow color.
"Primary Shadow Sample Num" : Scene and Shadow.

@Narugakuruga
Copy link
Copy Markdown

worldtuningtool.zip
Here's the fixed version I renamed these duplicated parameters.
But here's another bug: bloom override enable = false will make the game extremely bright on the menu screen.
I'm still investigating it.

@Pizzabelly
Copy link
Copy Markdown
Contributor Author

@Narugakuruga I'm glad you got it building. You're using the commit I linked here which is a pretty old version of the code though. Check out the latest master, I've made lots of fixes https://codeberg.org/pizzabelly/WorldTuningTool. I'm pretty sure the latest commit should build on this branch.

@Narugakuruga
Copy link
Copy Markdown

I found another bug horal frost reach shadow disappears. Your previous plugin MHWNewCamera has a solution for it.
I think the plugin is all good except the horalfrost reach shadow.
The Bloom Brightness issue doesn't look like a bug in the plugin side. It's the game design (^_^)

@Pizzabelly
Copy link
Copy Markdown
Contributor Author

Pizzabelly commented May 23, 2026

WorldTuningTool.json This is my working config. It should have parity with everything that was previously in the "Graphical Tweaks" section of my MHWNewCamera mod.

If you mean shadows are completely gone in hoarfrost reach, my old mod had an option called "Higher Shadow Detail in Hoarfrost Reach/Seliana Gathering Hub" that would adjust the "Shadow Cascade Mode" value from 1 to 2. The problem was that it required an even bigger shadow map texture (16K vs 8K) which was super wasteful in other areas. Using that option with the version of "3x Shadow Resolution" in WorldTuningTool will result in shadows being disabled in Hoarfrost Reach.

You could restore the old behavior with this patch and an override in Hoarfrost Reach for "Shadow Cascade Mode" set to 2.

diff --git a/Plugin.cs b/Plugin.cs
index 9f9ba3a..e8e7afd 100755
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1420,7 +1420,7 @@ namespace WorldTuningTool
         private Patch shadowRes1_3;
         private Patch shadowRes2;
         private Patch shadowRes3;
-        //private Patch shadowRes4_Limit;
+        private Patch shadowRes4_Limit;
 
         private void tripleShadowResEnable()
         {
@@ -1430,6 +1430,7 @@ namespace WorldTuningTool
             shadowRes1_3.Enable();
             shadowRes2.Enable();
             shadowRes3.Enable();
+            shadowRes4_Limit.Enable();
         }
 
         private void tripleShadowResDisable()
@@ -1440,6 +1441,7 @@ namespace WorldTuningTool
             shadowRes1_3.Disable();
             shadowRes2.Disable();
             shadowRes3.Disable();
+            shadowRes4_Limit.Disable();
         }
 
         private bool fullResVolumeBlur = false;
@@ -1731,10 +1733,10 @@ namespace WorldTuningTool
             // and any value higher would crash. Keeping this at the default value (unpatched) *should* work unless the
             // game does something unpredictable. At 3x Shadow Resolution + High, the shadow map will be 8448x8448.
             /* Results in 16320x16320, not sure why not 16128.
+            */
             shadowRes4_Limit = new Patch(addr + 0x29, [ // N/64 = 255, fractional values closer to 256 not tested.
                 0xB8, 0x40, 0x15, 0x00, 0x00, 0xEB, 0x21 // This case is used for Low, Medium and High in-game.
             ]);
-            */
 
             // The volume blur filter is created at a different place in the code and happens at a different
             // time (area change/createLightingObject() vs change of Volume Quality setting). It's also rendered

Also, if you have more issues to report you should make an issue on the codeberg repo or message me on the Monster Hunter Modding discord, I'm pizza___________________________.

@Fexty12573
Copy link
Copy Markdown
Owner

I'm trying to understand the purpose of m_is_inside_present
I think I had issues at some point with my present hook being called multiple times (recursively) due to overlays and this was my fix for it.

Also yes, the swap chain check should be in the D3D11 branch as well, I forgot about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants