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 --- Config.cs | 63 +- LUT.cs | 106 +-- Lights.cs | 216 +++--- Plugin.cs | 1181 +++++++++++++++++++------------ Shaders/color_grading_add_uchimura.diff | 41 ++ 5 files changed, 1009 insertions(+), 598 deletions(-) create mode 100644 Shaders/color_grading_add_uchimura.diff diff --git a/Config.cs b/Config.cs index 70419df..3f9d6ec 100644 --- a/Config.cs +++ b/Config.cs @@ -51,7 +51,7 @@ namespace WorldTuningTool public class Config : IConfig { public String Name => "WorldTuningTool"; - public String Version => "0.9.4"; + public String Version => "1.0"; public static string StageToString(StageExt stage) { @@ -183,15 +183,76 @@ namespace WorldTuningTool { #if SHADER_FEATURES public bool FullResolutionSSLR { get; set; } = false; + public bool VolumeUpsampleNoLinear { get; set; } = false; + public bool FXAAMaxQualityPreset { get; set; } = false; + public bool SkinAllowNegativeWetness { get; set; } = false; #endif public bool FullResolutionVolumeBlur { get; set; } = false; public bool HigherThanHighestVolumeRendering { get; set; } = false; public bool DisableLODLimits { get; set; } = false; + public bool CharacterCreatorFaceRendering { get; set; } = false; public bool LargerFoliageSwayRange { get; set; } = false; public bool DisableReducedRateAnimations { get; set; } = false; public PatchConfig() {} } + public static Dictionary OldParameterNames = new Dictionary() + { + { "Sunlight Group", "Primary Light Group" }, + { "Sunlight Direction", "Primary Light Direction" }, + { "Sunlight Color", "Primary Light Color" }, + { "Sunlight Intensity", "Primary Light Intensity" }, + { "Sunlight Is Primary", "Primary Light Is Primary" }, + { "Projection Scale", "Primary Light Projection Scale" }, + { "Projection Offset Speed", "Primary Light Projection Offset Speed" }, + { "Projection Up", "Primary Light Projection Up" }, + { "Do Volumetric", "Primary Light Do Volumetric" }, + { "Shadow Cast", "Primary Shadow Cast" }, + { "Shadow Map Size", "Primary Shadow Map Size" }, + { "Shadow Near Clip Distance", "Primary Shadow Near Clip Distance" }, + { "Shadow Cascade Mode", "Primary Shadow Cascade Mode" }, + { "Shadow Cascade 2Way Bias", "Primary Shadow Cascade 2Way Bias" }, + { "Shadow Distance", "Primary Shadow Cascade Distance" }, + { "Shadow Backforward Distance", "Primary Shadow Cascade Backforward Distance" }, + { "Shadow Is Fixed Fov Mode", "Primary Shadow Is Fixed Fov Mode" }, + { "Shadow Fov", "Primary Shadow Fov" }, + { "Shadow Is Discretization Fov Mode", "Primary Shadow Is Discretization Fov Mode" }, + { "Shadow Discretization Angle", "Primary Shadow Discretization Angle" }, + { "Shadow Distribution", "Primary Shadow Cascade Distribution" }, + { "Cascade Manual Split", "Primary Shadow Cascade Manual Split" }, + { "Cascade Manual Split Distance[0]", "Primary Shadow Cascade Manual Split Distance[0]" }, + { "Cascade Manual Split Distance[1]", "Primary Shadow Cascade Manual Split Distance[1]" }, + { "Cascade Manual Split Distance[2]", "Primary Shadow Cascade Manual Split Distance[2]" }, + { "Shadow Sloped Depth Bias", "Primary Shadow Sloped Depth Bias" }, + { "Shadow Depth Bias", "Primary Shadow Depth Bias" }, + { "Shadow Max Depth Bias", "Primary Shadow Max Depth Bias" }, + { "Cascade Individual Shadow Bias", "Primary Shadow Cascade Individual Shadow Bias" }, + { "Cascade Depth Bias[0]", "Primary Shadow Cascade Depth Bias[0]" }, + { "Cascade Sloped Depth Bias[0]", "Primary Shadow Cascade Sloped Depth Bias[0]" }, + { "Cascade Max Depth Bias[0]", "Primary Shadow Cascade Max Depth Bias[0]" }, + { "Cascade Depth Bias[1]", "Primary Shadow Cascade Depth Bias[1]" }, + { "Cascade Sloped Depth Bias[1]", "Primary Shadow Cascade Sloped Depth Bias[1]" }, + { "Cascade Max Depth Bias[1]", "Primary Shadow Cascade Max Depth Bias[1]" }, + { "Cascade Depth Bias[2]", "Primary Shadow Cascade Depth Bias[2]" }, + { "Cascade Sloped Depth Bias[2]", "Primary Shadow Cascade Sloped Depth Bias[2]" }, + { "Cascade Max Depth Bias[2]", "Primary Shadow Cascade Max Depth Bias[2]" }, + { "Light Tone Map Type", "Tone Map Type" }, + { "Light Compute Luminance", "Tone Map Compute Luminance" }, + { "Light Luminance Version", "Tone Map Luminance Version" }, + { "Light Shoulder Strength", "Tone Map Shoulder Strength" }, + { "Light Linear Strength", "Tone Map Linear Strength" }, + { "Light Linear Angle", "Tone Map Linear Angle" }, + { "Light Toe Strength", "Tone Map Toe Strength" }, + { "Light Toe Num", "Tone Map Toe Num" }, + { "Light Toe Denum", "Tone Map Toe Denum" }, + { "Light White Point", "Tone Map White Point" }, + { "Light LUT Blend", "Color Grading LUT Blend" }, + { "Light Vfx LUT Blend", "Color Grading Vfx LUT Blend" }, + { "Light Enable Color Grading", "Color Grading Enable" }, + { "Light Is Linear To PQ", "Color Grading Is Linear To PQ" }, + { "Light Is PQ To Linear", "Color Grading Is PQ To Linear" } + }; + public bool DisableLightsFeature { get; set; } = false; public PatchConfig Patches { get; set; } = new PatchConfig(); diff --git a/LUT.cs b/LUT.cs index a8db19d..1018745 100644 --- a/LUT.cs +++ b/LUT.cs @@ -6,47 +6,57 @@ using System.Runtime.InteropServices; using ImGuiNET; using SharpPluginLoader.Core.Memory; +using SharpPluginLoader.Core.IO; #if TEXTURE_FEATURE using SharpPluginLoader.Core.Resources; -using SharpPluginLoader.Core.IO; #endif namespace WorldTuningTool { using static Plugin; - public class LUT + public static class WorldLUTs { private const string addPath = "nativePC/plugins/CSharp/LUT"; - public LUT() { } + private static string[] builtinList = { + "native:\\light\\LUT\\CC_effect_type00_LUTM.tex", + "native:\\light\\LUT\\CC_event_A_type00_LUTM.tex", + "native:\\light\\LUT\\CC_event_B_type00_LUTM.tex", + "native:\\light\\LUT\\CC_event_darkB_type10_LUTM.tex", + "native:\\light\\LUT\\CC_event_darkG_type10_LUTM.tex", + "native:\\light\\LUT\\CC_event_darkR_type10_LUTM.tex", + "native:\\light\\LUT\\CC_event_dark_type00_LUTM.tex", + "native:\\light\\LUT\\CC_event_dark_type10_LUTM.tex", + "native:\\light\\LUT\\CC_event_evc0001_type00_LUTM.tex", + "native:\\light\\LUT\\CC_globalbase_LUTM.tex", + "native:\\light\\LUT\\CC_globalbaseSATU_LUTM.tex", + "native:\\light\\LUT\\CC_globalbase_stage_LUTM.tex", + "native:\\light\\LUT\\CC_st101day_global_type00_LUTM.tex", + "native:\\light\\LUT\\CC_st101day_global_type10_LUTM.tex", + "native:\\light\\LUT\\CC_st104day_global_type00_LUTM.tex", + "native:\\light\\LUT\\CC_st105day_global_type00_LUTM.tex", + "native:\\light\\LUT\\CC_title_st101d_type00_LUTM.tex", + "native:\\light\\LUT\\CC_title_st102d_type00_LUTM.tex", + "native:\\light\\LUT\\CC_title_st103d_type00_LUTM.tex", + "native:\\light\\LUT\\CC_title_st104d_type00_LUTM.tex", + "native:\\light\\LUT\\CC_title_st105d_type00_LUTM.tex" + }; // https://github.com/AsteriskAmpersand/CrappyLUTStudio--CLUTS-/blob/5af10daaa5f295b106cc5db09530a6fe5a4320d4/LUT.py#L35 - private byte[]? parseWorldLUT(BinaryReader reader) + private static byte[]? parseWorldLUT(BinaryReader reader) { byte[] signature = reader.ReadBytes(4); - if (!(signature[0] == 0x54 && signature[1] == 0x45 && - (signature[2] == 0x58 && signature[3] == 0x0))) + if (!(signature[0] == 0x54 && signature[1] == 0x45 && signature[2] == 0x58 && signature[3] == 0x0)) { return null; } - ulong version = reader.ReadUInt64(); - uint datablock = reader.ReadUInt32(); - uint format = reader.ReadUInt32(); - uint mipCount = reader.ReadUInt32(); + byte[] skip = reader.ReadBytes(20); uint width = reader.ReadUInt32(); uint height = reader.ReadUInt32(); - uint mipListCount = reader.ReadUInt32(); - uint typeData = reader.ReadUInt32(); + skip = reader.ReadBytes(8); uint depth = reader.ReadUInt32(); - byte[] NULL0 = reader.ReadBytes(12); - int NEG0 = reader.ReadInt32(); - byte[] NULL1 = reader.ReadBytes(8); - int Special = reader.ReadInt32(); - byte[] NULL2 = reader.ReadBytes(16); - byte[] NEG1 = reader.ReadBytes(32); - byte[] flags = reader.ReadBytes(32); - byte[] NULLX = reader.ReadBytes(32); + skip = reader.ReadBytes(140); reader.BaseStream.Position = (long)reader.ReadUInt64(); if (!(width == 32 && height == 32 && depth == 32)) { @@ -57,7 +67,7 @@ namespace WorldTuningTool // https://drive.google.com/file/d/143Eh08ZYncCAMwJ1q4gWxVOqR_OSWYvs/view // When does DOMAIN_MIN/MAX apply? - private byte[]? parseCubeLUT(StreamReader reader) + private static byte[]? parseCubeLUT(StreamReader reader) { string? line; Vector3[]? parsed = null; @@ -118,7 +128,7 @@ namespace WorldTuningTool return data; } - private unsafe bool overwriteFromStream(nint texture, Stream stream, bool cube = false) + private static unsafe bool overwriteFromStream(nint texture, Stream stream, bool cube = false) { byte[]? data = null; if (cube) @@ -150,7 +160,7 @@ namespace WorldTuningTool #endif } - private unsafe bool overwriteFromFile(nint texture, string path) + private static unsafe bool overwriteFromFile(nint texture, string path) { string ext = path.Split('.').Last().ToLower(); using (FileStream stream = File.Open(path, FileMode.Open)) @@ -159,17 +169,29 @@ namespace WorldTuningTool } } - private void reloadBlendLUT(nint lightingObject) + private static unsafe bool overwriteFromMtFile(nint texture, string path) + { + MtFileStream? file = MtFileStream.FromPath(path, OpenMode.Read, false); + bool success = false; + if (file != null) + { + success = overwriteFromStream(texture, new MemoryStream(file.Read(file.Length))); + file.Close(); + } + return success; + } + + private static void reloadBlendLUT(nint lightingObject) { MemoryUtil.GetRef(lightingObject + 0x1D4) = MemoryUtil.GetRef(lightingObject + 0x1D0) + 1.0f; } - private string[] fileList = []; + private static string[] fileList = []; private static string[] selectedFile = [ "", "" ]; private static bool[] selectionStarted = [ false, false ]; private static bool[] selectedInvalid = [ false, false ]; - public void DrawUI(nint texture, nint lightingObject, int i, float width) + public static void DrawUI(nint texture, nint lightingObject, int i, float width) { ImGui.PushID(i); string lutPath = Marshal.PtrToStringAnsi(texture + 0xC)!; @@ -177,14 +199,9 @@ namespace WorldTuningTool #if TEXTURE_FEATURE if (ImGui.Button("Reset")) { - MtFileStream? file = MtFileStream.FromPath($"native:\\{lutPath}.tex", OpenMode.Read, false); - if (file != null) + if (overwriteFromMtFile(texture, $"native:\\{lutPath}.tex")) { - if (overwriteFromStream(texture, new MemoryStream(file.Read(file.Length)))) - { - reloadBlendLUT(lightingObject); - } - file.Close(); + reloadBlendLUT(lightingObject); } selectedFile[i] = ""; selectedInvalid[i] = false; @@ -196,11 +213,24 @@ namespace WorldTuningTool { ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF); } - if (ImGui.BeginCombo("##LUT Files", selectedFile[i], ImGuiComboFlags.HeightLarge)) + bool beginCombo = ImGui.BeginCombo("##LUT Files", selectedFile[i], ImGuiComboFlags.HeightLarge); + if (prevWasInvalid) { - if (prevWasInvalid) + ImGui.PopStyleColor(); + } + if (beginCombo) + { + foreach (string nativePath in builtinList) { - ImGui.PopStyleColor(); + bool isSelected = selectedFile[i] == nativePath; + if (ImGui.Selectable(nativePath, isSelected)) + { + selectedFile[i] = nativePath; + if (overwriteFromMtFile(texture, nativePath)) + { + reloadBlendLUT(lightingObject); + } + } } if (!selectionStarted[i]) { @@ -224,10 +254,6 @@ namespace WorldTuningTool } else { - if (prevWasInvalid) - { - ImGui.PopStyleColor(); - } selectionStarted[i] = false; } #endif diff --git a/Lights.cs b/Lights.cs index fd072e2..baca819 100644 --- a/Lights.cs +++ b/Lights.cs @@ -11,10 +11,8 @@ namespace WorldTuningTool { using static Plugin; - public class Lights + public static class Lights { - public Lights() { } - private class BaseLight { public nint Object = 0x0; @@ -497,89 +495,66 @@ namespace WorldTuningTool private delegate nint CreateMhObjectLight(); private delegate nint CreateMhObjectLight2(nint unknownPtr); private delegate nint DestroyMhObjectLight(nint mhObjectLightInternal, int unknownInt); - private Hook? createMhObjectLight; - private Hook? createMhObjectLight2; - private Hook? destroyMhObjectLight; + private static Hook? createMhObjectLight; + private static Hook? createMhObjectLight2; + private static Hook? destroyMhObjectLight; private delegate nint CreateLlkObjectLight(); private delegate nint CreateLlkObjectLight2(nint unknownPtr); private delegate nint DestroyLlkObjectLight(nint llkObjectLightInternal, int unknownInt); - private Hook? createLlkObjectLight; - private Hook? createLlkObjectLight2; - private Hook? destroyLlkObjectLight; + private static Hook? createLlkObjectLight; + private static Hook? createLlkObjectLight2; + private static Hook? destroyLlkObjectLight; #endif private delegate nint CreateLightObject(nint lightObject); private delegate nint DestroyLightObject(nint lightObjectInternal, int unknownInt); - private Hook? createLightObject; - private static Dictionary> lightTypes = new Dictionary>() + private static Hook? createLightObject; + private static Dictionary> lightTypes = new Dictionary>() { - { lton(0x143514168), (x) => new uLight(x) }, - { lton(0x143514288), (x) => new uInfiniteLight(x) }, - { lton(0x1434994D0), (x) => new uMhInfiniteLight(x) }, - { lton(0x1434954F0), (x) => new uMhActorInfiniteLight(x) }, - { lton(0x143494150), (x) => new uLlkInfiniteLight(x) }, - { lton(0x1434936A0), (x) => new uLlkActorInfiniteLight(x) }, - { lton(0x143493E30), (x) => new uLlkFollowCameraInfiniteLight(x) }, - { lton(0x1435143A8), (x) => new uPointLight(x) }, - { lton(0x14349A6C8), (x) => new uMhPointLight(x) }, - { lton(0x1434952B0), (x) => new uMhActorPointLight(x) }, - { lton(0x1434944E8), (x) => new uLlkPointLight(x) }, - { lton(0x143493460), (x) => new uLlkActorPointLight(x) }, - { lton(0x143493BF0), (x) => new uLlkFollowCameraPointLight(x) }, - { lton(0x1435144C8), (x) => new uSpotLight(x) }, - { lton(0x14349E280), (x) => new uMhSpotLight(x) }, - { lton(0x1434953D0), (x) => new uMhActorSpotLight(x) }, - { lton(0x143494888), (x) => new uLlkSpotLight(x) }, - { lton(0x143493580), (x) => new uLlkActorSpotLight(x) }, - { lton(0x1434937C0), (x) => new uLlkNullAngleSpotLight(x) }, - { lton(0x143493D10), (x) => new uLlkFollowCameraSpotLight(x) }, - { lton(0x1435145E8), (x) => new uHemiSphereLight(x) }, - { lton(0x143499378), (x) => new uMhHemiSphereLight(x) }, - { lton(0x143493F98), (x) => new uLlkHemiSphereLight(x) } - + { 0x143514168, (x) => new uLight(x) }, + { 0x143514288, (x) => new uInfiniteLight(x) }, + { 0x1434994D0, (x) => new uMhInfiniteLight(x) }, + { 0x1434954F0, (x) => new uMhActorInfiniteLight(x) }, + { 0x143494150, (x) => new uLlkInfiniteLight(x) }, + { 0x1434936A0, (x) => new uLlkActorInfiniteLight(x) }, + { 0x143493E30, (x) => new uLlkFollowCameraInfiniteLight(x) }, + { 0x1435143A8, (x) => new uPointLight(x) }, + { 0x14349A6C8, (x) => new uMhPointLight(x) }, + { 0x1434952B0, (x) => new uMhActorPointLight(x) }, + { 0x1434944E8, (x) => new uLlkPointLight(x) }, + { 0x143493460, (x) => new uLlkActorPointLight(x) }, + { 0x143493BF0, (x) => new uLlkFollowCameraPointLight(x) }, + { 0x1435144C8, (x) => new uSpotLight(x) }, + { 0x14349E280, (x) => new uMhSpotLight(x) }, + { 0x1434953D0, (x) => new uMhActorSpotLight(x) }, + { 0x143494888, (x) => new uLlkSpotLight(x) }, + { 0x143493580, (x) => new uLlkActorSpotLight(x) }, + { 0x1434937C0, (x) => new uLlkNullAngleSpotLight(x) }, + { 0x143493D10, (x) => new uLlkFollowCameraSpotLight(x) }, + { 0x1435145E8, (x) => new uHemiSphereLight(x) }, + { 0x143499378, (x) => new uMhHemiSphereLight(x) }, + { 0x143493F98, (x) => new uLlkHemiSphereLight(x) } }; - private static nint[] lightObjectDestructors = { - lton(0x142311FF0), // # uLight - lton(0x142311F40), // # uInfiniteLight - lton(0x141FB8F50), // # uMhInfiniteLight - lton(0x141F91DE0), // # uMhActorInfiniteLight - lton(0x141F855A0), // # uLlkInfiniteLight - lton(0x141F81940), // # uLlkActorInfiniteLight - lton(0x141F83B00), // # uLlkFollowCameraInfiniteLight - lton(0x142312070), // # uPointLight - lton(0x141FC0950), // # uMhPointLight - lton(0x141F91E80), // # uMhActorPointLight - lton(0x141F87D90), // # uLlkPointLight - lton(0x141F819B0), // # uLlkActorPointLight - lton(0x141F83B70), // # uLlkFollowCameraPointLight - lton(0x1423120F0), // # uSpotLight - lton(0x141FDE0D0), // # uMhSpotLight - lton(0x141F91F20), // # uMhActorSpotLight - lton(0x141F8B390), // # uLlkSpotLight - lton(0x141F81A20), // # uLlkActorSpotLight - lton(0x141F81A90), // # uLlkNullAngleSpotLight - lton(0x141F83BE0), // # uLlkFollowCameraSpotLight - lton(0x142311EC0), // # uHemiSphereLight - lton(0x141FB8C20), // # uMhHemiSphereLight - lton(0x141F84A40) // # uLlkHemiSphereLight - }; - private Hook[] lightObjectDestructorHooks = new Hook[lightObjectDestructors.Length]; + private static Hook[] lightObjectDestructorHooks = new Hook[lightTypes.Count()]; - private List newLights = new List(); - private List sceneLights = new List(); - private bool sortByDistanceToPlayerPoint = false; - private bool sortByDistanceToPlayerSpot = false; + private static List newLights = new List(); + private static List sceneLights = new List(); + private static bool sortByDistanceToPlayerPoint = false; + private static bool sortByDistanceToPlayerSpot = false; - private NativeAction addToScene; - private NativeAction removeFromScene; - private List ourLights = new List(); + private static NativeFunction newPointLight; + private static NativeFunction newSpotLight; + private static NativeFunction newHemiSphereLight; + private static NativeAction addToScene; + private static NativeAction removeFromScene; + private static List ourLights = new List(); #if HOOK_OBJECT_LIGHTS - private List objectLights = new List(); + private static List objectLights = new List(); #endif - public void Initialize() + public static void Initialize() { createLightObject = Hook.Create(0x142311420, CreateLightObjectHook); DestroyLightObject[] destructorHookFuncs = { @@ -607,26 +582,29 @@ namespace WorldTuningTool DestroyLightObjectHook21, DestroyLightObjectHook22 }; - for (int i = 0; i < lightObjectDestructors.Length; i++) + for (int i = 0; i < lightTypes.Count(); i++) // Not ordered. { - lightObjectDestructorHooks[i] = Hook.Create(lightObjectDestructors[i], destructorHookFuncs[i]); + nint destructor = MemoryUtil.Read(lightTypes.Keys.ElementAt(i)); + lightObjectDestructorHooks[i] = Hook.Create(destructor, destructorHookFuncs[i]); } #if HOOK_OBJECT_LIGHTS createMhObjectLight = Hook.Create(0x141FBF290, CreateMhObjectLightHook); createMhObjectLight2 = Hook.Create(0x141FBF500, CreateMhObjectLight2Hook); destroyMhObjectLight = Hook.Create(0x141FBF6B0, DestroyMhObjectLightHook); - createLlkObjectLight = Hook.Create(0x141F85DF0, CreateLlkObjectLightHook); createLlkObjectLight2 = Hook.Create(0x141F86090, CreateLlkObjectLight2Hook); destroyLlkObjectLight = Hook.Create(0x141F86270, DestroyLlkObjectLightHook); #endif + newPointLight = new NativeFunction(0x141FC0780); + newSpotLight = new NativeFunction(0x141FDDF00); + newHemiSphereLight = new NativeFunction(0x141FB8A50); addToScene = new NativeAction(0x142219070); removeFromScene = new NativeAction(0x142228F10); } - public void PostUpdateLightLinker() + public static void PostUpdateLightLinker() { foreach (uLight light in sceneLights) { @@ -637,8 +615,10 @@ namespace WorldTuningTool } } - public void OnUpdate() + public static void OnUpdate() { + // @TODO: Safe to check newLights.Count > 0? + // Apparently that read would be guaranteed atomic in c#. lock (newLights) { for (int i = newLights.Count - 1; i >= 0; i--) @@ -648,7 +628,7 @@ namespace WorldTuningTool nint vTable = MemoryUtil.Read(light.Object); if (lightTypes.ContainsKey(vTable)) { - if (vTable == lton(0x143514168)) + if (vTable == 0x143514168) { Log.Error("Light is still uLight OnUpdate()."); } @@ -662,7 +642,7 @@ namespace WorldTuningTool } } - private nint CreateLightObjectHook(nint lightObject) + private static nint CreateLightObjectHook(nint lightObject) { lightObject = createLightObject!.Original(lightObject); uLight light = new uLight(lightObject); @@ -673,7 +653,7 @@ namespace WorldTuningTool return lightObject; } - private void cleanupCommon(nint lightObject) + private static void cleanupCommon(nint lightObject) { for (int i = 0; i < sceneLights.Count; i++) { @@ -707,138 +687,138 @@ namespace WorldTuningTool } } - private nint DestroyLightObjectHook0(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook0(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[0]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook1(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook1(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[1]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook2(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook2(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[2]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook3(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook3(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[3]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook4(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook4(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[4]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook5(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook5(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[5]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook6(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook6(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[6]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook7(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook7(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[7]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook8(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook8(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[8]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook9(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook9(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[9]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook10(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook10(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[10]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook11(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook11(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[11]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook12(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook12(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[12]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook13(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook13(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[13]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook14(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook14(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[14]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook15(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook15(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[15]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook16(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook16(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[16]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook17(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook17(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[17]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook18(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook18(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[18]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook19(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook19(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[19]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook20(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook20(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[20]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook21(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook21(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[21]!.Original(lightObject, unknownInt); } - private nint DestroyLightObjectHook22(nint lightObject, int unknownInt) + private static nint DestroyLightObjectHook22(nint lightObject, int unknownInt) { Assert(unknownInt == 1); cleanupCommon(lightObject); return lightObjectDestructorHooks[22]!.Original(lightObject, unknownInt); } #if HOOK_OBJECT_LIGHTS - private nint CreateMhObjectLightHook() + private static nint CreateMhObjectLightHook() { nint objectLight = createMhObjectLight!.Original(); objectLights.Add(new uMhObjectLight(objectLight)); return objectLight; } - private nint CreateMhObjectLight2Hook(nint unknownPtr) + private static nint CreateMhObjectLight2Hook(nint unknownPtr) { nint objectLight = createMhObjectLight2!.Original(unknownPtr); objectLights.Add(new uMhObjectLight(objectLight)); return objectLight; } - private nint DestroyMhObjectLightHook(nint mhObjectLightInternal, int unknownInt) + private static nint DestroyMhObjectLightHook(nint mhObjectLightInternal, int unknownInt) { Assert(unknownInt == 1); for (int i = 0; i < objectLights.Count; i++) @@ -853,21 +833,21 @@ namespace WorldTuningTool return destroyMhObjectLight!.Original(mhObjectLightInternal, unknownInt); } - private nint CreateLlkObjectLightHook() + private static nint CreateLlkObjectLightHook() { nint objectLight = createLlkObjectLight!.Original(); objectLights.Add(new uLlkObjectLight(objectLight)); return objectLight; } - private nint CreateLlkObjectLight2Hook(nint unknownPtr) + private static nint CreateLlkObjectLight2Hook(nint unknownPtr) { nint objectLight = createLlkObjectLight2!.Original(unknownPtr); objectLights.Add(new uLlkObjectLight(objectLight)); return objectLight; } - private nint DestroyLlkObjectLightHook(nint llkObjectLightInternal, int unknownInt) + private static nint DestroyLlkObjectLightHook(nint llkObjectLightInternal, int unknownInt) { Assert(unknownInt == 1); for (int i = 0; i < objectLights.Count; i++) @@ -883,7 +863,7 @@ namespace WorldTuningTool } #endif - private void DrawLights(IEnumerable lights, float width) + private static void DrawLights(IEnumerable lights, float width) { bool disableAll = ImGui.Button("Disable All"); if (ImGui.BeginItemTooltip()) @@ -964,26 +944,26 @@ namespace WorldTuningTool } } - public unsafe void DrawUI(float width) + public static unsafe void DrawUI(float width) { int lightType = -1; nint lightObject = 0x0; if (ImGui.Button("New Point Light")) { lightType = 2; - lightObject = new NativeFunction(0x141FC0780).Invoke(); + lightObject = newPointLight.Invoke(); } ImGui.SameLine(); if (ImGui.Button("New Spot Light")) { lightType = 3; - lightObject = new NativeFunction(0x141FDDF00).Invoke(); + lightObject = newSpotLight.Invoke(); } ImGui.SameLine(); if (ImGui.Button("New Hemi Sphere Light")) { lightType = 4; - lightObject = new NativeFunction(0x141FB8A50).Invoke(); + lightObject = newHemiSphereLight.Invoke(); } bool lightTook = false; lock (newLights) @@ -1051,7 +1031,7 @@ namespace WorldTuningTool ImGui.PushID("Infinite"); if (ImGui.CollapsingHeader("Infinite")) { - DrawLights(sceneLights.Where(x => (x.Type == 1)), width); + DrawLights(sceneLights.Where((x) => x.Type == 1), width); ImGui.Separator(); } ImGui.PopID(); @@ -1065,7 +1045,7 @@ namespace WorldTuningTool Vector3 pos = default; Player? player = Player.MainPlayer; if (player != null) pos = player.Position; - DrawLights(Enumerable.OrderBy(sceneLights.Where(x => (x.Type == 2)), x => x, Comparer.Create((x, y) => + DrawLights(Enumerable.OrderBy(sceneLights.Where((x) => x.Type == 2), (x) => x, Comparer.Create((x, y) => { Vector3 xPos = ((uPointLight)x).Position; if (((uPointLight)x).Parent != 0x0) @@ -1086,7 +1066,7 @@ namespace WorldTuningTool } else { - DrawLights(sceneLights.Where(x => (x.Type == 2)), width); + DrawLights(sceneLights.Where((x) => x.Type == 2), width); } ImGui.Separator(); } @@ -1101,7 +1081,7 @@ namespace WorldTuningTool Vector3 pos = default; Player? player = Player.MainPlayer; if (player != null) pos = player.Position; - DrawLights(Enumerable.OrderBy(sceneLights.Where(x => (x.Type == 3)), x => x, Comparer.Create((x, y) => + DrawLights(Enumerable.OrderBy(sceneLights.Where((x) => x.Type == 3), (x) => x, Comparer.Create((x, y) => { Vector3 xPos = ((uSpotLight)x).Position; if (((uSpotLight)x).Parent != 0x0) @@ -1122,7 +1102,7 @@ namespace WorldTuningTool } else { - DrawLights(sceneLights.Where(x => (x.Type == 3)), width); + DrawLights(sceneLights.Where((x) => x.Type == 3), width); } ImGui.Separator(); } @@ -1130,7 +1110,7 @@ namespace WorldTuningTool ImGui.PushID("HemiSphere"); if (ImGui.CollapsingHeader("Hemi Sphere")) { - DrawLights(sceneLights.Where(x => (x.Type == 4)), width); + DrawLights(sceneLights.Where((x) => x.Type == 4), width); ImGui.Separator(); } ImGui.PopID(); 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 } diff --git a/Shaders/color_grading_add_uchimura.diff b/Shaders/color_grading_add_uchimura.diff new file mode 100644 index 0000000..aa44115 --- /dev/null +++ b/Shaders/color_grading_add_uchimura.diff @@ -0,0 +1,41 @@ +--- a/color_grading.asm 2026-10-07 20:38:52.515256500 -0400 ++++ b/color_grading.asm 2026-10-07 23:37:24.393674847 -0400 +@@ -148,6 +148,30 @@ + add r1.xyz, r1.xyzx, -cb3[1].yyyy + mul r0.xyz, r1.xyzx, cb3[1].xxxx + else ++ ieq r1.x, cb3[0].x, l(7) ++ if_nz r1.x ++ mul r1.xyz, r0.xyzx, l(4.545455, 4.545455, 4.545455, 0.000000) ++ mov_sat r2.xyz, r1.xyzx ++ mad r3.xyz, r2.xyzx, l(-2.000000, -2.000000, -2.000000, 0.000000), l(3.000000, 3.000000, 3.000000, 0.000000) ++ mul r2.xyz, r2.xyzx, r2.xyzx ++ mad r2.xyz, -r3.xyzx, r2.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) ++ ge r3.xyz, r0.xyzx, l(0.532000, 0.532000, 0.532000, 0.000000) ++ and r4.xyz, r3.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) ++ add r5.xyz, -r2.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000) ++ movc r3.xyz, r3.xyzx, l(-1.000000, -1.000000, -1.000000, 0.000000), l(0x80000000, 0x80000000, 0x80000000, 0) ++ add r3.xyz, r3.xyzx, r5.xyzx ++ log r1.xyz, r1.xyzx ++ mul r1.xyz, r1.xyzx, l(1.330000, 1.330000, 1.330000, 0.000000) ++ exp r1.xyz, r1.xyzx ++ mul r1.xyz, r1.xyzx, r2.xyzx ++ add r2.xyz, r0.xyzx, l(-0.532000, -0.532000, -0.532000, 0.000000) ++ mul r2.xyz, r2.xyzx, l(-3.082682, -3.082682, -3.082682, 0.000000) ++ exp r2.xyz, r2.xyzx ++ mad r2.xyz, -r2.xyzx, l(0.468000, 0.468000, 0.468000, 0.000000), l(1.000000, 1.000000, 1.000000, 0.000000) ++ mul r3.xyz, r0.xyzx, r3.xyzx ++ mad r1.xyz, r1.xyzx, l(0.220000, 0.220000, 0.220000, 0.000000), r3.xyzx ++ mad r0.xyz, r2.xyzx, r4.xyzx, r1.xyzx ++ else + if_nz cb3[0].y + dp3 r1.x, r0.xyzx, l(0.299010, 0.587000, 0.114000, 0.000000) + switch cb3[0].x +@@ -204,6 +228,7 @@ + break + endswitch + endif ++ endif + endif + endif + ine r1.x, cb2[3].x, l(0) -- cgit v1.2.3-101-g0448