summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Config.cs63
-rw-r--r--LUT.cs106
-rw-r--r--Lights.cs216
-rw-r--r--Plugin.cs1181
-rw-r--r--Shaders/color_grading_add_uchimura.diff41
5 files changed, 1009 insertions, 598 deletions
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<string, string> OldParameterNames = new Dictionary<string, string>()
+ {
+ { "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<float>(lightingObject + 0x1D4) = MemoryUtil.GetRef<float>(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>? createMhObjectLight;
- private Hook<CreateMhObjectLight2>? createMhObjectLight2;
- private Hook<DestroyMhObjectLight>? destroyMhObjectLight;
+ private static Hook<CreateMhObjectLight>? createMhObjectLight;
+ private static Hook<CreateMhObjectLight2>? createMhObjectLight2;
+ private static Hook<DestroyMhObjectLight>? destroyMhObjectLight;
private delegate nint CreateLlkObjectLight();
private delegate nint CreateLlkObjectLight2(nint unknownPtr);
private delegate nint DestroyLlkObjectLight(nint llkObjectLightInternal, int unknownInt);
- private Hook<CreateLlkObjectLight>? createLlkObjectLight;
- private Hook<CreateLlkObjectLight2>? createLlkObjectLight2;
- private Hook<DestroyLlkObjectLight>? destroyLlkObjectLight;
+ private static Hook<CreateLlkObjectLight>? createLlkObjectLight;
+ private static Hook<CreateLlkObjectLight2>? createLlkObjectLight2;
+ private static Hook<DestroyLlkObjectLight>? destroyLlkObjectLight;
#endif
private delegate nint CreateLightObject(nint lightObject);
private delegate nint DestroyLightObject(nint lightObjectInternal, int unknownInt);
- private Hook<CreateLightObject>? createLightObject;
- private static Dictionary<nint, Func<nint, uLight>> lightTypes = new Dictionary<nint, Func<nint, uLight>>()
+ private static Hook<CreateLightObject>? createLightObject;
+ private static Dictionary<long, Func<nint, uLight>> lightTypes = new Dictionary<long, Func<nint, uLight>>()
{
- { 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<DestroyLightObject>[] lightObjectDestructorHooks = new Hook<DestroyLightObject>[lightObjectDestructors.Length];
+ private static Hook<DestroyLightObject>[] lightObjectDestructorHooks = new Hook<DestroyLightObject>[lightTypes.Count()];
- private List<uLight> newLights = new List<uLight>();
- private List<uLight> sceneLights = new List<uLight>();
- private bool sortByDistanceToPlayerPoint = false;
- private bool sortByDistanceToPlayerSpot = false;
+ private static List<uLight> newLights = new List<uLight>();
+ private static List<uLight> sceneLights = new List<uLight>();
+ private static bool sortByDistanceToPlayerPoint = false;
+ private static bool sortByDistanceToPlayerSpot = false;
- private NativeAction<nint, int, nint, int> addToScene;
- private NativeAction<nint> removeFromScene;
- private List<uLight> ourLights = new List<uLight>();
+ private static NativeFunction<nint> newPointLight;
+ private static NativeFunction<nint> newSpotLight;
+ private static NativeFunction<nint> newHemiSphereLight;
+ private static NativeAction<nint, int, nint, int> addToScene;
+ private static NativeAction<nint> removeFromScene;
+ private static List<uLight> ourLights = new List<uLight>();
#if HOOK_OBJECT_LIGHTS
- private List<BaseLight> objectLights = new List<BaseLight>();
+ private static List<BaseLight> objectLights = new List<BaseLight>();
#endif
- public void Initialize()
+ public static void Initialize()
{
createLightObject = Hook.Create<CreateLightObject>(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<DestroyLightObject>(lightObjectDestructors[i], destructorHookFuncs[i]);
+ nint destructor = MemoryUtil.Read<nint>(lightTypes.Keys.ElementAt(i));
+ lightObjectDestructorHooks[i] = Hook.Create<DestroyLightObject>(destructor, destructorHookFuncs[i]);
}
#if HOOK_OBJECT_LIGHTS
createMhObjectLight = Hook.Create<CreateMhObjectLight>(0x141FBF290, CreateMhObjectLightHook);
createMhObjectLight2 = Hook.Create<CreateMhObjectLight2>(0x141FBF500, CreateMhObjectLight2Hook);
destroyMhObjectLight = Hook.Create<DestroyMhObjectLight>(0x141FBF6B0, DestroyMhObjectLightHook);
-
createLlkObjectLight = Hook.Create<CreateLlkObjectLight>(0x141F85DF0, CreateLlkObjectLightHook);
createLlkObjectLight2 = Hook.Create<CreateLlkObjectLight2>(0x141F86090, CreateLlkObjectLight2Hook);
destroyLlkObjectLight = Hook.Create<DestroyLlkObjectLight>(0x141F86270, DestroyLlkObjectLightHook);
#endif
+ newPointLight = new NativeFunction<nint>(0x141FC0780);
+ newSpotLight = new NativeFunction<nint>(0x141FDDF00);
+ newHemiSphereLight = new NativeFunction<nint>(0x141FB8A50);
addToScene = new NativeAction<nint, int, nint, int>(0x142219070);
removeFromScene = new NativeAction<nint>(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<nint>(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<BaseLight> lights, float width)
+ private static void DrawLights(IEnumerable<BaseLight> 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<nint>(0x141FC0780).Invoke();
+ lightObject = newPointLight.Invoke();
}
ImGui.SameLine();
if (ImGui.Button("New Spot Light"))
{
lightType = 3;
- lightObject = new NativeFunction<nint>(0x141FDDF00).Invoke();
+ lightObject = newSpotLight.Invoke();
}
ImGui.SameLine();
if (ImGui.Button("New Hemi Sphere Light"))
{
lightType = 4;
- lightObject = new NativeFunction<nint>(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<uLight, uLight>(sceneLights.Where(x => (x.Type == 2)), x => x, Comparer<uLight>.Create((x, y) =>
+ DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where((x) => x.Type == 2), (x) => x, Comparer<uLight>.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<uLight, uLight>(sceneLights.Where(x => (x.Type == 3)), x => x, Comparer<uLight>.Create((x, y) =>
+ DrawLights(Enumerable.OrderBy<uLight, uLight>(sceneLights.Where((x) => x.Type == 3), (x) => x, Comparer<uLight>.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<Config>(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<Override> overrides)
{
List<Override> 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<Override> 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<Override>? maybeGetStageOverrides(Config config)
{
- if (!config.Overrides.ContainsKey(currentStage))
+ if (currentStage != StageExt.Global && config.Overrides.TryGetValue(currentStage, out List<Override>? 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<T>(name, offset, 0, type, m.min, m.max, m.step, 0);
}
+ public static Parameter<T> P<T>(string name, long offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged
+ {
+ return new Parameter<T>(name, (nint)offset, 0, type, m.min, m.max, m.step, 0);
+ }
+
public static Parameter<T> V<T>(string name, nint offset, ParameterType type, (T? min, T? max, T? step) m = default) where T : unmanaged
{
return new Parameter<T>(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>? updateSSLRParams;
- private delegate void UpdateLightingParams(nint stackOffset, nint lightingObjectInternal);
- private Hook<UpdateLightingParams>? updateLightingParams;
+ private delegate void UpdateToneMapParams(nint stackOffset, nint toneMapObjectInternal);
+ private Hook<UpdateToneMapParams>? updateToneMapParams;
private static bool InTransition = false;
private static List<Parameter> DirtyParams = new List<Parameter>();
@@ -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<bool>("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<float>("LOD Bias 1", 0x21C, ParameterType.FLOAT, pMin(0.0f)),
P<float>("LOD Bias 2", 0x220, ParameterType.FLOAT, pMin(0.0f)),
P<float>("LOD Caster Bias", 0x1E4, ParameterType.FLOAT, pMin(0.0f)),
- // If platform is PS4/Xbox/PC it appears [2] is PC.
- P<float>("LOD Length Platform Bias[2]", 0x22C + (4 * 2), ParameterType.FLOAT, pMin(0.0f)),
- P<float>("LOD Pixel Size Platform Bias[2]", 0x244 + (4 * 2), ParameterType.FLOAT, pMin(0.0f)),
P<int>("LOD Limit", 0xE898, ParameterType.INT, pStep(1)),
P<float>("LOD Passthrough Culling Rate", 0x1F0, ParameterType.FLOAT, pMin(0.0f)),
P<float>("LOD Far Culling Fade Length Max", 0x20C, ParameterType.FLOAT, pMin(0.0f)),
P<float>("LOD Far Culling Fade Pixel Max", 0x210, ParameterType.FLOAT, pMin(0.0f)),
P<float>("Speed Tree LOD Billboard Fade Range", 0x214, ParameterType.FLOAT, pMin(0.0f)),
P<float>("LOD Culling Length Bias", 0x224, ParameterType.FLOAT, pMin(0.0f)),
- P<float>("LOD Culling Pixel Bias", 0x228, ParameterType.FLOAT, pMin(0.0f))
+ P<float>("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<float>("LOD Length Bias", 0x1F4, ParameterType.FLOAT, pMin(0.0f)),
+ P<float>("LOD Length Bias (HQ)", 0x1FC, ParameterType.FLOAT, pMin(0.0f)),
+ // MonsterHunterWorld.exe+1B19B95 - comiss xmm1,xmm0
+ P<float>("LOD Pixel Size Bias", 0x200, ParameterType.FLOAT, pMin(0.0f)),
+ P<float>("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<float>("LOD Length Platform Bias[2]", 0x22C + (4 * 2), ParameterType.FLOAT, pMin(0.0f)),
+ P<float>("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<float>("Passthrough Correct", 0xE950, ParameterType.FLOAT)
};
+ private static Parameter shadowResParameter = P<int>("Shadow Resolution Multiplier", 0, ParameterType.SHADOW_RESOLUTION, pStep(1));
private static Parameter[] shadowCascadeParameters = {
P<bool>("Primary Shadow HQ", 0xE5C0, ParameterType.BOOL),
P<bool>("Primary Shadow HQ (HQ)", 0xE5C2, ParameterType.BOOL),
@@ -1704,11 +1719,87 @@ namespace WorldTuningTool
P<int>("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>? updatePrimaryLightParams;
+ private Hook<StaticPrimaryLightParams>? staticPrimaryLightParams;
+ // "Min Roughness" is +0xFC in params but never read.
+ private static Parameter[] primaryLightParameters = {
+ M<int>("Primary Light Group", 0x14, ParameterType.BITS, 0x7),
+ P<byte>("Primary Light Priority", 0x1A, ParameterType.BYTE),
+ P<float>("Primary Light Direction", 0x110, ParameterType.VECTOR3, pStep(0.00025f)),
+ P<float>("Primary Light Color", 0xE0, ParameterType.COLOR_FACTOR, pMaxStep(1.0f, 0.001f)),
+ P<float>("Primary Light Intensity", 0xF4, ParameterType.FLOAT, pStep(0.005f)),
+ P<bool>("Primary Light Is Primary", 0x1D, ParameterType.BOOL),
+ P<float>("Primary Light Projection Scale", 0x134, ParameterType.VECTOR2),
+ P<float>("Primary Light Projection Offset Speed", 0x144, ParameterType.VECTOR2),
+ P<float>("Primary Light Projection Up", 0x160, ParameterType.VECTOR3),
+ P<bool>("Primary Light Do Volumetric", 0x1F, ParameterType.BOOL),
+ P<bool>("Primary Shadow Cast", 0x23, ParameterType.BOOL),
+ P<int>("Primary Shadow Map Size", 0x30, ParameterType.ALIGNED_INT, pMinStep(0, 128)), // 0 = 64x64 no multiplier @TODO: Verify in the code.
+ P<float>("Primary Shadow Near Clip Distance", 0x28, ParameterType.FLOAT),
+ P<bool>("Primary Shadow Is Fixed Fov Mode", 0x1F9, ParameterType.BOOL),
+ P<float>("Primary Shadow Fov", 0x1F4, ParameterType.FLOAT, pStep(0.0001f)),
+ P<bool>("Primary Shadow Is Discretization Fov Mode", 0x205, ParameterType.BOOL),
+ P<float>("Primary Shadow Discretization Angle", 0x200, ParameterType.FLOAT, pStep(0.0001f)),
+ P<int>("Primary Shadow Cascade Mode", 0x174, ParameterType.INT, pMinMaxStep(0, 3, 1)),
+ P<float>("Primary Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT),
+ P<float>("Primary Shadow Cascade Distance", 0x6C, ParameterType.FLOAT, pStep(5.0f)),
+ P<float>("Primary Shadow Cascade Backforward Distance", 0x7C, ParameterType.FLOAT, pStep(5.0f)),
+ P<float>("Primary Shadow Cascade Distribution", 0x74, ParameterType.FLOAT, pStep(0.001f)),
+ P<bool>("Primary Shadow Cascade Manual Split", 0x4D, ParameterType.BOOL),
+ P<float>("Primary Shadow Cascade Manual Split Distance[0]", 0x54, ParameterType.FLOAT),
+ P<float>("Primary Shadow Cascade Manual Split Distance[1]", 0x5C, ParameterType.FLOAT),
+ P<float>("Primary Shadow Cascade Manual Split Distance[2]", 0x64, ParameterType.FLOAT),
+ P<float>("Primary Shadow Sloped Depth Bias", 0x40, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Depth Bias", 0x38, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Max Depth Bias", 0x48, ParameterType.FLOAT, pStep(0.00001f)),
+ P<bool>("Primary Shadow Cascade Individual Shadow Bias", 0x81, ParameterType.BOOL),
+ P<float>("Primary Shadow Cascade Depth Bias[0]", 0x88, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Sloped Depth Bias[0]", 0xA0, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Max Depth Bias[0]", 0xB8, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Depth Bias[1]", 0x90, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Sloped Depth Bias[1]", 0xA8, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Max Depth Bias[1]", 0xC0, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Depth Bias[2]", 0x98, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Sloped Depth Bias[2]", 0xB0, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Primary Shadow Cascade Max Depth Bias[2]", 0xC8, ParameterType.FLOAT, pStep(0.00001f)),
+ };
+ private static Parameter[] primaryShadowParameters = {
+ P<int>("Primary Shadow Sample Num", 0x1DC, ParameterType.INT, pStep(1)),
+ P<float>("Primary Shadow Radius", 0x1EC, ParameterType.FLOAT, pStep(0.0001f))
+ };
+ private static Parameter[] primaryBroadAreaParameters = {
+ P<float>("Broad Area Shadow Depth Bias", 0x1C4, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Broad Area Shadow Sloped Depth Bias", 0x1CC, ParameterType.FLOAT, pStep(0.00001f)),
+ P<float>("Broad Area Shadow Max Depth Bias", 0x1D4, ParameterType.FLOAT, pStep(0.00001f)),
+ };
+
+ private static MtObject? sLightProbes = null;
+ private static Parameter[] sLightProbesParameters = {
+ P<int>("Light Probes Probe Color", 0x38, ParameterType.COLOR),
+ P<float>("Light Probes Probe Intensity", 0x3C, ParameterType.FLOAT),
+ P<int>("Light Probes Top Color", 0x44, ParameterType.COLOR),
+ P<float>("Light Probes Top Intensity", 0x48, ParameterType.FLOAT),
+ P<int>("Light Probes Bottom Color", 0x4C, ParameterType.COLOR),
+ P<float>("Light Probes Bottom Intensity", 0x50, ParameterType.FLOAT),
+ P<float>("Light Probes Direction", 0x60, ParameterType.VECTOR3),
+ P<int>("Light Probes Shadow Top Color", 0x70, ParameterType.COLOR),
+ P<float>("Light Probes Shadow Top Intensity", 0x74, ParameterType.FLOAT),
+ P<int>("Light Probes Shadow Bottom Color", 0x78, ParameterType.COLOR),
+ P<float>("Light Probes Shadow Bottom Intensity", 0x7C, ParameterType.FLOAT),
+ P<float>("Light Probes Shadow Direction", 0x80, ParameterType.VECTOR3),
+ P<int>("Light Probes Daytime State", 0x9C, ParameterType.INT, pMinMaxStep(0, 6, 1)),
+ P<float>("Light Probes Daytime Interpolation", 0xA0, ParameterType.FLOAT),
+ P<int>("Light Probes Max Iter", 0xA4, ParameterType.INT),
+ P<int>("Light Probes Debug Mode", 0x98, ParameterType.INT, pStep(1))
+ };
+
private static Parameter[] contactShadowParameters = {
P<float>("Fake Light Intensity", 0xEC40, ParameterType.FLOAT),
// MonsterHunterWorld.exe+1B18711 - mov [rbx+0000EC44],3F800000 (Other unknown reference).
- P<float>("Fake Light Intensity (Gameplay)", lton(0x141B1A19F) + 0x6, ParameterType.PATCH_FLOAT),
- P<float>("Fake Light Blend", lton(0x141CDE0CE) + 0x6, ParameterType.PATCH_FLOAT),
+ P<float>("Fake Light Intensity (Gameplay)", 0x141B1A19F + 0x6, ParameterType.PATCH_FLOAT),
+ P<float>("Fake Light Blend", 0x141CDE0CE + 0x6, ParameterType.PATCH_FLOAT),
P<bool>("Force Disable Contact Shadows", 0xB4ED, ParameterType.BOOL),
P<bool>("Facial Contact Shadows Enabled", 0xB4EE, ParameterType.BOOL),
P<bool>("Facial Contact Shadows Enable Noise", 0xB501, ParameterType.BOOL),
@@ -1745,6 +1836,57 @@ namespace WorldTuningTool
P<float>("SSAO Edge Atten Rate", 0xB4DC, ParameterType.FLOAT, pStep(0.001f))
};
+ private static MtObject? sVolumeRenderer = null;
+ private static Parameter[] sVolumeRendererParameters = {
+ P<bool>("Volume Rendering Enabled", 0x38, ParameterType.BOOL)
+ };
+
+ private delegate nint CreateToneMapObject();
+ private delegate nint DestroyToneMapObject(nint toneMapObjectInternal, int unknownInt);
+ private Hook<CreateToneMapObject>? createToneMapObject;
+ private Hook<DestroyToneMapObject>? destroyToneMapObject;
+ private nint toneMapObject = 0x0;
+ private static Parameter[] toneMapParameters = {
+ P<int>("Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 9, 1)),
+ P<bool>("Tone Map Compute Luminance", 0x170, ParameterType.BOOL),
+ P<bool>("Tone Map Luminance Version", 0x168, ParameterType.BOOL),
+ P<float>("Tone Map Shoulder Strength", 0x174, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map Linear Strength", 0x178, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map Linear Angle", 0x17C, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map Toe Strength", 0x180, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map Toe Num", 0x184, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map Toe Denum", 0x188, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Tone Map White Point", 0x18C, ParameterType.FLOAT, pStep(0.01f)),
+ P<float>("Color Grading LUT Blend", 0x1C8, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)),
+ P<float>("Color Grading Vfx LUT Blend", 0x1D0, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)),
+ P<bool>("Color Grading Enable", 0x1D8, ParameterType.BOOL),
+ P<bool>("Color Grading Is Linear To PQ", 0x1A1, ParameterType.BOOL),
+ P<bool>("Color Grading Is PQ To Linear", 0x1A0, ParameterType.BOOL),
+ P<float>("Volume Dispersion", 0x19C, ParameterType.FLOAT),
+ P<float>("Volume Edge Sharpness", 0x198, ParameterType.FLOAT, pStep(0.00001f)),
+ P<bool>("Volume Downsample", 0x210, ParameterType.BOOL)
+ };
+ private static Parameter[] exposureParameters = {
+ P<float>("Exposure Bt Adaption Limit", 0x460, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure Bt Sensitivity", 0x458, ParameterType.FLOAT, pMaxStep(1.0f, 0.001f)),
+ P<float>("Exposure Dk Adaption Limit", 0x464, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure Dk Sensitivity", 0x45C, ParameterType.FLOAT, pMaxStep(1.0f, 0.001f)),
+ P<float>("Exposure Value", 0x474, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure Min White Point", 0x470, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure Max White Point", 0x46C, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure Mid Gray", 0x454, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Exposure White Range", 0x468, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.001f))
+ };
+ private static Parameter[] brightnessParameters = {
+ P<float>("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)),
+ V<bool>("Hdr Output", 0x21A, ParameterType.BOOL),
+ P<float>("Hdr Output White Level", 0x21C, ParameterType.FLOAT, pStep(0.05f)),
+ P<float>("Hdr Output Gamut Mapping Ratio", 0x220, ParameterType.FLOAT, pStep(0.001f)),
+ P<float>("Hdr Output Gamma", 0x224, ParameterType.FLOAT, pStep(0.001f)),
+ P<bool>("Hdr Is Gui Hdr Gamma", 0x228, ParameterType.BOOL)
+ };
+
private static Parameter[] sslrParameters = {
P<int>("SSLR Loop Count", 0xE628, ParameterType.INT, pStep(1)),
P<float>("SSLR Loop Count Factor for CBR", 0xE62C, ParameterType.FLOAT),
@@ -1764,116 +1906,12 @@ namespace WorldTuningTool
P<float>("SSLR Intensity", 0xB424, ParameterType.FLOAT)
};
- private static Parameter shadowResParameter = P<int>("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>? updateShadowParams;
- private Hook<StaticShadowParams>? 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<int>("Sunlight Group", 0x14, ParameterType.INT, pMinMaxStep(1, 255, 1)),
- P<float>("Sunlight Direction", 0x110, ParameterType.VECTOR3, pStep(0.00025f)),
- P<float>("Sunlight Color", 0xE0, ParameterType.COLOR_FACTOR, pMaxStep(1.0f, 0.001f)),
- P<float>("Sunlight Intensity", 0xF4, ParameterType.FLOAT, pStep(0.005f)),
- P<bool>("Sunlight Is Primary", 0x1D, ParameterType.BOOL),
- P<bool>("Do Volumetric", 0x1F, ParameterType.BOOL),
- P<bool>("Shadow Cast", 0x23, ParameterType.BOOL),
- P<int>("Shadow Map Size", 0x30, ParameterType.ALIGNED_INT, pMinStep(0, 128)), // 0 = 64x64 no multiplier @TODO: Verify in the code.
- P<float>("Shadow Near Clip Distance", 0x28, ParameterType.FLOAT),
- P<int>("Shadow Cascade Mode", 0x174, ParameterType.INT, pMinMaxStep(0, 3, 1)),
- P<float>("Shadow Cascade 2Way Bias", 0x17C, ParameterType.FLOAT),
- P<float>("Shadow Distance", 0x6C, ParameterType.FLOAT, pStep(5.0f)),
- P<float>("Shadow Backforward Distance", 0x7C, ParameterType.FLOAT, pStep(5.0f)),
- P<bool>("Shadow Is Fixed Fov Mode", 0x1F9, ParameterType.BOOL),
- P<float>("Shadow Fov", 0x1F4, ParameterType.FLOAT, pStep(0.0001f)),
- P<bool>("Shadow Is Discretization Fov Mode", 0x205, ParameterType.BOOL),
- P<float>("Shadow Discretization Angle", 0x200, ParameterType.FLOAT, pStep(0.0001f)),
- P<float>("Shadow Distribution", 0x74, ParameterType.FLOAT, pStep(0.001f)),
- P<bool>("Cascade Manual Split", 0x4D, ParameterType.BOOL),
- P<float>("Cascade Manual Split Distance[0]", 0x54, ParameterType.FLOAT),
- P<float>("Cascade Manual Split Distance[1]", 0x5C, ParameterType.FLOAT),
- P<float>("Cascade Manual Split Distance[2]", 0x64, ParameterType.FLOAT),
- P<float>("Shadow Sloped Depth Bias", 0x40, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Shadow Depth Bias", 0x38, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Shadow Max Depth Bias", 0x48, ParameterType.FLOAT, pStep(0.00001f)),
- P<bool>("Cascade Individual Shadow Bias", 0x81, ParameterType.BOOL),
- P<float>("Cascade Depth Bias[0]", 0x88, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Sloped Depth Bias[0]", 0xA0, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Max Depth Bias[0]", 0xB8, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Depth Bias[1]", 0x90, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Sloped Depth Bias[1]", 0xA8, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Max Depth Bias[1]", 0xC0, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Depth Bias[2]", 0x98, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Sloped Depth Bias[2]", 0xB0, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Cascade Max Depth Bias[2]", 0xC8, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Broad Area Shadow Depth Bias", 0x1C4, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Broad Area Shadow Sloped Depth Bias", 0x1CC, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Broad Area Shadow Max Depth Bias", 0x1D4, ParameterType.FLOAT, pStep(0.00001f)),
- P<float>("Projection Scale", 0x134, ParameterType.VECTOR2),
- P<float>("Projection Offset Speed", 0x144, ParameterType.VECTOR2),
- P<float>("Projection Up", 0x160, ParameterType.VECTOR3),
- P<int>("Primary Shadow Sample Num", 0x1DC, ParameterType.INT, pStep(1)),
- P<float>("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<int>("Light Probes Probe Color", 0x38, ParameterType.COLOR),
- P<float>("Light Probes Probe Intensity", 0x3C, ParameterType.FLOAT),
- P<int>("Light Probes Top Color", 0x44, ParameterType.COLOR),
- P<float>("Light Probes Top Intensity", 0x48, ParameterType.FLOAT),
- P<int>("Light Probes Bottom Color", 0x4C, ParameterType.COLOR),
- P<float>("Light Probes Bottom Intensity", 0x50, ParameterType.FLOAT),
- P<float>("Light Probes Direction", 0x60, ParameterType.VECTOR3),
- P<int>("Light Probes Shadow Top Color", 0x70, ParameterType.COLOR),
- P<float>("Light Probes Shadow Top Intensity", 0x74, ParameterType.FLOAT),
- P<int>("Light Probes Shadow Bottom Color", 0x78, ParameterType.COLOR),
- P<float>("Light Probes Shadow Bottom Intensity", 0x7C, ParameterType.FLOAT),
- P<float>("Light Probes Shadow Direction", 0x80, ParameterType.VECTOR3),
- P<int>("Light Probes Daytime State", 0x9C, ParameterType.INT, pMinMaxStep(0, 6, 1)),
- P<float>("Light Probes Daytime Interpolation", 0xA0, ParameterType.FLOAT),
- P<int>("Light Probes Max Iter", 0xA4, ParameterType.INT),
- P<int>("Light Probes Debug Mode", 0x98, ParameterType.INT, pStep(1))
- };
-
- private delegate nint CreateLightingObject();
- private delegate nint DestroyLightingObject(nint lightingObjectInternal, int unknownInt);
- private Hook<CreateLightingObject>? createLightingObject;
- private Hook<DestroyLightingObject>? destroyLightingObject;
- private nint lightingObject = 0x0;
- private static LUT luts = new LUT();
- private static Parameter[] lightingParameters = {
- P<int>("Light Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 6, 1)),
- P<bool>("Light Compute Luminance", 0x170, ParameterType.BOOL),
- P<bool>("Light Luminance Version", 0x168, ParameterType.BOOL),
- P<float>("Light Shoulder Strength", 0x174, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light Linear Strength", 0x178, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light Linear Angle", 0x17C, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light Toe Strength", 0x180, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light Toe Num", 0x184, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light Toe Denum", 0x188, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Light White Point", 0x18C, ParameterType.FLOAT, pStep(0.01f)),
- P<float>("Light LUT Blend", 0x1C8, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)),
- P<float>("Light Vfx LUT Blend", 0x1D0, ParameterType.FLOAT, pMinMaxStep(0.0f, 1.0f, 0.01f)),
- P<bool>("Light Enable Color Grading", 0x1D8, ParameterType.BOOL),
- P<bool>("Light Is Linear To PQ", 0x1A1, ParameterType.BOOL),
- P<bool>("Light Is PQ To Linear", 0x1A0, ParameterType.BOOL),
- P<float>("Volume Dispersion", 0x19C, ParameterType.FLOAT),
- P<float>("Volume Edge Sharpness", 0x198, ParameterType.FLOAT, pStep(0.00001f)),
- P<bool>("Volume Downsample", 0x210, ParameterType.BOOL)
- };
- private static Parameter[] brightnessParameters = {
- P<float>("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f)),
- V<bool>("Hdr Output", 0x21A, ParameterType.BOOL),
- P<float>("Hdr Output White Level", 0x21C, ParameterType.FLOAT, pStep(0.05f)),
- P<float>("Hdr Output Gamut Mapping Ratio", 0x220, ParameterType.FLOAT, pStep(0.001f)),
- P<float>("Hdr Output Gamma", 0x224, ParameterType.FLOAT, pStep(0.001f)),
- P<bool>("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>? createRenderPassesObject;
+ private Hook<DestroyRenderPassesObject>? destroyRenderPassesObject;
+ private nint renderPassesObject = 0x0;
+ private static Parameter[] renderPassesParameters = {
};
private delegate nint CreateBloomObject();
@@ -2089,6 +2127,30 @@ namespace WorldTuningTool
P<float>("Fog Mip Fog Color", 0x330, ParameterType.COLOR_FACTOR, pStep(0.001f))
};
+ private static MtObject? sMhSpeedTree = null;
+ private static Parameter[] speedTreeParameters = {
+ //P<bool>("Speed Tree is Active", 0x339, ParameterType.BOOL),
+ P<bool>("Speed Tree Wind Active", 0x33A, ParameterType.BOOL),
+ //P<bool>("Speed Tree System Wind Active", 0x33C, ParameterType.BOOL),
+ //P<bool>("Speed Tree Disp Off Water Reflection", 0x33B, ParameterType.BOOL),
+ P<float>("Speed Tree Wind Direction", 0x210 + 0x30, ParameterType.VECTOR3),
+ P<float>("Speed Tree Wind Strength", 0x210 + 0x40, ParameterType.FLOAT),
+ /*
+ P<float>("Speed Tree Wind Strength Response", 0x210 + 0x44, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Direction Response", 0x210 + 0x48, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Frequency", 0x210 + 0x4C, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Strength Min", 0x210 + 0x50, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Strength Max", 0x210 + 0x54, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Duration Min", 0x210 + 0x58, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Duration Max", 0x210 + 0x5C, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Rise Scalar", 0x210 + 0x60, ParameterType.FLOAT),
+ P<float>("Speed Tree Wind Gust Fall Scalar", 0x210 + 0x64, ParameterType.FLOAT),
+ P<bool>("Speed Tree Wind Gust Enable", 0x210 + 0x68, ParameterType.BOOL),
+ P<float>("Speed Tree Wind Instance Delay", 0x32C, ParameterType.FLOAT),
+ P<float>("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>? 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<EvaluateSceneParams>(0x1423C3790, EvaluateSceneParamsHook); // nint, nint, int, nint
+ evaluateSceneParams = Hook.Create<EvaluateSceneParams>(0x1423C3790, EvaluateSceneParamsHook);
// These run in a loop during cutscenes.
- updateSSAOParams = Hook.Create<UpdateSSAOParams>(0x1416D8B10, UpdateSSAOParamsHook); // nint
- updateSSLRParams = Hook.Create<UpdateSSLRParams>(0x1416DA3F0, UpdateSSLRParamsHook); // nint
- updateLightingParams = Hook.Create<UpdateLightingParams>(0x1416DAAB0, UpdateLightingParamsHook); // nint, nint
+ updateSSAOParams = Hook.Create<UpdateSSAOParams>(0x1416D8B10, UpdateSSAOParamsHook);
+ updateSSLRParams = Hook.Create<UpdateSSLRParams>(0x1416DA3F0, UpdateSSLRParamsHook);
+ updateToneMapParams = Hook.Create<UpdateToneMapParams>(0x1416DAAB0, UpdateToneMapParamsHook);
+
+ createToneMapObject = Hook.Create<CreateToneMapObject>(0x1424CDE20, CreateToneMapObjectHook);
+ destroyToneMapObject = Hook.Create<DestroyToneMapObject>(0x1424CE380, DestroyToneMapObjectHook);
- createLightingObject = Hook.Create<CreateLightingObject>(0x1424CDE20, CreateLightingObjectHook);
- destroyLightingObject = Hook.Create<DestroyLightingObject>(0x1424CE380, DestroyLightingObjectHook); // nint, int
+ createRenderPassesObject = Hook.Create<CreateRenderPassesObject>(0x14255BA70, CreateRenderPassesObjectHook);
+ destroyRenderPassesObject = Hook.Create<DestroyRenderPassesObject>(0x14255C710, DestroyRenderPassesObjectHook);
createBloomObject = Hook.Create<CreateBloomObject>(0x1424CB3C0, CreateBloomObjectHook);
- createBloomObject2 = Hook.Create<CreateBloomObject2>(0x1424CB5E0, CreateBloomObject2Hook); // nint
- destroyBloomObject = Hook.Create<DestroyBloomObject>(0x1424CB750, DestroyBloomObjectHook); // nint, int
+ createBloomObject2 = Hook.Create<CreateBloomObject2>(0x1424CB5E0, CreateBloomObject2Hook);
+ destroyBloomObject = Hook.Create<DestroyBloomObject>(0x1424CB750, DestroyBloomObjectHook);
createDofObject = Hook.Create<CreateDofObject>(0x142421E80, CreateDofObjectHook);
- createDofObject2 = Hook.Create<CreateDofObject2>(0x1424220A0, CreateDofObject2Hook); // nint
- destroyDofObject = Hook.Create<DestroyDofObject>(0x142422290, DestroyDofObjectHook); // nint, int
+ createDofObject2 = Hook.Create<CreateDofObject2>(0x1424220A0, CreateDofObject2Hook);
+ destroyDofObject = Hook.Create<DestroyDofObject>(0x142422290, DestroyDofObjectHook);
createMotionBlurObject = Hook.Create<CreateMotionBlurObject>(0x1424C95E0, CreateMotionBlurObjectHook);
- createMotionBlurObject2 = Hook.Create<CreateMotionBlurObject2>(0x1424C9740, CreateMotionBlurObject2Hook); // nint
- destroyMotionBlurObject = Hook.Create<DestroyMotionBlurObject>(0x1424C97E0, DestroyMotionBlurObjectHook); // nint, int
+ createMotionBlurObject2 = Hook.Create<CreateMotionBlurObject2>(0x1424C9740, CreateMotionBlurObject2Hook);
+ destroyMotionBlurObject = Hook.Create<DestroyMotionBlurObject>(0x1424C97E0, DestroyMotionBlurObjectHook);
createHazeObject = Hook.Create<CreateHazeObject>(0x1424C6A80, CreateHazeObjectHook);
- createHazeObject2 = Hook.Create<CreateHazeObject2>(0x1424C6C70, CreateHazeObject2Hook); // nint
- destroyHazeObject = Hook.Create<DestroyHazeObject>(0x1424C6E20, DestroyHazeObjectHook); // nint, int
+ createHazeObject2 = Hook.Create<CreateHazeObject2>(0x1424C6C70, CreateHazeObject2Hook);
+ destroyHazeObject = Hook.Create<DestroyHazeObject>(0x1424C6E20, DestroyHazeObjectHook);
- createSimpleSkyObject = Hook.Create<CreateSimpleSkyObject>(0x141FCCC20, CreateSimpleSkyObjectHook); // nint
- destroySimpleSkyObject = Hook.Create<DestroySimpleSkyObject>(0x141FCD840, DestroySimpleSkyObjectHook); // nint, int
+ createSimpleSkyObject = Hook.Create<CreateSimpleSkyObject>(0x141FCCC20, CreateSimpleSkyObjectHook);
+ destroySimpleSkyObject = Hook.Create<DestroySimpleSkyObject>(0x141FCD840, DestroySimpleSkyObjectHook);
createFogObject = Hook.Create<CreateFogObject>(0x141FADB50, CreateFogObjectHook);
- createFogObject2 = Hook.Create<CreateFogObject2>(0x141FADC80, CreateFogObject2Hook); // nint
- destroyFogObject = Hook.Create<DestroyFogObject>(0x141FADD50, DestroyFogObjectHook); // nint, int
+ createFogObject2 = Hook.Create<CreateFogObject2>(0x141FADC80, CreateFogObject2Hook);
+ destroyFogObject = Hook.Create<DestroyFogObject>(0x141FADD50, DestroyFogObjectHook);
- createWaterWaveObject = Hook.Create<CreateWaterWaveObject>(0x1423F0850, CreateWaterWaveObjectHook); // nint
- destroyWaterWaveObject = Hook.Create<DestroyWaterWaveObject>(0x1423F0EE0, DestroyWaterWaveObjectHook); // nint, int
+ createWaterWaveObject = Hook.Create<CreateWaterWaveObject>(0x1423F0850, CreateWaterWaveObjectHook);
+ destroyWaterWaveObject = Hook.Create<DestroyWaterWaveObject>(0x1423F0EE0, DestroyWaterWaveObjectHook);
createFXAAObject = Hook.Create<CreateFXAAObject>(0x142393560, CreateFXAAObjectHook);
- createFXAAObject2 = Hook.Create<CreateFXAAObject2>(0x142393680, CreateFXAAObject2Hook); // nint
- destroyFXAAObject = Hook.Create<DestroyFXAAObject>(0x142393740, DestroyFXAAObjectHook); // nint, int
+ createFXAAObject2 = Hook.Create<CreateFXAAObject2>(0x142393680, CreateFXAAObject2Hook);
+ destroyFXAAObject = Hook.Create<DestroyFXAAObject>(0x142393740, DestroyFXAAObjectHook);
createTAAObject = Hook.Create<CreateTAAObject>(0x1423911A0, CreateTAAObjectHook);
- createTAAObject2 = Hook.Create<CreateTAAObject2>(0x142391320, CreateTAAObject2Hook); // nint
- destroyTAAObject = Hook.Create<DestroyTAAObject>(0x1423916E0, DestroyTAAObjectHook); // nint, int
+ createTAAObject2 = Hook.Create<CreateTAAObject2>(0x142391320, CreateTAAObject2Hook);
+ destroyTAAObject = Hook.Create<DestroyTAAObject>(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<UpdateShadowParams>(addr, UpdateShadowParamsHook);
- staticShadowParams = Hook.Create<StaticShadowParams>(0x1416D94F0, StaticShadowParamsHook); // nint, nint
+ Assert(addr == 0x141AB2260);
+ updatePrimaryLightParams = Hook.Create<UpdatePrimaryLightParams>(addr, UpdatePrimaryLightParamsHook);
+ staticPrimaryLightParams = Hook.Create<StaticPrimaryLightParams>(0x1416D94F0, StaticPrimaryLightParamsHook);
+
+ defaultHqMode = new Patch(0x14226562B, [0xC6, 0x87, 0xA3, 0xE9, 0x00, 0x00, 0x01]);
+ //defaultHqMode.Enable();
setShadowQuality = new NativeAction<int>(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<byte>(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<Override> globalOverrides, List<Override>? 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<nint>(0x14500E180);
- nint shadowObject = MemoryUtil.Read<nint>(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<nint>(MemoryUtil.Read<nint>(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<nint>(lightingObject + 0x1C0);
+ nint lutBlendTexture = MemoryUtil.Read<nint>(toneMapObject + 0x1C0);
ImGui.Text($"LUT Blend: 0x{lutBlendTexture:X}");
- nint lutMap0 = MemoryUtil.Read<nint>(lightingObject + 0x1A8);
+ nint lutMap0 = MemoryUtil.Read<nint>(toneMapObject + 0x1A8);
if (lutMap0 != 0x0)
{
- luts.DrawUI(lutMap0, lightingObject, 0, width);
+ WorldLUTs.DrawUI(lutMap0, toneMapObject, 0, width);
}
- nint lutMap1 = MemoryUtil.Read<nint>(lightingObject + 0x1B0);
+ nint lutMap1 = MemoryUtil.Read<nint>(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<nint>(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<byte>(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)