From 298e392ccb1967036b60abc151ec3093304ab00e Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Thu, 30 Jul 2026 10:51:51 -0400 Subject: Improve LUT feature, add HDR params Signed-off-by: Andrew Opalach --- Plugin.cs | 123 +++++++++++++------------------------------------------------- 1 file changed, 26 insertions(+), 97 deletions(-) (limited to 'Plugin.cs') diff --git a/Plugin.cs b/Plugin.cs index 820b79f..6547a0a 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -6,7 +6,6 @@ using System.Numerics; using System.Globalization; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; #if ENABLE_ASSERTS using System.Diagnostics; #endif @@ -24,11 +23,10 @@ using SharpPluginLoader.Core.Resources; #endif // @TODO: -// - Cleanup SSR patches. // - Configurable Broad Area Shadow Resolution. // - Hook sMhScene constructor to set hqMode. // - Optimized update logic. -// - Only update non-override values when ui is shown. +// - Only update non-override values when UI is shown. // - Map sky params. // - Lights refactor. // - Descriptions. @@ -50,6 +48,7 @@ using SharpPluginLoader.Core.Resources; // - The Rotten Vale jump out of Southeast Camp. Wall on the opposite side slightly to the left. // - Special Arena. // - Elder's Recess Lavasioth area. +// - Hoarfrost pit area with wedge beetles. // // Known issues to think about: // - Hair clipping while looking down. @@ -828,8 +827,7 @@ namespace WorldTuningTool if (NoOverride) { - // Dependent on overall ImGui style. - ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(40.0f, 0.0f)); + ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(ImGui.GetFrameHeight() + ImGui.GetStyle().ItemSpacing.X, 0.0f)); } else if (!assumeOverride) { @@ -1592,16 +1590,10 @@ namespace WorldTuningTool private Hook? createLightingObject; private Hook? destroyLightingObject; private nint lightingObject = 0x0; - private delegate void SetLightingParameters(nint lightingObjectInternal); - private Hook? setLightingParams; - private NativeAction setLightingParamsFunc; private delegate void UpdateLightingParameters(nint stackOffset, nint lightingObjectInternal); private Hook? updateLightingParams; private Hook? updateLutBlend; - private static WorldLUT lut = new WorldLUT(); - private static string selectedLut = ""; - private static bool lutSelectionStarted = false; - private static bool selectedLutInvalid = false; + private static WorldLUTs luts = new WorldLUTs(); private static Parameter[] lightingParameters = { newParameter("Light Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 6, 1)), newParameter("Light Compute Luminance", 0x170, ParameterType.BOOL), @@ -1624,7 +1616,12 @@ namespace WorldTuningTool }; private static Parameter[] brightnessParameters = { newParameter("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)), - newParameter("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)) + newParameter("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)), + newParameterView("Hdr Output", 0x21A, ParameterType.BOOL), + newParameter("Hdr Output White Level", 0x21C, ParameterType.FLOAT, pStep(0.05f)), + newParameter("Hdr Output Gamut Mapping Ratio", 0x220, ParameterType.FLOAT, pStep(0.001f)), + newParameter("Hdr Output Gamma", 0x224, ParameterType.FLOAT, pStep(0.001f)), + newParameter("Hdr Is Gui Hdr Gamma", 0x228, ParameterType.BOOL) }; private static MtObject? sLightProbes = null; private static Parameter[] lightProbesParameters = { @@ -1735,7 +1732,7 @@ namespace WorldTuningTool private static Parameter[] allParameters = new Parameter[]{ hqMode } .Concat(lodParameters) .Concat(snowParameters) - .Concat(new Parameter[] { shadowResParameter }) + .Append(shadowResParameter) .Concat(shadowParameters2) .Concat(shadowCascadeParameters) .Concat(broadAreaShadowParameters) @@ -1745,6 +1742,7 @@ namespace WorldTuningTool .Concat(sslrParameters) .Concat(passthroughParameters) .Concat(lightingParameters) + .Concat(brightnessParameters) .Concat(bloomParameters) .Concat(dofParameters) .Concat(motionBlurParameters) @@ -2143,7 +2141,7 @@ namespace WorldTuningTool onAreaChange = Hook.Create(0x141AC27D0, OnAreaChangeHook); // nint - // Needed for at least "Broad Area Shadow Dir". Otherwise it will flicker during an update on center change. + // Needed for at least "Broad Area Shadow Dir". Otherwise it will flicker on center change. evalSceneParams = Hook.Create(0x1423C3790, EvalSceneParamsHook); // nint, nint, int, nint // Light Dir XZY is updated seperately at 0x1420397F0, we assume this function always happens later, though. @@ -2156,8 +2154,6 @@ namespace WorldTuningTool createLightingObject = Hook.Create(0x1424CDE20, CreateLightingObjectHook); destroyLightingObject = Hook.Create(0x1424CE380, DestroyLightingObjectHook); // nint, int - setLightingParams = Hook.Create(0x1424CF1C0, SetLightingParametersHook); // nint - setLightingParamsFunc = new NativeAction(0x1424CF1C0); updateLutBlend = Hook.Create(0x1416D8DF0, UpdateLutBlendHook); // nint, nint createBloomObject = Hook.Create(0x1424CB3C0, CreateBloomObjectHook); @@ -2326,7 +2322,7 @@ namespace WorldTuningTool ssrShr3 = new Patch(new IntPtr(0x14269E07A), [0x90, 0x90]); ssrShr4 = new Patch(new IntPtr(0x14269E080), [0x90, 0x90]); // Approximate depth mip resolution. - ssrShr5 = new Patch(new IntPtr(0x14269DED3) + 0x2, [0x3]); + ssrShr5 = new Patch(new IntPtr(0x14269DED3) + 0x2, [0x3]); // 4 -> 3 ssrShr6 = new Patch(new IntPtr(0x14269DEDA) + 0x3, [0x3]); // Depth mips pass 1 dispatch dimensions. ssrSars1 = new Patch(new IntPtr(0x142282FD8) + 0x3, [0x3]); // 4 -> 3 @@ -2913,15 +2909,6 @@ namespace WorldTuningTool return destroyLightingObject!.Original(lightingObjectInternal, unknownInt); } - private void SetLightingParametersHook(nint lightingObjectInternal) - { - setLightingParams!.Original(lightingObjectInternal); - if (lightingObject == lightingObjectInternal) - { - selectedLut = ""; - } - } - private void UpdateLutBlendHook(nint stackOffset, nint lightingObjectInternal) { updateLutBlend!.Original(stackOffset, lightingObjectInternal); @@ -3862,91 +3849,33 @@ namespace WorldTuningTool } ImGui.PopID(); - /* - ImGui.PushID("Snow"); - if (ImGui.CollapsingHeader("Snow")) - { - ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); - foreach (Parameter param in snowParameters) - { - param.Draw(width); - } - } - ImGui.PopID(); - */ - ImGui.PushID("Lighting"); if (ImGui.CollapsingHeader("Lighting")) { + ImGui.Text($"Address: 0x{lightingObject:X}"); if (lightingObject != 0x0) { - ImGui.Text($"Address: 0x{lightingObject:X}"); - if (ImGui.CollapsingHeader("LUT")) + if (ImGui.CollapsingHeader("LUTs")) { - nint d3dResource = WorldLUT.ProbeD3DResource(lightingObject); - if (d3dResource != 0x0) - { - if (ImGui.Button("Reset")) - { - // Attempt to force check for reloading LUT to pass. - MemoryUtil.GetRef(lightingObject + 0x1D4) = MemoryUtil.GetRef(lightingObject + 0x1D0) + 1.0f; - } - ImGui.SameLine(); - ImGui.SetNextItemWidth(width * 0.625f); - bool prevLutWasInvalid = selectedLutInvalid; - if (prevLutWasInvalid) - { - ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); - } - if (ImGui.BeginCombo("##LUT Files", selectedLut, ImGuiComboFlags.HeightLarge)) - { - if (prevLutWasInvalid) - { - ImGui.PopStyleColor(); - } - if (!lutSelectionStarted) - { - lut.ReloadLUTs(); - lutSelectionStarted = true; - } - foreach (string lutPath in lut.GetLUTs()) - { - string lutFile = Path.GetFileName(lutPath); - bool isSelected = selectedLut == lutFile; - if (ImGui.Selectable(lutFile, isSelected)) - { - selectedLutInvalid = !lut.OverwriteFromFile(d3dResource, lutPath); - selectedLut = lutFile; - } - } - ImGui.EndCombo(); - } - else - { - if (prevLutWasInvalid) - { - ImGui.PopStyleColor(); - } - lutSelectionStarted = false; - } - } + nint lutBlendTexture = MemoryUtil.Read(lightingObject + 0x1C0); + ImGui.Text($"LUT Blend: 0x{lutBlendTexture:X}"); nint lutMap0 = MemoryUtil.Read(lightingObject + 0x1A8); if (lutMap0 != 0x0) { - ImGui.Text($"LUT Map 0: {Marshal.PtrToStringAnsi(lutMap0 + 0xC)!}"); + luts.DrawLUT(lutMap0, lightingObject, 0, width); } nint lutMap1 = MemoryUtil.Read(lightingObject + 0x1B0); if (lutMap1 != 0x0) { - ImGui.Text($"LUT Map 1: {Marshal.PtrToStringAnsi(lutMap1 + 0xC)!}"); + luts.DrawLUT(lutMap1, lightingObject, 1, width); } } foreach (Parameter param in lightingParameters) { param.Draw(width); } - ImGui.Separator(); } + ImGui.Separator(); ImGui.Text($"Address: 0x{sMhRender!.Instance:X}"); foreach (Parameter param in brightnessParameters) { @@ -3964,9 +3893,9 @@ namespace WorldTuningTool ImGui.PushID("Bloom"); if (ImGui.CollapsingHeader("Bloom")) { + ImGui.Text($"Address: 0x{bloomObject:X}"); if (bloomObject != 0x0) { - ImGui.Text($"Address: 0x{bloomObject:X}"); foreach (Parameter param in bloomParameters) { param.Draw(width); @@ -3978,9 +3907,9 @@ namespace WorldTuningTool ImGui.PushID("DepthOfField"); if (ImGui.CollapsingHeader("Depth of Field")) { + ImGui.Text($"Address: 0x{dofObject:X}"); if (dofObject != 0x0) { - ImGui.Text($"Address: 0x{dofObject:X}"); foreach (Parameter param in dofParameters) { param.Draw(width); @@ -3992,9 +3921,9 @@ namespace WorldTuningTool ImGui.PushID("MotionBlur"); if (ImGui.CollapsingHeader("Motion Blur")) { + ImGui.Text($"Address: 0x{motionBlurObject:X}"); if (motionBlurObject != 0x0) { - ImGui.Text($"Address: 0x{motionBlurObject:X}"); foreach (Parameter param in motionBlurParameters) { param.Draw(width); @@ -4006,9 +3935,9 @@ namespace WorldTuningTool ImGui.PushID("FXAA"); if (ImGui.CollapsingHeader("FXAA")) { + ImGui.Text($"Address: 0x{fxaaObject:X}"); if (fxaaObject != 0x0) { - ImGui.Text($"Address: 0x{fxaaObject:X}"); foreach (Parameter param in fxaaParameters) { param.Draw(width); @@ -4020,9 +3949,9 @@ namespace WorldTuningTool ImGui.PushID("TAA"); if (ImGui.CollapsingHeader("TAA")) { + ImGui.Text($"Address: 0x{taaObject:X}"); if (taaObject != 0x0) { - ImGui.Text($"Address: 0x{taaObject:X}"); foreach (Parameter param in taaParameters) { param.Draw(width); -- cgit v1.2.3-101-g0448