From aeb22677767008e995dd2f8390433b918a2cf301 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Fri, 9 Oct 2026 13:03:46 -0400 Subject: Add patches, exposure parameters and cleanup Signed-off-by: Andrew Opalach --- Plugin.cs | 1181 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 742 insertions(+), 439 deletions(-) (limited to 'Plugin.cs') diff --git a/Plugin.cs b/Plugin.cs index 20d9786..61553d9 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -26,9 +26,8 @@ using SharpPluginLoader.Core.Resources; // @TODO: // - https://dev.epicgames.com/community/learning/tutorials/34xz/unreal-engine-ocio-3d-luts-applying-3d-luts-when-using-ocio -// - Add built-in LUT list. -// - Configurable Broad Area Shadow Resolution. // - Hook sMhScene constructor to set hqMode. +// - Configurable Broad Area Shadow Resolution. // - Optimized update logic. // - Only update non-override values when UI is shown. // - Descriptions. @@ -36,7 +35,6 @@ using SharpPluginLoader.Core.Resources; // - Lights iterop. // - SPL Patches: // - No crash on empty config. -// - Style change // - Hotload nukes config? // // Areas that need Shadow Distance retuning: @@ -79,8 +77,6 @@ namespace WorldTuningTool #endif } - public static nint lton(long l) { unchecked { return (nint)l; } } - private static byte ByteFlag(bool f) { return f ? (byte)0x1 : (byte)0x0; } private static int BitIndex(int mask) @@ -119,7 +115,7 @@ namespace WorldTuningTool public static Vector2 StringToVector2(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); - string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray(); + string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 2) throw new FormatException(); return new Vector2(StringToSingle(sp[0]), StringToSingle(sp[1])); } @@ -127,7 +123,7 @@ namespace WorldTuningTool public static Vector3 StringToVector3(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); - string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray(); + string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 3) throw new FormatException(); return new Vector3(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2])); } @@ -135,7 +131,7 @@ namespace WorldTuningTool public static Vector4 StringToVector4(string s, char delim = ',') { if (String.IsNullOrEmpty(s)) throw new FormatException(); - string[] sp = s.Split(delim).Select(v => v.Trim()).ToArray(); + string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 4) throw new FormatException(); return new Vector4(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2]), StringToSingle(sp[3])); } @@ -174,6 +170,12 @@ namespace WorldTuningTool SHADOW_RESOLUTION } + private const float defaultParamWidth = 0.21f; + private const float fadeAlphaFactor = 0.7f; + private const float disableAlphaFactor = 0.6f; + + private static bool ignoreMinMax = false; + private static IPlugin? Instance = null; private static Config getConfig() @@ -181,6 +183,11 @@ namespace WorldTuningTool return ConfigManager.GetConfig(Instance!); } + private static bool editMode = false; + private static int configState = 0; + private const int SelectedNotSaved = 1; + private const int SetNotSaved = (1 << 1); + private static void rebuildConfig(Config config, List overrides) { List selectedGlobals = config.Globals[selectedGlobal]; @@ -191,10 +198,6 @@ namespace WorldTuningTool } } - private static int configState = 0; - private const int SelectedNotSaved = 1; - private const int SetNotSaved = (1 << 1); - private static void saveConfig(Config config) { List tmpOverrides = config.Overrides[globalStage]; @@ -204,23 +207,15 @@ namespace WorldTuningTool configState = 0; } - private const float defaultParamWidth = 0.21f; - private const float fadeAlphaFactor = 0.7f; - private const float disableAlphaFactor = 0.6f; - - private static bool ignoreMinMax = false; - - private static bool editMode = false; - private const StageExt globalStage = StageExt.Global; private static StageExt currentStage => (StageExt)Area.CurrentStage; private static List? maybeGetStageOverrides(Config config) { - if (!config.Overrides.ContainsKey(currentStage)) + if (currentStage != StageExt.Global && config.Overrides.TryGetValue(currentStage, out List? stageOverrides)) { - return null; + return stageOverrides; } - return (currentStage != StageExt.Global) ? config.Overrides[currentStage] : null; + return null; } private static StageExt selectedStage = globalStage; @@ -925,7 +920,7 @@ namespace WorldTuningTool if (Type == ParameterType.COLOR_FACTOR) { Vector3 v3Color = v3; - // Only scale the color vector if max is unbound. Otherwise, assume that intensity and color are combined. + // Only scale the color vector if max is unbound. Otherwise, assume that intensity and color are seperate. if (maxf == Single.MaxValue) { float v3Max = MathF.Max(Math.Abs(v3.X), MathF.Max(Math.Abs(v3.Y), Math.Abs(v3.Z))); @@ -1265,6 +1260,11 @@ namespace WorldTuningTool return new Parameter(name, offset, 0, type, m.min, m.max, m.step, 0); } + public static Parameter P(string name, long offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged + { + return new Parameter(name, (nint)offset, 0, type, m.min, m.max, m.step, 0); + } + public static Parameter V(string name, nint offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged { return new Parameter(name, offset, 0, type, m.min, m.max, m.step, ParameterFlags.ViewOnly); @@ -1277,6 +1277,11 @@ namespace WorldTuningTool private static Parameter? getParameterByName(string name) { + if (OldParameterNames.TryGetValue(name, out string? newName)) + { + Log.Warn($"Paramter '{name}' renamed to {newName}."); + name = newName; + } foreach (Parameter param in allParameters) { if (param.Name == name) @@ -1579,7 +1584,7 @@ namespace WorldTuningTool } hasStatus = true; } - else if (valueDiffers) + else if (valueDiffers || superseded) { ImGui.SameLine(); string byLine = ""; @@ -1616,8 +1621,8 @@ namespace WorldTuningTool private delegate void UpdateSSLRParams(nint stackOffset); private Hook? updateSSLRParams; - private delegate void UpdateLightingParams(nint stackOffset, nint lightingObjectInternal); - private Hook? updateLightingParams; + private delegate void UpdateToneMapParams(nint stackOffset, nint toneMapObjectInternal); + private Hook? updateToneMapParams; private static bool InTransition = false; private static List DirtyParams = new List(); @@ -1645,9 +1650,9 @@ namespace WorldTuningTool private static MtObject? sLightLinker = null; private static bool disableLightsFeature = false; - private static Lights lights = new Lights(); private static Parameter hqMode = P("HQ Mode", 0xE9A3, ParameterType.BOOL); + private static Patch defaultHqMode; private static bool setWeatherMode = false; private static int requestWeatherMode = 1; @@ -1661,16 +1666,25 @@ namespace WorldTuningTool P("LOD Bias 1", 0x21C, ParameterType.FLOAT, pMin(0.0f)), P("LOD Bias 2", 0x220, ParameterType.FLOAT, pMin(0.0f)), P("LOD Caster Bias", 0x1E4, ParameterType.FLOAT, pMin(0.0f)), - // If platform is PS4/Xbox/PC it appears [2] is PC. - P("LOD Length Platform Bias[2]", 0x22C + (4 * 2), ParameterType.FLOAT, pMin(0.0f)), - P("LOD Pixel Size Platform Bias[2]", 0x244 + (4 * 2), ParameterType.FLOAT, pMin(0.0f)), P("LOD Limit", 0xE898, ParameterType.INT, pStep(1)), P("LOD Passthrough Culling Rate", 0x1F0, ParameterType.FLOAT, pMin(0.0f)), P("LOD Far Culling Fade Length Max", 0x20C, ParameterType.FLOAT, pMin(0.0f)), P("LOD Far Culling Fade Pixel Max", 0x210, ParameterType.FLOAT, pMin(0.0f)), P("Speed Tree LOD Billboard Fade Range", 0x214, ParameterType.FLOAT, pMin(0.0f)), P("LOD Culling Length Bias", 0x224, ParameterType.FLOAT, pMin(0.0f)), - P("LOD Culling Pixel Bias", 0x228, ParameterType.FLOAT, pMin(0.0f)) + P("LOD Culling Pixel Bias", 0x228, ParameterType.FLOAT, pMin(0.0f)), + // Length/Pixel Size bias only apply when Bias 1/2 are 0. + // MonsterHunterWorld.exe+1B19AA1 - comiss xmm0,xmm1 + P("LOD Length Bias", 0x1F4, ParameterType.FLOAT, pMin(0.0f)), + P("LOD Length Bias (HQ)", 0x1FC, ParameterType.FLOAT, pMin(0.0f)), + // MonsterHunterWorld.exe+1B19B95 - comiss xmm1,xmm0 + P("LOD Pixel Size Bias", 0x200, ParameterType.FLOAT, pMin(0.0f)), + P("LOD Pixel Size Bias (HQ)", 0x208, ParameterType.FLOAT, pMin(0.0f)), + // Factor applied to the result of LOD Bias 1/2 or Length/Pixel Size Bias. + // MonsterHunterWorld.exe+222F7C4 - mulss xmm4,xmm6 + // If platform is PS4/Xbox/PC it appears [2] is PC. + P("LOD Length Platform Bias[2]", 0x22C + (4 * 2), ParameterType.FLOAT, pMin(0.0f)), + P("LOD Pixel Size Platform Bias[2]", 0x244 + (4 * 2), ParameterType.FLOAT, pMin(0.0f)) }; private static Parameter[] snowParameters = { @@ -1687,6 +1701,7 @@ namespace WorldTuningTool P("Passthrough Correct", 0xE950, ParameterType.FLOAT) }; + private static Parameter shadowResParameter = P("Shadow Resolution Multiplier", 0, ParameterType.SHADOW_RESOLUTION, pStep(1)); private static Parameter[] shadowCascadeParameters = { P("Primary Shadow HQ", 0xE5C0, ParameterType.BOOL), P("Primary Shadow HQ (HQ)", 0xE5C2, ParameterType.BOOL), @@ -1704,11 +1719,87 @@ namespace WorldTuningTool P("Broad Area Shadow Precision", 0x5518, ParameterType.INT, pMinMaxStep(0, 2, 1)) }; + private delegate void UpdatePrimaryLightParams(nint primaryLightParams, nint stackOffset); + private delegate void StaticPrimaryLightParams(nint primaryLightParamsStatic, nint primaryLightObjectInternal); + private Hook? updatePrimaryLightParams; + private Hook? staticPrimaryLightParams; + // "Min Roughness" is +0xFC in params but never read. + private static Parameter[] primaryLightParameters = { + M("Primary Light Group", 0x14, ParameterType.BITS, 0x7), + P("Primary Light Priority", 0x1A, ParameterType.BYTE), + P("Primary Light Direction", 0x110, ParameterType.VECTOR3, pStep(0.00025f)), + P("Primary Light Color", 0xE0, ParameterType.COLOR_FACTOR, pMaxStep(1.0f, 0.001f)), + P("Primary Light Intensity", 0xF4, ParameterType.FLOAT, pStep(0.005f)), + P("Primary Light Is Primary", 0x1D, ParameterType.BOOL), + P("Primary Light Projection Scale", 0x134, ParameterType.VECTOR2), + P("Primary Light Projection Offset Speed", 0x144, ParameterType.VECTOR2), + P("Primary Light Projection Up", 0x160, ParameterType.VECTOR3), + P("Primary Light Do Volumetric", 0x1F, ParameterType.BOOL), + P("Primary Shadow Cast", 0x23, ParameterType.BOOL), + P("Primary Shadow Map Size", 0x30, ParameterType.ALIGNED_INT, pMinStep(0, 128)), // 0 = 64x64 no multiplier @TODO: Verify in the code. + P("Primary Shadow Near Clip Distance", 0x28, ParameterType.FLOAT), + P("Primary Shadow Is Fixed Fov Mode", 0x1F9, ParameterType.BOOL), + P("Primary Shadow Fov", 0x1F4, ParameterType.FLOAT, pStep(0.0001f)), + P("Primary Shadow Is Discretization Fov Mode", 0x205, ParameterType.BOOL), + P("Primary Shadow Discretization Angle", 0x200, ParameterType.FLOAT, pStep(0.0001f)), + P("Primary Shadow Cascade Mode", 0x174, ParameterType.INT, pMinMaxStep(0, 3, 1)), + P("Primary Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT), + P("Primary Shadow Cascade Distance", 0x6C, ParameterType.FLOAT, pStep(5.0f)), + P("Primary Shadow Cascade Backforward Distance", 0x7C, ParameterType.FLOAT, pStep(5.0f)), + P("Primary Shadow Cascade Distribution", 0x74, ParameterType.FLOAT, pStep(0.001f)), + P("Primary Shadow Cascade Manual Split", 0x4D, ParameterType.BOOL), + P("Primary Shadow Cascade Manual Split Distance[0]", 0x54, ParameterType.FLOAT), + P("Primary Shadow Cascade Manual Split Distance[1]", 0x5C, ParameterType.FLOAT), + P("Primary Shadow Cascade Manual Split Distance[2]", 0x64, ParameterType.FLOAT), + P("Primary Shadow Sloped Depth Bias", 0x40, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Depth Bias", 0x38, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Max Depth Bias", 0x48, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Individual Shadow Bias", 0x81, ParameterType.BOOL), + P("Primary Shadow Cascade Depth Bias[0]", 0x88, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Sloped Depth Bias[0]", 0xA0, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Max Depth Bias[0]", 0xB8, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Depth Bias[1]", 0x90, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Sloped Depth Bias[1]", 0xA8, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Max Depth Bias[1]", 0xC0, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Depth Bias[2]", 0x98, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Sloped Depth Bias[2]", 0xB0, ParameterType.FLOAT, pStep(0.00001f)), + P("Primary Shadow Cascade Max Depth Bias[2]", 0xC8, ParameterType.FLOAT, pStep(0.00001f)), + }; + private static Parameter[] primaryShadowParameters = { + P("Primary Shadow Sample Num", 0x1DC, ParameterType.INT, pStep(1)), + P("Primary Shadow Radius", 0x1EC, ParameterType.FLOAT, pStep(0.0001f)) + }; + private static Parameter[] primaryBroadAreaParameters = { + P("Broad Area Shadow Depth Bias", 0x1C4, ParameterType.FLOAT, pStep(0.00001f)), + P("Broad Area Shadow Sloped Depth Bias", 0x1CC, ParameterType.FLOAT, pStep(0.00001f)), + P("Broad Area Shadow Max Depth Bias", 0x1D4, ParameterType.FLOAT, pStep(0.00001f)), + }; + + private static MtObject? sLightProbes = null; + private static Parameter[] sLightProbesParameters = { + P("Light Probes Probe Color", 0x38, ParameterType.COLOR), + P("Light Probes Probe Intensity", 0x3C, ParameterType.FLOAT), + P("Light Probes Top Color", 0x44, ParameterType.COLOR), + P("Light Probes Top Intensity", 0x48, ParameterType.FLOAT), + P("Light Probes Bottom Color", 0x4C, ParameterType.COLOR), + P("Light Probes Bottom Intensity", 0x50, ParameterType.FLOAT), + P("Light Probes Direction", 0x60, ParameterType.VECTOR3), + P("Light Probes Shadow Top Color", 0x70, ParameterType.COLOR), + P("Light Probes Shadow Top Intensity", 0x74, ParameterType.FLOAT), + P("Light Probes Shadow Bottom Color", 0x78, ParameterType.COLOR), + P("Light Probes Shadow Bottom Intensity", 0x7C, ParameterType.FLOAT), + P("Light Probes Shadow Direction", 0x80, ParameterType.VECTOR3), + P("Light Probes Daytime State", 0x9C, ParameterType.INT, pMinMaxStep(0, 6, 1)), + P("Light Probes Daytime Interpolation", 0xA0, ParameterType.FLOAT), + P("Light Probes Max Iter", 0xA4, ParameterType.INT), + P("Light Probes Debug Mode", 0x98, ParameterType.INT, pStep(1)) + }; + private static Parameter[] contactShadowParameters = { P("Fake Light Intensity", 0xEC40, ParameterType.FLOAT), // MonsterHunterWorld.exe+1B18711 - mov [rbx+0000EC44],3F800000 (Other unknown reference). - P("Fake Light Intensity (Gameplay)", lton(0x141B1A19F) + 0x6, ParameterType.PATCH_FLOAT), - P("Fake Light Blend", lton(0x141CDE0CE) + 0x6, ParameterType.PATCH_FLOAT), + P("Fake Light Intensity (Gameplay)", 0x141B1A19F + 0x6, ParameterType.PATCH_FLOAT), + P("Fake Light Blend", 0x141CDE0CE + 0x6, ParameterType.PATCH_FLOAT), P("Force Disable Contact Shadows", 0xB4ED, ParameterType.BOOL), P("Facial Contact Shadows Enabled", 0xB4EE, ParameterType.BOOL), P("Facial Contact Shadows Enable Noise", 0xB501, ParameterType.BOOL), @@ -1745,6 +1836,57 @@ namespace WorldTuningTool P("SSAO Edge Atten Rate", 0xB4DC, ParameterType.FLOAT, pStep(0.001f)) }; + private static MtObject? sVolumeRenderer = null; + private static Parameter[] sVolumeRendererParameters = { + P("Volume Rendering Enabled", 0x38, ParameterType.BOOL) + }; + + private delegate nint CreateToneMapObject(); + private delegate nint DestroyToneMapObject(nint toneMapObjectInternal, int unknownInt); + private Hook? createToneMapObject; + private Hook? destroyToneMapObject; + private nint toneMapObject = 0x0; + private static Parameter[] toneMapParameters = { + P("Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 9, 1)), + P("Tone Map Compute Luminance", 0x170, ParameterType.BOOL), + P("Tone Map Luminance Version", 0x168, ParameterType.BOOL), + P("Tone Map Shoulder Strength", 0x174, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map Linear Strength", 0x178, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map Linear Angle", 0x17C, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map Toe Strength", 0x180, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map Toe Num", 0x184, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map Toe Denum", 0x188, ParameterType.FLOAT, pStep(0.001f)), + P("Tone Map White Point", 0x18C, ParameterType.FLOAT, pStep(0.01f)), + P("Color Grading LUT Blend", 0x1C8, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)), + P("Color Grading Vfx LUT Blend", 0x1D0, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)), + P("Color Grading Enable", 0x1D8, ParameterType.BOOL), + P("Color Grading Is Linear To PQ", 0x1A1, ParameterType.BOOL), + P("Color Grading Is PQ To Linear", 0x1A0, ParameterType.BOOL), + P("Volume Dispersion", 0x19C, ParameterType.FLOAT), + P("Volume Edge Sharpness", 0x198, ParameterType.FLOAT, pStep(0.00001f)), + P("Volume Downsample", 0x210, ParameterType.BOOL) + }; + private static Parameter[] exposureParameters = { + P("Exposure Bt Adaption Limit", 0x460, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure Bt Sensitivity", 0x458, ParameterType.FLOAT, pMaxStep(1.0f, 0.001f)), + P("Exposure Dk Adaption Limit", 0x464, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure Dk Sensitivity", 0x45C, ParameterType.FLOAT, pMaxStep(1.0f, 0.001f)), + P("Exposure Value", 0x474, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure Min White Point", 0x470, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure Max White Point", 0x46C, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure Mid Gray", 0x454, ParameterType.FLOAT, pStep(0.001f)), + P("Exposure White Range", 0x468, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.001f)) + }; + private static Parameter[] brightnessParameters = { + P("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)), + P("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)), + V("Hdr Output", 0x21A, ParameterType.BOOL), + P("Hdr Output White Level", 0x21C, ParameterType.FLOAT, pStep(0.05f)), + P("Hdr Output Gamut Mapping Ratio", 0x220, ParameterType.FLOAT, pStep(0.001f)), + P("Hdr Output Gamma", 0x224, ParameterType.FLOAT, pStep(0.001f)), + P("Hdr Is Gui Hdr Gamma", 0x228, ParameterType.BOOL) + }; + private static Parameter[] sslrParameters = { P("SSLR Loop Count", 0xE628, ParameterType.INT, pStep(1)), P("SSLR Loop Count Factor for CBR", 0xE62C, ParameterType.FLOAT), @@ -1764,116 +1906,12 @@ namespace WorldTuningTool P("SSLR Intensity", 0xB424, ParameterType.FLOAT) }; - private static Parameter shadowResParameter = P("Shadow Resolution Multiplier", 0, ParameterType.SHADOW_RESOLUTION, pStep(1)); - private delegate void UpdateShadowParams(nint shadowParams, nint stackOffset); - private delegate void StaticShadowParams(nint shadowParamsStatic, nint shadowObjectInternal); - private Hook? updateShadowParams; - private Hook? staticShadowParams; - private static Parameter[] shadowParameters1 = { - }; - // These are parameters for an Infinite Light object (uSdlInfinite @ 0x143343038). - // "Min Roughness" is +0xFC in params but is never read. - private static Parameter[] shadowParameters2 = { - P("Sunlight Group", 0x14, ParameterType.INT, pMinMaxStep(1, 255, 1)), - P("Sunlight Direction", 0x110, ParameterType.VECTOR3, pStep(0.00025f)), - P("Sunlight Color", 0xE0, ParameterType.COLOR_FACTOR, pMaxStep(1.0f, 0.001f)), - P("Sunlight Intensity", 0xF4, ParameterType.FLOAT, pStep(0.005f)), - P("Sunlight Is Primary", 0x1D, ParameterType.BOOL), - P("Do Volumetric", 0x1F, ParameterType.BOOL), - P("Shadow Cast", 0x23, ParameterType.BOOL), - P("Shadow Map Size", 0x30, ParameterType.ALIGNED_INT, pMinStep(0, 128)), // 0 = 64x64 no multiplier @TODO: Verify in the code. - P("Shadow Near Clip Distance", 0x28, ParameterType.FLOAT), - P("Shadow Cascade Mode", 0x174, ParameterType.INT, pMinMaxStep(0, 3, 1)), - P("Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT), - P("Shadow Distance", 0x6C, ParameterType.FLOAT, pStep(5.0f)), - P("Shadow Backforward Distance", 0x7C, ParameterType.FLOAT, pStep(5.0f)), - P("Shadow Is Fixed Fov Mode", 0x1F9, ParameterType.BOOL), - P("Shadow Fov", 0x1F4, ParameterType.FLOAT, pStep(0.0001f)), - P("Shadow Is Discretization Fov Mode", 0x205, ParameterType.BOOL), - P("Shadow Discretization Angle", 0x200, ParameterType.FLOAT, pStep(0.0001f)), - P("Shadow Distribution", 0x74, ParameterType.FLOAT, pStep(0.001f)), - P("Cascade Manual Split", 0x4D, ParameterType.BOOL), - P("Cascade Manual Split Distance[0]", 0x54, ParameterType.FLOAT), - P("Cascade Manual Split Distance[1]", 0x5C, ParameterType.FLOAT), - P("Cascade Manual Split Distance[2]", 0x64, ParameterType.FLOAT), - P("Shadow Sloped Depth Bias", 0x40, ParameterType.FLOAT, pStep(0.00001f)), - P("Shadow Depth Bias", 0x38, ParameterType.FLOAT, pStep(0.00001f)), - P("Shadow Max Depth Bias", 0x48, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Individual Shadow Bias", 0x81, ParameterType.BOOL), - P("Cascade Depth Bias[0]", 0x88, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Sloped Depth Bias[0]", 0xA0, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Max Depth Bias[0]", 0xB8, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Depth Bias[1]", 0x90, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Sloped Depth Bias[1]", 0xA8, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Max Depth Bias[1]", 0xC0, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Depth Bias[2]", 0x98, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Sloped Depth Bias[2]", 0xB0, ParameterType.FLOAT, pStep(0.00001f)), - P("Cascade Max Depth Bias[2]", 0xC8, ParameterType.FLOAT, pStep(0.00001f)), - P("Broad Area Shadow Depth Bias", 0x1C4, ParameterType.FLOAT, pStep(0.00001f)), - P("Broad Area Shadow Sloped Depth Bias", 0x1CC, ParameterType.FLOAT, pStep(0.00001f)), - P("Broad Area Shadow Max Depth Bias", 0x1D4, ParameterType.FLOAT, pStep(0.00001f)), - P("Projection Scale", 0x134, ParameterType.VECTOR2), - P("Projection Offset Speed", 0x144, ParameterType.VECTOR2), - P("Projection Up", 0x160, ParameterType.VECTOR3), - P("Primary Shadow Sample Num", 0x1DC, ParameterType.INT, pStep(1)), - P("Primary Shadow Radius", 0x1EC, ParameterType.FLOAT, pStep(0.0001f)) - }; - - private static MtObject? sLightProbes = null; - private delegate void UpdateLightProbesParams(nint unknownPtr, int unknownInt); - private static Parameter[] sLightProbesParameters = { - P("Light Probes Probe Color", 0x38, ParameterType.COLOR), - P("Light Probes Probe Intensity", 0x3C, ParameterType.FLOAT), - P("Light Probes Top Color", 0x44, ParameterType.COLOR), - P("Light Probes Top Intensity", 0x48, ParameterType.FLOAT), - P("Light Probes Bottom Color", 0x4C, ParameterType.COLOR), - P("Light Probes Bottom Intensity", 0x50, ParameterType.FLOAT), - P("Light Probes Direction", 0x60, ParameterType.VECTOR3), - P("Light Probes Shadow Top Color", 0x70, ParameterType.COLOR), - P("Light Probes Shadow Top Intensity", 0x74, ParameterType.FLOAT), - P("Light Probes Shadow Bottom Color", 0x78, ParameterType.COLOR), - P("Light Probes Shadow Bottom Intensity", 0x7C, ParameterType.FLOAT), - P("Light Probes Shadow Direction", 0x80, ParameterType.VECTOR3), - P("Light Probes Daytime State", 0x9C, ParameterType.INT, pMinMaxStep(0, 6, 1)), - P("Light Probes Daytime Interpolation", 0xA0, ParameterType.FLOAT), - P("Light Probes Max Iter", 0xA4, ParameterType.INT), - P("Light Probes Debug Mode", 0x98, ParameterType.INT, pStep(1)) - }; - - private delegate nint CreateLightingObject(); - private delegate nint DestroyLightingObject(nint lightingObjectInternal, int unknownInt); - private Hook? createLightingObject; - private Hook? destroyLightingObject; - private nint lightingObject = 0x0; - private static LUT luts = new LUT(); - private static Parameter[] lightingParameters = { - P("Light Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 6, 1)), - P("Light Compute Luminance", 0x170, ParameterType.BOOL), - P("Light Luminance Version", 0x168, ParameterType.BOOL), - P("Light Shoulder Strength", 0x174, ParameterType.FLOAT, pStep(0.001f)), - P("Light Linear Strength", 0x178, ParameterType.FLOAT, pStep(0.001f)), - P("Light Linear Angle", 0x17C, ParameterType.FLOAT, pStep(0.001f)), - P("Light Toe Strength", 0x180, ParameterType.FLOAT, pStep(0.001f)), - P("Light Toe Num", 0x184, ParameterType.FLOAT, pStep(0.001f)), - P("Light Toe Denum", 0x188, ParameterType.FLOAT, pStep(0.001f)), - P("Light White Point", 0x18C, ParameterType.FLOAT, pStep(0.01f)), - P("Light LUT Blend", 0x1C8, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)), - P("Light Vfx LUT Blend", 0x1D0, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)), - P("Light Enable Color Grading", 0x1D8, ParameterType.BOOL), - P("Light Is Linear To PQ", 0x1A1, ParameterType.BOOL), - P("Light Is PQ To Linear", 0x1A0, ParameterType.BOOL), - P("Volume Dispersion", 0x19C, ParameterType.FLOAT), - P("Volume Edge Sharpness", 0x198, ParameterType.FLOAT, pStep(0.00001f)), - P("Volume Downsample", 0x210, ParameterType.BOOL) - }; - private static Parameter[] brightnessParameters = { - P("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)), - P("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)), - V("Hdr Output", 0x21A, ParameterType.BOOL), - P("Hdr Output White Level", 0x21C, ParameterType.FLOAT, pStep(0.05f)), - P("Hdr Output Gamut Mapping Ratio", 0x220, ParameterType.FLOAT, pStep(0.001f)), - P("Hdr Output Gamma", 0x224, ParameterType.FLOAT, pStep(0.001f)), - P("Hdr Is Gui Hdr Gamma", 0x228, ParameterType.BOOL) + private delegate nint CreateRenderPassesObject(nint unknownPtr1, nint unknownPtr2); + private delegate nint DestroyRenderPassesObject(nint renderPassesObjectInternal, int unknownInt); + private Hook? createRenderPassesObject; + private Hook? destroyRenderPassesObject; + private nint renderPassesObject = 0x0; + private static Parameter[] renderPassesParameters = { }; private delegate nint CreateBloomObject(); @@ -2089,6 +2127,30 @@ namespace WorldTuningTool P("Fog Mip Fog Color", 0x330, ParameterType.COLOR_FACTOR, pStep(0.001f)) }; + private static MtObject? sMhSpeedTree = null; + private static Parameter[] speedTreeParameters = { + //P("Speed Tree is Active", 0x339, ParameterType.BOOL), + P("Speed Tree Wind Active", 0x33A, ParameterType.BOOL), + //P("Speed Tree System Wind Active", 0x33C, ParameterType.BOOL), + //P("Speed Tree Disp Off Water Reflection", 0x33B, ParameterType.BOOL), + P("Speed Tree Wind Direction", 0x210 + 0x30, ParameterType.VECTOR3), + P("Speed Tree Wind Strength", 0x210 + 0x40, ParameterType.FLOAT), + /* + P("Speed Tree Wind Strength Response", 0x210 + 0x44, ParameterType.FLOAT), + P("Speed Tree Wind Direction Response", 0x210 + 0x48, ParameterType.FLOAT), + P("Speed Tree Wind Gust Frequency", 0x210 + 0x4C, ParameterType.FLOAT), + P("Speed Tree Wind Gust Strength Min", 0x210 + 0x50, ParameterType.FLOAT), + P("Speed Tree Wind Gust Strength Max", 0x210 + 0x54, ParameterType.FLOAT), + P("Speed Tree Wind Gust Duration Min", 0x210 + 0x58, ParameterType.FLOAT), + P("Speed Tree Wind Gust Duration Max", 0x210 + 0x5C, ParameterType.FLOAT), + P("Speed Tree Wind Gust Rise Scalar", 0x210 + 0x60, ParameterType.FLOAT), + P("Speed Tree Wind Gust Fall Scalar", 0x210 + 0x64, ParameterType.FLOAT), + P("Speed Tree Wind Gust Enable", 0x210 + 0x68, ParameterType.BOOL), + P("Speed Tree Wind Instance Delay", 0x32C, ParameterType.FLOAT), + P("Speed Tree Wind Blend Length", 0x328, ParameterType.FLOAT) + */ + }; + private delegate nint CreateWaterWaveObject(nint unknownPtr); private delegate nint DestroyWaterWaveObject(nint waterWaveObjectInternal, int unknownInt); private Hook? createWaterWaveObject; @@ -2134,24 +2196,29 @@ namespace WorldTuningTool .Concat(sTimeParameters) .Concat(lodParameters) .Concat(snowParameters) + .Concat(passthroughParameters) .Append(shadowResParameter) - .Concat(shadowParameters2) .Concat(shadowCascadeParameters) + .Concat(primaryShadowParameters) .Concat(broadAreaShadowParameters) + .Concat(primaryBroadAreaParameters) + .Concat(primaryLightParameters) .Concat(sLightProbesParameters) .Concat(contactShadowParameters) .Concat(capsuleLightParameters) .Concat(ssaoParameters) - .Concat(sslrParameters) - .Concat(passthroughParameters) - .Concat(lightingParameters) + .Concat(sVolumeRendererParameters) + .Concat(toneMapParameters) + .Concat(exposureParameters) .Concat(brightnessParameters) + .Concat(sslrParameters) .Concat(bloomParameters) .Concat(dofParameters) .Concat(motionBlurParameters) .Concat(hazeParameters) .Concat(simpleSkyParameters) .Concat(fogParameters) + .Concat(speedTreeParameters) .Concat(waterWaveParameters) .Concat(fxaaParameters) .Concat(taaParameters) @@ -2329,6 +2396,12 @@ namespace WorldTuningTool private bool continousSSLRTemporalReset = false; private Patch forceSSLRTemporalReset; +#if SHADER_FEATURES + private bool volumeUpsampleNoLinear = false; + private bool fxaaMaxQuality = false; + private bool skinAllowNegativeWet = false; +#endif + private bool fullResVolumeBlur = false; private Patch volumeSars1; private Patch volumeSars2; @@ -2394,11 +2467,21 @@ namespace WorldTuningTool defaultViewModeLODLimit_4.Disable(); } + private Patch defaultCharaCreatorParam; + private bool charaCreatorFace = false; + private bool largerFoliageSwayRange = false; private Patch addressHigherValueForFoliageSway; private bool disableReducedRateAnimations = false; + private bool disableReducedRateAnimations2 = false; private Patch zeroFrameSkip; + private Patch zeroFrameSkip2; + private Patch zeroFrameSkip3; + + private bool viewModeLodOverride = false; + private Patch viewModeAddressLod1; + private Patch viewModeAddressLod2; private bool nukeEffects = false; private Patch jmpOverEffects; @@ -2458,7 +2541,7 @@ namespace WorldTuningTool // Assert no duplicate names. foreach (Parameter param in allParameters) { - Assert(Array.FindAll(allParameters, (p => p.Name == param.Name)).Length == 1); + Assert(Array.FindAll(allParameters, ((p) => p.Name == param.Name)).Length == 1); } // Assert OrderedStages covers all values. @@ -2475,54 +2558,60 @@ namespace WorldTuningTool // Used for: // "Capsule AO Intensity". // "Broad Area Shadow Direction". Otherwise it will flicker on center change. - evaluateSceneParams = Hook.Create(0x1423C3790, EvaluateSceneParamsHook); // nint, nint, int, nint + evaluateSceneParams = Hook.Create(0x1423C3790, EvaluateSceneParamsHook); // These run in a loop during cutscenes. - updateSSAOParams = Hook.Create(0x1416D8B10, UpdateSSAOParamsHook); // nint - updateSSLRParams = Hook.Create(0x1416DA3F0, UpdateSSLRParamsHook); // nint - updateLightingParams = Hook.Create(0x1416DAAB0, UpdateLightingParamsHook); // nint, nint + updateSSAOParams = Hook.Create(0x1416D8B10, UpdateSSAOParamsHook); + updateSSLRParams = Hook.Create(0x1416DA3F0, UpdateSSLRParamsHook); + updateToneMapParams = Hook.Create(0x1416DAAB0, UpdateToneMapParamsHook); + + createToneMapObject = Hook.Create(0x1424CDE20, CreateToneMapObjectHook); + destroyToneMapObject = Hook.Create(0x1424CE380, DestroyToneMapObjectHook); - createLightingObject = Hook.Create(0x1424CDE20, CreateLightingObjectHook); - destroyLightingObject = Hook.Create(0x1424CE380, DestroyLightingObjectHook); // nint, int + createRenderPassesObject = Hook.Create(0x14255BA70, CreateRenderPassesObjectHook); + destroyRenderPassesObject = Hook.Create(0x14255C710, DestroyRenderPassesObjectHook); createBloomObject = Hook.Create(0x1424CB3C0, CreateBloomObjectHook); - createBloomObject2 = Hook.Create(0x1424CB5E0, CreateBloomObject2Hook); // nint - destroyBloomObject = Hook.Create(0x1424CB750, DestroyBloomObjectHook); // nint, int + createBloomObject2 = Hook.Create(0x1424CB5E0, CreateBloomObject2Hook); + destroyBloomObject = Hook.Create(0x1424CB750, DestroyBloomObjectHook); createDofObject = Hook.Create(0x142421E80, CreateDofObjectHook); - createDofObject2 = Hook.Create(0x1424220A0, CreateDofObject2Hook); // nint - destroyDofObject = Hook.Create(0x142422290, DestroyDofObjectHook); // nint, int + createDofObject2 = Hook.Create(0x1424220A0, CreateDofObject2Hook); + destroyDofObject = Hook.Create(0x142422290, DestroyDofObjectHook); createMotionBlurObject = Hook.Create(0x1424C95E0, CreateMotionBlurObjectHook); - createMotionBlurObject2 = Hook.Create(0x1424C9740, CreateMotionBlurObject2Hook); // nint - destroyMotionBlurObject = Hook.Create(0x1424C97E0, DestroyMotionBlurObjectHook); // nint, int + createMotionBlurObject2 = Hook.Create(0x1424C9740, CreateMotionBlurObject2Hook); + destroyMotionBlurObject = Hook.Create(0x1424C97E0, DestroyMotionBlurObjectHook); createHazeObject = Hook.Create(0x1424C6A80, CreateHazeObjectHook); - createHazeObject2 = Hook.Create(0x1424C6C70, CreateHazeObject2Hook); // nint - destroyHazeObject = Hook.Create(0x1424C6E20, DestroyHazeObjectHook); // nint, int + createHazeObject2 = Hook.Create(0x1424C6C70, CreateHazeObject2Hook); + destroyHazeObject = Hook.Create(0x1424C6E20, DestroyHazeObjectHook); - createSimpleSkyObject = Hook.Create(0x141FCCC20, CreateSimpleSkyObjectHook); // nint - destroySimpleSkyObject = Hook.Create(0x141FCD840, DestroySimpleSkyObjectHook); // nint, int + createSimpleSkyObject = Hook.Create(0x141FCCC20, CreateSimpleSkyObjectHook); + destroySimpleSkyObject = Hook.Create(0x141FCD840, DestroySimpleSkyObjectHook); createFogObject = Hook.Create(0x141FADB50, CreateFogObjectHook); - createFogObject2 = Hook.Create(0x141FADC80, CreateFogObject2Hook); // nint - destroyFogObject = Hook.Create(0x141FADD50, DestroyFogObjectHook); // nint, int + createFogObject2 = Hook.Create(0x141FADC80, CreateFogObject2Hook); + destroyFogObject = Hook.Create(0x141FADD50, DestroyFogObjectHook); - createWaterWaveObject = Hook.Create(0x1423F0850, CreateWaterWaveObjectHook); // nint - destroyWaterWaveObject = Hook.Create(0x1423F0EE0, DestroyWaterWaveObjectHook); // nint, int + createWaterWaveObject = Hook.Create(0x1423F0850, CreateWaterWaveObjectHook); + destroyWaterWaveObject = Hook.Create(0x1423F0EE0, DestroyWaterWaveObjectHook); createFXAAObject = Hook.Create(0x142393560, CreateFXAAObjectHook); - createFXAAObject2 = Hook.Create(0x142393680, CreateFXAAObject2Hook); // nint - destroyFXAAObject = Hook.Create(0x142393740, DestroyFXAAObjectHook); // nint, int + createFXAAObject2 = Hook.Create(0x142393680, CreateFXAAObject2Hook); + destroyFXAAObject = Hook.Create(0x142393740, DestroyFXAAObjectHook); createTAAObject = Hook.Create(0x1423911A0, CreateTAAObjectHook); - createTAAObject2 = Hook.Create(0x142391320, CreateTAAObject2Hook); // nint - destroyTAAObject = Hook.Create(0x1423916E0, DestroyTAAObjectHook); // nint, int + createTAAObject2 = Hook.Create(0x142391320, CreateTAAObject2Hook); + destroyTAAObject = Hook.Create(0x1423916E0, DestroyTAAObjectHook); nint addr = PatternScanner.FindFirst(Pattern.FromString("48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 56 41 57 48 8B EC 48 83 EC 30 48 8B FA 48 8B D9 E8 AA B6 C1 FF 48 8B 47 10 48 8D 57 50")); - Assert(addr == 0x141AB2260); // nint, nint - updateShadowParams = Hook.Create(addr, UpdateShadowParamsHook); - staticShadowParams = Hook.Create(0x1416D94F0, StaticShadowParamsHook); // nint, nint + Assert(addr == 0x141AB2260); + updatePrimaryLightParams = Hook.Create(addr, UpdatePrimaryLightParamsHook); + staticPrimaryLightParams = Hook.Create(0x1416D94F0, StaticPrimaryLightParamsHook); + + defaultHqMode = new Patch(0x14226562B, [0xC6, 0x87, 0xA3, 0xE9, 0x00, 0x00, 0x01]); + //defaultHqMode.Enable(); setShadowQuality = new NativeAction(0x14043FF80); @@ -2544,9 +2633,9 @@ namespace WorldTuningTool shadowRes1_2 = new Patch(addr + 0x68, [0x59]); // movss -> mulss. shadowRes1_3 = new Patch(addr + 0x77, [0x59]); // movss -> mulss. #if OVERSIZED_SHADOW_MAP - shadowRes1_4 = new Patch(lton(0x142288AAA) + 0x4, [0x7A, 0x97, 0xF8, 0x00]); // Limit 4.0 -> 6.0. + shadowRes1_4 = new Patch(0x142288AAA + 0x4, [0x7A, 0x97, 0xF8, 0x00]); // Limit 4.0 -> 6.0. #else - shadowRes1_4 = new Patch(lton(0x142288AAA) + 0x4, [0x9E]); // Limit 4.0 -> 5.0. + shadowRes1_4 = new Patch(0x142288AAA + 0x4, [0x9E]); // Limit 4.0 -> 5.0. #endif addr = PatternScanner.FindFirst(Pattern.FromString("89 91 00 55 00 00 83 FA 05 77 41 48 63 C2 4C 8D 05 ?? ?? ?? ?? 41 8B 94 80 84 8B 28 02 49 03 D0 FF E2 B8 00 08 00 00")); Assert(addr == 0x142288B00); @@ -2570,35 +2659,35 @@ namespace WorldTuningTool broadAreaShadowRes2_Addr = addr; // 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 + // time (area change/createToneMapObject() vs change of Volume Quality setting). It's also rendered // in a seperate pass that happens after the initial volume rendering. So keep that in mind if inspecting // a frame in renderdoc. - volumeSars1 = new Patch(lton(0x1424D0159), [0x90, 0x90]); - volumeSars2 = new Patch(lton(0x1424D01A0), [0x90, 0x90]); - volumeSars3 = new Patch(lton(0x1424D01C6), [0x90, 0x90]); - volumeSars4 = new Patch(lton(0x1424D0219), [0x90, 0x90]); - volumeSars5 = new Patch(lton(0x1424D0242), [0x90, 0x90]); - volumeSars6 = new Patch(lton(0x1424D029D), [0x90, 0x90]); - volumeSars7 = new Patch(lton(0x1424D02C6), [0x90, 0x90]); - volumeSars8 = new Patch(lton(0x1424D0321), [0x90, 0x90]); - volumeSars9 = new Patch(lton(0x1424D034A), [0x90, 0x90]); + volumeSars1 = new Patch(0x1424D0159, [0x90, 0x90]); + volumeSars2 = new Patch(0x1424D01A0, [0x90, 0x90]); + volumeSars3 = new Patch(0x1424D01C6, [0x90, 0x90]); + volumeSars4 = new Patch(0x1424D0219, [0x90, 0x90]); + volumeSars5 = new Patch(0x1424D0242, [0x90, 0x90]); + volumeSars6 = new Patch(0x1424D029D, [0x90, 0x90]); + volumeSars7 = new Patch(0x1424D02C6, [0x90, 0x90]); + volumeSars8 = new Patch(0x1424D0321, [0x90, 0x90]); + volumeSars9 = new Patch(0x1424D034A, [0x90, 0x90]); /* As far as I can tell, this is limited by buffers created cpu-side. Seems like * it would be an extremely hard change. - froxelRes1 = new Patch(lton(0x142384F15) + 0x1, [0x02]); // 4 -> 2 - froxelRes2 = new Patch(lton(0x142389711) + 0x1, [0x02]); // 4 -> 2 - froxelRes3 = new Patch(lton(0x142389878) + 0x1, [0x02]); // 4 -> 2 - froxelRes4 = new Patch(lton(0x14238989E) + 0x1, [0x02]); // 4 -> 2 - froxelRes5 = new Patch(lton(0x1423898D8) + 0x1, [0x02]); // 4 -> 2 - froxelRes6 = new Patch(lton(0x14238992B) + 0x1, [0x02]); // 4 -> 2 - froxelRes7 = new Patch(lton(0x14238FED1) + 0x4, [0x7B, 0xFF, 0xAB, 0x00]); // 0.25 -> 0.50 - froxelRes8 = new Patch(lton(0x14239009C) + 0x4, [0xB0, 0xFD, 0xAB, 0X00]); // 0.25 -> 0.50 + froxelRes1 = new Patch(0x142384F15 + 0x1, [0x02]); // 4 -> 2 + froxelRes2 = new Patch(0x142389711 + 0x1, [0x02]); // 4 -> 2 + froxelRes3 = new Patch(0x142389878 + 0x1, [0x02]); // 4 -> 2 + froxelRes4 = new Patch(0x14238989E + 0x1, [0x02]); // 4 -> 2 + froxelRes5 = new Patch(0x1423898D8 + 0x1, [0x02]); // 4 -> 2 + froxelRes6 = new Patch(0x14238992B + 0x1, [0x02]); // 4 -> 2 + froxelRes7 = new Patch(0x14238FED1 + 0x4, [0x7B, 0xFF, 0xAB, 0x00]); // 0.25 -> 0.50 + froxelRes8 = new Patch(0x14239009C + 0x4, [0xB0, 0xFD, 0xAB, 0X00]); // 0.25 -> 0.50 */ /* Would require a complicated shader edit to maybe work. Similar to SSLR. - checkerRes1 = new Patch(lton(0x14238580D) + 0x4, [0x43]); // 0.5 -> 1.0 - checkerRes2 = new Patch(lton(0x14238FFC3) + 0x4, [0x8D]); // 0.5 -> 1.0 + checkerRes1 = new Patch(0x14238580D + 0x4, [0x43]); // 0.5 -> 1.0 + checkerRes2 = new Patch(0x14238FFC3 + 0x4, [0x8D]); // 0.5 -> 1.0 */ - value2ForVolumeQuality = new Patch(lton(0x142389652), [0xB8, 0x02, 0x00, 0x00, 0x00, 0x90]); + value2ForVolumeQuality = new Patch(0x142389652, [0xB8, 0x02, 0x00, 0x00, 0x00, 0x90]); // Gameplay. addr = PatternScanner.FindFirst(Pattern.FromString("80 BB 34 EC 00 00 00 88 8B 31 EC 00 00 C6 83 30 EC 00 00 00 74 1C C6 83 34 EC 00 00 00 48 8B 0D 68 4B 4F 03 80 B9 58 02 00 00 00 75 05 E8 5A F5 01 00 48 8B CB E8 E2 05 00 00 83 BB DC EB 00 00 06 74 0A C7 83 DC EB 00 00 06 00 00 00")); @@ -2616,18 +2705,25 @@ namespace WorldTuningTool defaultViewModeLODLimit_2 = new Patch(addr + 0x24, [0x07]); // Talking to NPC. - defaultViewModeLODLimit_3 = new Patch(lton(0x14128F1AC) + 0x1, [0x07]); - defaultViewModeLODLimit_4 = new Patch(lton(0x14128F1AC) + 0xF, [0x07]); + defaultViewModeLODLimit_3 = new Patch(0x14128F1AC + 0x1, [0x07]); + defaultViewModeLODLimit_4 = new Patch(0x14128F1AC + 0xF, [0x07]); + + defaultCharaCreatorParam = new Patch(0x141B1A0C1 + 0x6, [0x1]); addr = PatternScanner.FindFirst(Pattern.FromString("74 4D 33 C0 48 81 C1 00 02 00 00 F3 0F 10 11 0F 2F CA 72 0C FF C0 48 83 C1 04 83 F8 03 72 EC C3")); Assert(addr == 0x1426D89CA); addressHigherValueForFoliageSway = new Patch(addr + 0x7, [0x04]); // Found using mFrameSkipNum annotation from MHW-DTI-Dumps. - zeroFrameSkip = new Patch(lton(0x142246948), [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]); + zeroFrameSkip = new Patch(0x142246948, [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]); + zeroFrameSkip2 = new Patch(0x142641888, [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]); + zeroFrameSkip3 = new Patch(0x14237AD75, [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]); + + viewModeAddressLod1 = new Patch(0x141B19A6C + 0x4, [0x1C, 0x02, 0x00, 0x00]); + viewModeAddressLod2 = new Patch(0x141B19B7C + 0x4, [0x20, 0x02, 0x00, 0x00]); // vTable of Interest: 0x1433B8730. - jmpOverEffects = new Patch(lton(0x14263483B), [0xEB]); + jmpOverEffects = new Patch(0x14263483B, [0xEB]); // The game will crash when trying to switch to the FULL_RES path for SSR. It's likley because // it tries to access shaders that are not available in the game files. @@ -2637,78 +2733,78 @@ namespace WorldTuningTool // is that it's compiled out and that this method of increasing the SSR resolution can't work. /* // Attempt to forcefully enable FULL_RES path for SSR. - ssrFullRes1 = new Patch(lton(0x14228894D), [0x0F, 0x85, 0xB9, 0xAA, 0x30, 0x00]); - ssrFullRes1_1 = new Patch(lton(0x14259340C), [0xC6, 0x81, 0x28, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrFullRes2 = new Patch(lton(0x14228897D), [0x0F, 0x85, 0x99, 0xAA, 0x30, 0x00]); - ssrFullRes2_1 = new Patch(lton(0x14259341C), [0xC6, 0x81, 0x30, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrFullRes3 = new Patch(lton(0x1422889AD), [0x0F, 0x85, 0x79, 0xAA, 0x30, 0x00]); - ssrFullRes3_1 = new Patch(lton(0x14259342C), [0xC6, 0x81, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); - ssrFullRes4 = new Patch(lton(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(0x14228894D, [0x0F, 0x85, 0xB9, 0xAA, 0x30, 0x00]); + ssrFullRes1_1 = new Patch(0x14259340C, [0xC6, 0x81, 0x28, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes2 = new Patch(0x14228897D, [0x0F, 0x85, 0x99, 0xAA, 0x30, 0x00]); + ssrFullRes2_1 = new Patch(0x14259341C, [0xC6, 0x81, 0x30, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes3 = new Patch(0x1422889AD, [0x0F, 0x85, 0x79, 0xAA, 0x30, 0x00]); + ssrFullRes3_1 = new Patch(0x14259342C, [0xC6, 0x81, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90]); + ssrFullRes4 = new Patch(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]); */ // SSLR resolution factor 0.5 -> 1.0 (not related to fSSLRFactor or fSSLRScale). - ssrRes1 = new Patch(lton(0x1425926B8) + 0x9, [0x80]); - ssrRes2 = new Patch(lton(0x1425934C0) + 0x8, [0x80]); + ssrRes1 = new Patch(0x1425926B8 + 0x9, [0x80]); + ssrRes2 = new Patch(0x1425934C0 + 0x8, [0x80]); // Skip mip mapping pass (part of _FULL_RES). - ssrRes3 = new Patch(lton(0x142282B53), [0x31, 0xC0, 0x90, 0x90, 0x90]); + ssrRes3 = new Patch(0x142282B53, [0x31, 0xC0, 0x90, 0x90, 0x90]); // Depth mips resolution. - ssrShr1 = new Patch(lton(0x14269DE47), [0x90, 0x90]); - ssrShr2 = new Patch(lton(0x14269DE54), [0x90, 0x90]); - ssrShr3 = new Patch(lton(0x14269E07A), [0x90, 0x90]); - ssrShr4 = new Patch(lton(0x14269E080), [0x90, 0x90]); + ssrShr1 = new Patch(0x14269DE47, [0x90, 0x90]); + ssrShr2 = new Patch(0x14269DE54, [0x90, 0x90]); + ssrShr3 = new Patch(0x14269E07A, [0x90, 0x90]); + ssrShr4 = new Patch(0x14269E080, [0x90, 0x90]); // Approximate depth mip resolution. - ssrShr5 = new Patch(lton(0x14269DED3) + 0x2, [0x3]); // 4 -> 3 - ssrShr6 = new Patch(lton(0x14269DEDA) + 0x3, [0x3]); + ssrShr5 = new Patch(0x14269DED3 + 0x2, [0x3]); // 4 -> 3 + ssrShr6 = new Patch(0x14269DEDA + 0x3, [0x3]); // Depth mips pass 1 dispatch dimensions. - ssrSars1 = new Patch(lton(0x142282FD8) + 0x3, [0x3]); // 4 -> 3 - ssrSars2 = new Patch(lton(0x142282FE5) + 0x2, [0x3]); + ssrSars1 = new Patch(0x142282FD8 + 0x3, [0x3]); // 4 -> 3 + ssrSars2 = new Patch(0x142282FE5 + 0x2, [0x3]); // Depth mips pass 2 iRegion parameter. - ssrSars3 = new Patch(lton(0x142283014) + 0x3, [0x3]); - ssrSars4 = new Patch(lton(0x142283018) + 0x3, [0x3]); - ssrSars5 = new Patch(lton(0x14228301C) + 0x3, [0x3]); - ssrSars6 = new Patch(lton(0x142283020) + 0x2, [0x3]); + ssrSars3 = new Patch(0x142283014 + 0x3, [0x3]); + ssrSars4 = new Patch(0x142283018 + 0x3, [0x3]); + ssrSars5 = new Patch(0x14228301C + 0x3, [0x3]); + ssrSars6 = new Patch(0x142283020 + 0x2, [0x3]); // Depth mips pass 2 dispatch dimensions. - ssrSars7 = new Patch(lton(0x1422832B3) + 0x3, [0x3]); - ssrSars8 = new Patch(lton(0x1422832C8) + 0x2, [0x3]); + ssrSars7 = new Patch(0x1422832B3 + 0x3, [0x3]); + ssrSars8 = new Patch(0x1422832C8 + 0x2, [0x3]); // Depth copy, for unknown use, viewport/scissor. - ssrSars9 = new Patch(lton(0x1423C5809), [0x90, 0x90]); - ssrSars10 = new Patch(lton(0x1423C5818), [0x90, 0x90]); - ssrSars11 = new Patch(lton(0x1423C5824), [0x90, 0x90]); - ssrSars12 = new Patch(lton(0x1423C5830), [0x90, 0x90]); - ssrSars13 = new Patch(lton(0x1423C5ABC), [0x90, 0x90]); - ssrSars14 = new Patch(lton(0x1423C5AF3), [0x90, 0x90]); + ssrSars9 = new Patch(0x1423C5809, [0x90, 0x90]); + ssrSars10 = new Patch(0x1423C5818, [0x90, 0x90]); + ssrSars11 = new Patch(0x1423C5824, [0x90, 0x90]); + ssrSars12 = new Patch(0x1423C5830, [0x90, 0x90]); + ssrSars13 = new Patch(0x1423C5ABC, [0x90, 0x90]); + ssrSars14 = new Patch(0x1423C5AF3, [0x90, 0x90]); // RayAppendBuffer dispatch dimensions, 4 -> 3 wasteful. - //new Patch(lton(0x14228C323) + 0x3, [0x3]); - //new Patch(lton(0x14228C32D) + 0x2, [0x3]); + //new Patch(0x14228C323 + 0x3, [0x3]); + //new Patch(0x14228C32D + 0x2, [0x3]); // Clear trace buffer, 8 -> 7 wasteful - //new Patch(lton(0x14228C3F4) + 0x2, [0x7]); + //new Patch(0x14228C3F4 + 0x2, [0x7]); // Approximate mip resolution. - ssrShr7 = new Patch(lton(0x142592EBA) + 0x2, [0x3]); // 4 -> 3 - ssrShr8 = new Patch(lton(0x142592ED0) + 0x2, [0x3]); + ssrShr7 = new Patch(0x142592EBA + 0x2, [0x3]); // 4 -> 3 + ssrShr8 = new Patch(0x142592ED0 + 0x2, [0x3]); // Mips pass 1 dispatch dimensions. - ssrSars15 = new Patch(lton(0x142283626) + 0x3, [0x03]); // 4 -> 3 - ssrSars16 = new Patch(lton(0x142283633) + 0x2, [0x03]); + ssrSars15 = new Patch(0x142283626 + 0x3, [0x03]); // 4 -> 3 + ssrSars16 = new Patch(0x142283633 + 0x2, [0x03]); // Mips pass 2 iRegion parameter. - ssrSars17 = new Patch(lton(0x142283667) + 0x2, [0x03]); - ssrSars18 = new Patch(lton(0x14228366A) + 0x3, [0x03]); - ssrSars19 = new Patch(lton(0x14228366E) + 0x3, [0x03]); - ssrSars20 = new Patch(lton(0x142283672) + 0x3, [0x03]); + ssrSars17 = new Patch(0x142283667 + 0x2, [0x03]); + ssrSars18 = new Patch(0x14228366A + 0x3, [0x03]); + ssrSars19 = new Patch(0x14228366E + 0x3, [0x03]); + ssrSars20 = new Patch(0x142283672 + 0x3, [0x03]); // Mips pass 2 dispatch dimensions. - ssrSars21 = new Patch(lton(0x1422838E7) + 0x3, [0x03]); - ssrSars22 = new Patch(lton(0x1422838FC) + 0x2, [0x03]); + ssrSars21 = new Patch(0x1422838E7 + 0x3, [0x03]); + ssrSars22 = new Patch(0x1422838FC + 0x2, [0x03]); // Mips blur dispatch dimensions. - ssrSars23 = new Patch(lton(0x1422839B0), [0x8D, 0x0E, 0x44, 0x8D, 0x76, 0x01, 0x90]); + ssrSars23 = new Patch(0x1422839B0, [0x8D, 0x0E, 0x44, 0x8D, 0x76, 0x01, 0x90]); // Resolve pass, 4 -> 3 wasteful. - //new Patch(lton(0x14228686D) + 0x3, [0x3]); - //new Patch(lton(0x142286877) + 0x2, [0x3]); + //new Patch(0x14228686D + 0x3, [0x3]); + //new Patch(0x142286877 + 0x2, [0x3]); - forceSSLRTemporalReset = new Patch(lton(0x14228CE53), [0xB9, 0x01, 0x00, 0x00, 0x00, 0x90, 0x90]); + forceSSLRTemporalReset = new Patch(0x14228CE53, [0xB9, 0x01, 0x00, 0x00, 0x00, 0x90, 0x90]); return new PluginData(); } @@ -2719,7 +2815,7 @@ namespace WorldTuningTool disableLightsFeature = config.DisableLightsFeature; if (!disableLightsFeature) { - lights.Initialize(); + Lights.Initialize(); } PatchConfig patches = config.Patches; #if SHADER_FEATURES @@ -2760,6 +2856,9 @@ namespace WorldTuningTool ssrSars22.Enable(); ssrSars23.Enable(); } + volumeUpsampleNoLinear = patches.VolumeUpsampleNoLinear; + fxaaMaxQuality = patches.FXAAMaxQualityPreset; + skinAllowNegativeWet = patches.SkinAllowNegativeWetness; #endif fullResVolumeBlur = patches.FullResolutionVolumeBlur; if (fullResVolumeBlur) @@ -2776,6 +2875,11 @@ namespace WorldTuningTool { disableLODLimitsEnable(); } + charaCreatorFace = patches.CharacterCreatorFaceRendering; + if (charaCreatorFace) + { + defaultCharaCreatorParam.Enable(); + } largerFoliageSwayRange = patches.LargerFoliageSwayRange; if (largerFoliageSwayRange) { @@ -2797,6 +2901,8 @@ namespace WorldTuningTool sQuest = SingletonManager.GetSingleton("sQuest")!; sLightLinker = SingletonManager.GetSingleton("sLightLinker")!; sLightProbes = SingletonManager.GetSingleton("sLightProbes")!; + sVolumeRenderer = SingletonManager.GetSingleton("sVolumeRenderer")!; + sMhSpeedTree = SingletonManager.GetSingleton("sMhSpeedTree")!; foreach (Parameter param in sLightProbesParameters) { param.Update(sLightProbes!.Instance); @@ -2877,7 +2983,7 @@ namespace WorldTuningTool if (!disableLightsFeature) { - lights.OnUpdate(); + Lights.OnUpdate(); } } @@ -2937,6 +3043,19 @@ namespace WorldTuningTool param.Update(sMhRender!.Instance); } + foreach (Parameter param in exposureParameters) + { + param.Update(sMhScene!.Instance); + } + + if (renderPassesObject != 0x0) + { + foreach (Parameter param in renderPassesParameters) + { + param.Update(renderPassesObject); + } + } + if (bloomObject != 0x0) { foreach (Parameter param in bloomParameters) @@ -2987,11 +3106,16 @@ namespace WorldTuningTool param.Update(sLightProbes!.Instance); } - if (lightingObject != 0x0) + foreach (Parameter param in sVolumeRendererParameters) { - foreach (Parameter param in lightingParameters) + param.Update(sVolumeRenderer!.Instance); + } + + if (toneMapObject != 0x0) + { + foreach (Parameter param in toneMapParameters) { - param.Update(lightingObject); + param.Update(toneMapObject); } } @@ -3027,9 +3151,14 @@ namespace WorldTuningTool } } + foreach (Parameter param in speedTreeParameters) + { + param.Update(sMhSpeedTree!.Instance); + } + if (!disableLightsFeature) { - lights.PostUpdateLightLinker(); + Lights.PostUpdateLightLinker(); } } @@ -3066,40 +3195,64 @@ namespace WorldTuningTool } } - private void UpdateLightingParamsHook(nint stackOffset, nint lightingObjectInternal) + private void UpdateToneMapParamsHook(nint stackOffset, nint toneMapObjectInternal) + { + updateToneMapParams!.Original(stackOffset, toneMapObjectInternal); + if (toneMapObject == toneMapObjectInternal) + { + foreach (Parameter param in toneMapParameters) + { + param.Update(toneMapObject, true); + } + } + } + + private nint CreateToneMapObjectHook() + { + toneMapObject = createToneMapObject!.Original(); + foreach (Parameter param in toneMapParameters) + { + param.Update(toneMapObject); + } + return toneMapObject; + } + + private nint DestroyToneMapObjectHook(nint toneMapObjectInternal, int unknownInt) { - updateLightingParams!.Original(stackOffset, lightingObjectInternal); - if (lightingObject == lightingObjectInternal) + Assert(unknownInt == 1); + if (toneMapObject == toneMapObjectInternal) { - foreach (Parameter param in lightingParameters) + toneMapObject = 0x0; + foreach (Parameter param in toneMapParameters) { - param.Update(lightingObject, true); + param.Update(toneMapObject); } } + return destroyToneMapObject!.Original(toneMapObjectInternal, unknownInt); } - private nint CreateLightingObjectHook() + private nint CreateRenderPassesObjectHook(nint unknownPtr1, nint unknownPtr2) { - lightingObject = createLightingObject!.Original(); - foreach (Parameter param in lightingParameters) + renderPassesObject = createRenderPassesObject!.Original(unknownPtr1, unknownPtr2); + foreach (Parameter param in renderPassesParameters) { - param.Update(lightingObject); + param.Update(renderPassesObject); } - return lightingObject; + return renderPassesObject; } - private nint DestroyLightingObjectHook(nint lightingObjectInternal, int unknownInt) + private nint DestroyRenderPassesObjectHook(nint renderPassesObjectInternal, int unknownInt) { Assert(unknownInt == 1); - if (lightingObject == lightingObjectInternal) + if (renderPassesObject == renderPassesObjectInternal) { - lightingObject = 0x0; - foreach (Parameter param in lightingParameters) + renderPassesObject = 0x0; + foreach (Parameter param in renderPassesParameters) { - param.Update(lightingObject); + param.Update(renderPassesObject); } } - return destroyLightingObject!.Original(lightingObjectInternal, unknownInt); + return destroyRenderPassesObject!.Original(renderPassesObjectInternal, unknownInt); } private nint CreateBloomObjectHook() @@ -3388,30 +3541,46 @@ namespace WorldTuningTool return destroyTAAObject!.Original(taaObjectInternal, unknownInt); } - private void UpdateShadowParamsHook(nint shadowParams, nint stackOffset) + private void UpdatePrimaryLightParamsHook(nint primaryLightParams, nint stackOffset) { bool isPrimary = MemoryUtil.Read(stackOffset + 0x1D) == 0x1; if (isPrimary) { - foreach (Parameter param in shadowParameters2) + foreach (Parameter param in primaryLightParameters) + { + param.Update(stackOffset, true); + } + foreach (Parameter param in primaryShadowParameters) + { + param.Update(stackOffset, true); + } + foreach (Parameter param in primaryBroadAreaParameters) { param.Update(stackOffset, true); } } - updateShadowParams!.Original(shadowParams, stackOffset); + updatePrimaryLightParams!.Original(primaryLightParams, stackOffset); } - private void StaticShadowParamsHook(nint shadowParamsStatic, nint shadowObjectInternal) + private void StaticPrimaryLightParamsHook(nint primaryLightParamsStatic, nint primaryLightObjectInternal) { - if (shadowObjectInternal == 0x0) + if (primaryLightObjectInternal == 0x0) { // Necessary to apply Broad Area Depth Bias overrides on first update. - foreach (Parameter param in shadowParameters2) + foreach (Parameter param in primaryLightParameters) { - param.Update(shadowParamsStatic, true); + param.Update(primaryLightParamsStatic, true); + } + foreach (Parameter param in primaryShadowParameters) + { + param.Update(primaryLightParamsStatic, true); + } + foreach (Parameter param in primaryBroadAreaParameters) + { + param.Update(primaryLightParamsStatic, true); } } - staticShadowParams!.Original(shadowParamsStatic, shadowObjectInternal); + staticPrimaryLightParams!.Original(primaryLightParamsStatic, primaryLightObjectInternal); } private void HandleSetChange(string prevSet, List globalOverrides, List? stageOverrides) @@ -3586,6 +3755,7 @@ namespace WorldTuningTool { boxColor = ImGui.GetStyle().Colors[(int)ImGuiCol.Button]; } + boxColor.W = ImGui.GetStyle().Alpha; ImDrawListPtr drawList = ImGui.GetWindowDrawList(); drawList.AddRectFilled(windowPos, windowPos + new Vector2(boxWidth, boxHeight), (uint)ColorVectorToInt(boxColor)); } @@ -3980,7 +4150,11 @@ namespace WorldTuningTool ImGui.Text("External:"); foreach (Override ovE in externalOverrides.Values) { - ovE.Draw(false, null, null, null, false, width); + Vector2 cursorPos = default; + float boxHeight = 0.0f, boxWidth = 0.0f; + prepareStatusBox(ref cursorPos, ref boxHeight, ref boxWidth); + bool hasStatus = ovE.Draw(false, null, null, null, false, width); + drawStatusBox(false, hasStatus, cursorPos, boxHeight, boxWidth); } ImGui.PopID(); @@ -3991,7 +4165,9 @@ namespace WorldTuningTool PatchConfig patches = config.Patches; #if SHADER_FEATURES - if (ImGui.Checkbox("Full Resolution Screen Space Reflections (Requires Restart)", ref fullResSSLR)) + ImGui.Text("Shader (Requires Restart):"); + ImGui.Separator(); + if (ImGui.Checkbox("Full Resolution Screen Space Reflections", ref fullResSSLR)) { patches.FullResolutionSSLR = fullResSSLR; config.Patches = patches; @@ -3999,11 +4175,49 @@ namespace WorldTuningTool } if (ImGui.BeginItemTooltip()) { - ImGui.Text("Restart Required"); + ImGui.Text("Very complex patch, please report any issues you notice.\nThis also appears to scale SSLR Eliminate Depth, it's suggested to half it's value when this is enabled."); + ImGui.EndTooltip(); + } + + if (ImGui.Checkbox("Volume Rendering No Linear Sampling", ref volumeUpsampleNoLinear)) + { + patches.VolumeUpsampleNoLinear = volumeUpsampleNoLinear; + config.Patches = patches; + saveConfig(config); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Fix for black square artifacts on object edges."); + ImGui.EndTooltip(); + } + + if (ImGui.Checkbox("FXAA Max Quality Preset", ref fxaaMaxQuality)) + { + patches.FXAAMaxQualityPreset = fxaaMaxQuality; + config.Patches = patches; + saveConfig(config); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("#define FXAA_QUALITY__PRESET 39"); + ImGui.EndTooltip(); + } + + if (ImGui.Checkbox("Skin Allow Negative Wetness", ref skinAllowNegativeWet)) + { + patches.SkinAllowNegativeWetness = skinAllowNegativeWet; + config.Patches = patches; + saveConfig(config); + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Can be used to reverse the effect of wet by default modded armor."); ImGui.EndTooltip(); } #endif + ImGui.Text("General:"); + ImGui.Separator(); if (ImGui.Checkbox("Volume Rendering Full Resolution Blur Pass (Requires Area Change)", ref fullResVolumeBlur)) { if (fullResVolumeBlur) @@ -4064,6 +4278,21 @@ namespace WorldTuningTool ImGui.EndTooltip(); } + if (ImGui.Checkbox("Character Creator Face Rendering", ref charaCreatorFace)) + { + if (charaCreatorFace) + { + defaultCharaCreatorParam.Enable(); + } + else + { + defaultCharaCreatorParam.Disable(); + } + patches.CharacterCreatorFaceRendering = charaCreatorFace; + config.Patches = patches; + saveConfig(config); + } + if (ImGui.Checkbox("Larger Foliage Sway Range", ref largerFoliageSwayRange)) { if (largerFoliageSwayRange) @@ -4103,13 +4332,32 @@ namespace WorldTuningTool ImGui.Text("Ignore the frame skip set on an animal's animation when are far from the camera."); ImGui.EndTooltip(); } + + if (ImGui.Checkbox("Override View Mode LODs", ref viewModeLodOverride)) + { + if (viewModeLodOverride) + { + viewModeAddressLod1.Enable(); + viewModeAddressLod2.Enable(); + } + else + { + viewModeAddressLod1.Disable(); + viewModeAddressLod2.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("View Mode still won't consider LOD Length/Pixel Size Bias."); + ImGui.EndTooltip(); + } } if (!disableLightsFeature) { if (ImGui.CollapsingHeader("Lights")) { - lights.DrawUI(width); + Lights.DrawUI(width); } } @@ -4145,7 +4393,7 @@ namespace WorldTuningTool ImGui.PopID(); ImGui.PushID("LOD"); - if (ImGui.CollapsingHeader("Level of Detail")) + if (ImGui.CollapsingHeader("LODs")) { ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); foreach (Parameter param in lodParameters) @@ -4159,52 +4407,49 @@ namespace WorldTuningTool } ImGui.PopID(); - // MonsterHunterWorld.exe+1AB99E0 - mov rax,[MonsterHunterWorld.exe+500E180] - nint shadowAddr = MemoryUtil.Read(0x14500E180); - nint shadowObject = MemoryUtil.Read(shadowAddr + 0x4B0); - shadowAddr += 0x5B0; + ImGui.PushID("Passthrough"); + if (ImGui.CollapsingHeader("Passthrough")) + { + ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); + foreach (Parameter param in passthroughParameters) + { + param.Draw(width); + } + } + ImGui.PopID(); + ImGui.PushID("Shadows"); - if (ImGui.CollapsingHeader("Sunlight and Shadows")) + if (ImGui.CollapsingHeader("Shadows")) { shadowResParameter.Draw(width); ImGui.Separator(); - ImGui.Text($"shadowAddr: 0x{shadowAddr:X}, shadowObject: 0x{shadowObject:X}"); - /* - if (ImGui.CollapsingHeader("Pass 1")) + ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); + foreach (Parameter param in shadowCascadeParameters) { - ImGui.PushID("Pass1"); - foreach (Parameter param in shadowParameters1) - { - param.Draw(width); - } - ImGui.PopID(); + param.Draw(width); } - if (ImGui.CollapsingHeader("Pass 2")) + foreach (Parameter param in primaryShadowParameters) { - ImGui.PushID("Pass2"); - */ - foreach (Parameter param in shadowParameters2) - { - param.Draw(width); - } - /* - ImGui.PopID(); + param.Draw(width); } - */ - ImGui.Separator(); - ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); - foreach (Parameter param in shadowCascadeParameters) + foreach (Parameter param in broadAreaShadowParameters) + { + param.Draw(width); + } + foreach (Parameter param in primaryBroadAreaParameters) { param.Draw(width); } } ImGui.PopID(); - ImGui.PushID("BroadAreaShadows"); - if (ImGui.CollapsingHeader("Broad Area Shadows")) + ImGui.PushID("PrimaryLight"); + if (ImGui.CollapsingHeader("Primary Light")) { - ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); - foreach (Parameter param in broadAreaShadowParameters) + // MonsterHunterWorld.exe+1AB99E0 - mov rax,[MonsterHunterWorld.exe+500E180] + nint primaryLightObject = MemoryUtil.Read(MemoryUtil.Read(0x14500E180) + 0x4B0); + ImGui.Text($"Address: 0x{primaryLightObject:X}"); + foreach (Parameter param in primaryLightParameters) { param.Draw(width); } @@ -4238,7 +4483,7 @@ namespace WorldTuningTool ImGui.PopID(); ImGui.PushID("SSAO"); - if (ImGui.CollapsingHeader("Ambient Occlusion")) + if (ImGui.CollapsingHeader("SSAO")) { ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); foreach (Parameter param in ssaoParameters) @@ -4248,22 +4493,11 @@ namespace WorldTuningTool } ImGui.PopID(); - ImGui.PushID("SSLR"); - if (ImGui.CollapsingHeader("Reflections")) - { - ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); - foreach (Parameter param in sslrParameters) - { - param.Draw(width); - } - } - ImGui.PopID(); - - ImGui.PushID("Passthrough"); - if (ImGui.CollapsingHeader("Passthrough")) + ImGui.PushID("VolumeRenderer"); + if (ImGui.CollapsingHeader("Volume Renderer")) { - ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); - foreach (Parameter param in passthroughParameters) + ImGui.Text($"Address: 0x{sVolumeRenderer!.Instance:X}"); + foreach (Parameter param in sVolumeRendererParameters) { param.Draw(width); } @@ -4273,30 +4507,40 @@ namespace WorldTuningTool ImGui.PushID("Lighting"); if (ImGui.CollapsingHeader("Lighting")) { - ImGui.Text($"Address: 0x{lightingObject:X}"); - if (lightingObject != 0x0) + ImGui.Text($"Address: 0x{toneMapObject:X}"); + if (toneMapObject != 0x0) { if (ImGui.CollapsingHeader("LUTs")) { - nint lutBlendTexture = MemoryUtil.Read(lightingObject + 0x1C0); + nint lutBlendTexture = MemoryUtil.Read(toneMapObject + 0x1C0); ImGui.Text($"LUT Blend: 0x{lutBlendTexture:X}"); - nint lutMap0 = MemoryUtil.Read(lightingObject + 0x1A8); + nint lutMap0 = MemoryUtil.Read(toneMapObject + 0x1A8); if (lutMap0 != 0x0) { - luts.DrawUI(lutMap0, lightingObject, 0, width); + WorldLUTs.DrawUI(lutMap0, toneMapObject, 0, width); } - nint lutMap1 = MemoryUtil.Read(lightingObject + 0x1B0); + nint lutMap1 = MemoryUtil.Read(toneMapObject + 0x1B0); if (lutMap1 != 0x0) { - luts.DrawUI(lutMap1, lightingObject, 1, width); + WorldLUTs.DrawUI(lutMap1, toneMapObject, 1, width); } } - foreach (Parameter param in lightingParameters) + foreach (Parameter param in toneMapParameters) { param.Draw(width); } } ImGui.Separator(); + ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); + foreach (Parameter param in exposureParameters) + { + param.Draw(width); + } + if (ImGui.Button("Reset")) + { + new NativeAction(0x142285F50).Invoke(sMhScene!.Instance); + } + ImGui.Separator(); ImGui.Text($"Address: 0x{sMhRender!.Instance:X}"); foreach (Parameter param in brightnessParameters) { @@ -4305,6 +4549,33 @@ namespace WorldTuningTool } ImGui.PopID(); + ImGui.PushID("SSLR"); + if (ImGui.CollapsingHeader("SSLR")) + { + ImGui.Text($"Address: 0x{sMhScene!.Instance:X}"); + foreach (Parameter param in sslrParameters) + { + param.Draw(width); + } + } + ImGui.PopID(); + + /* + ImGui.PushID("Render Passes"); + if (ImGui.CollapsingHeader("Render Passes")) + { + ImGui.Text($"Address: 0x{renderPassesObject:X}"); + if (renderPassesObject != 0x0) + { + foreach (Parameter param in renderPassesParameters) + { + param.Draw(width); + } + } + } + ImGui.PopID(); + */ + ImGui.PushID("Bloom"); if (ImGui.CollapsingHeader("Bloom")) { @@ -4389,6 +4660,17 @@ namespace WorldTuningTool } ImGui.PopID(); + ImGui.PushID("SpeedTree"); + if (ImGui.CollapsingHeader("SpeedTree")) + { + ImGui.Text($"Address: 0x{sMhSpeedTree!.Instance:X}"); + foreach (Parameter param in speedTreeParameters) + { + param.Draw(width); + } + } + ImGui.PopID(); + ImGui.PushID("WaterWave"); if (ImGui.CollapsingHeader("Water Waves")) { @@ -4491,6 +4773,25 @@ namespace WorldTuningTool ImGui.EndTooltip(); } + if (ImGui.Checkbox("Disable Reduced Rate Animations 2", ref disableReducedRateAnimations2)) + { + if (disableReducedRateAnimations2) + { + zeroFrameSkip2.Enable(); + zeroFrameSkip3.Enable(); + } + else + { + zeroFrameSkip2.Disable(); + zeroFrameSkip3.Disable(); + } + } + if (ImGui.BeginItemTooltip()) + { + ImGui.Text("Unlikely to do anything. If you find an instance were a frame skip is set here, please report.\nThis may be included by the first patch in the future."); + ImGui.EndTooltip(); + } + ImGui.Separator(); } @@ -4512,8 +4813,13 @@ namespace WorldTuningTool } #if SHADER_FEATURES - private static bool replaceShaderFromFile(ShaderInfo *info, string path) + private static bool replaceShaderFromFile(ShaderInfo *info, string path, ShaderSourceType type) { + //if (info->Replacement.Source != null) + //{ + // Log.Warn("Shader already replaced"); + // return false; + //} if (!System.IO.File.Exists(path)) { Log.Warn($"File not found: {path}."); @@ -4529,8 +4835,7 @@ namespace WorldTuningTool Log.Error($"Failed to read: {path}."); return false; } - info->Replacement.Length = shaderData.Length; - info->Replacement.Source = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(shaderData, 0); + info->Replacement.Set(shaderData, type); return true; } @@ -4539,141 +4844,55 @@ namespace WorldTuningTool public unsafe void OnCreateShader(ShaderInfo *info) { string hash = new string(info->DxbcHash); - if (hash == "0c3dacbd-32c175d5-10d80d04-cce7e689") - { - if (replaceShaderFromFile(info, $"{shaderPath}/alpha_as_luma.hlsl")) - { - info->Replacement.Type = ShaderSourceType.HLSL; - Log.Info("Alpha as luma 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 (!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")) - { - 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")) - { - info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("Cube Only shader replaced."); - } - } - */ - else if (hash == "2eed1f00-e24d1b19-9d521064-17b9a586") - { - 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")) - { - info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("Face shader replaced."); - } - } - /* - else if (hash == "18a797dc-9458d333-59e6dff0-9790fcea") - { - if (replaceShaderFromFile(info, $"{shaderPath}/sssss.shdr")) - { - info->Replacement.Type = ShaderSourceType.Binary; - Log.Info("SSSSS 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."); - } - } - */ + if (fullResSSLR) { if (hash == "4b722c0e-8e787cd5-5eaf5e6c-09782f91") { - if (replaceShaderFromFile(info, $"{shaderPath}/sslr_depth_mips.shdr")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_depth_mips.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_trace.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_mips.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_dither.shdr", ShaderSourceType.Binary)) { - 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")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter_no_dither.shdr", ShaderSourceType.Binary)) { - info->Replacement.Type = ShaderSourceType.Binary; Log.Info("SSLR resolve no jitter or dither shader replaced."); } } @@ -4682,13 +4901,97 @@ namespace WorldTuningTool { if (hash == "8703f55f-6c22fba7-1ef876f1-4767379e") { - if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter_min_only.shdr")) + if (replaceShaderFromFile(info, $"{shaderPath}/sslr_resolve_no_jitter_min_only.shdr", ShaderSourceType.Binary)) { - info->Replacement.Type = ShaderSourceType.Binary; Log.Info("SSLR resolve no jitter shader replaced."); } } } + + if (volumeUpsampleNoLinear) + { + if (!shadersLoadedOnce && hash == "2e4e18fd-6ea5eeae-2de3d65c-26ab36dd") + { + if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample1.shdr", ShaderSourceType.Binary)) + { + Log.Info("Volume upsample shader 1 replaced."); + } + } + else if (!shadersLoadedOnce && hash == "e2c8c13e-45bc99b2-4c3d7699-3d66188e") + { + if (replaceShaderFromFile(info, $"{shaderPath}/volume_upsample2.shdr", ShaderSourceType.Binary)) + { + Log.Info("Volume upsample shader 2 replaced."); + } + // This allows us to A/B using the volume rendering value 2 switch. + //shadersLoadedOnce = true; + } + } + + if (fxaaMaxQuality) + { + if (hash == "9ff245fb-4fd555e0-04d0ef15-84609fe1") + { + if (replaceShaderFromFile(info, $"{shaderPath}/fxaa_max_quality.hlsl", ShaderSourceType.HLSL)) + { + Log.Info("FXAA shader replaced."); + } + } + } + + if (skinAllowNegativeWet) + { + if (hash == "2eed1f00-e24d1b19-9d521064-17b9a586") + { + if (replaceShaderFromFile(info, $"{shaderPath}/body_skin.shdr", ShaderSourceType.Binary)) + { + Log.Info("Body skin shader replaced."); + } + } + else if (hash == "8e5e3c09-ebe77ee4-ba1cb659-d25bc7bf") + { + if (replaceShaderFromFile(info, $"{shaderPath}/face.shdr", ShaderSourceType.Binary)) + { + Log.Info("Face shader replaced."); + } + } + } + + if (hash == "ca33bab6-2119df84-41786a69-404471cd") + { + if (replaceShaderFromFile(info, $"{shaderPath}/color_grading_ex_tonemappers.shdr", ShaderSourceType.Binary)) + { + Log.Info("Color grading shader replaced."); + } + } + + /* + if (hash == "0c3dacbd-32c175d5-10d80d04-cce7e689") + { + if (replaceShaderFromFile(info, $"{shaderPath}/alpha_as_luma.hlsl", ShaderSourceType.HLSL)) + { + Log.Info("Alpha as luma shader replaced."); + } + } + */ + /* + else if (hash == "8cf2a107-ecde214b-9939b350-7b2af1a7") + { + if (replaceShaderFromFile(info, $"{shaderPath}/cube_only.shdr", ShaderSourceType.Binary)) + { + Log.Info("Cube Only shader replaced."); + } + } + */ + /* + else if (hash == "18a797dc-9458d333-59e6dff0-9790fcea") + { + if (replaceShaderFromFile(info, $"{shaderPath}/sssss.shdr", ShaderSourceType.Binary)) + { + Log.Info("SSSSS shader replaced."); + } + } + */ } #endif } -- cgit v1.2.3-101-g0448