diff options
| author | 2026-06-29 11:15:01 -0400 | |
|---|---|---|
| committer | 2026-06-29 11:15:01 -0400 | |
| commit | 6374a4b274e5048c56a820402275e28cf5ac1d39 (patch) | |
| tree | 6578b5ea21da09740d70b5f7492ea8925f9ed467 | |
| parent | 9ea738140d941ef0a7193e4f45278f2923997cc2 (diff) | |
| download | WorldTuningTool-6374a4b274e5048c56a820402275e28cf5ac1d39.tar.gz WorldTuningTool-6374a4b274e5048c56a820402275e28cf5ac1d39.tar.bz2 WorldTuningTool-6374a4b274e5048c56a820402275e28cf5ac1d39.zip | |
Cleanup and test some lighting stuff
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | LUT.cs | 35 | ||||
| -rwxr-xr-x | Plugin.cs | 243 | ||||
| -rw-r--r-- | Shaders/Original/alpha_as_luma.dxbc.xz | bin | 0 -> 596 bytes | |||
| -rw-r--r-- | Shaders/alpha_as_luma.hlsl | 58 |
4 files changed, 241 insertions, 95 deletions
@@ -3,6 +3,7 @@ using System.Text; using System.Numerics; using SharpPluginLoader.Core; +using SharpPluginLoader.Core.Memory; using SharpPluginLoader.Core.Rendering; namespace WorldTuningTool @@ -13,13 +14,41 @@ namespace WorldTuningTool public WorldLUT() { } + private string[] lutList = []; + public string[] GetLUTs() { - if (!Directory.Exists(lutsPath)) + return lutList; + } + + public void ReloadLUTs() + { + if (Directory.Exists(lutsPath)) { - return []; + lutList = Directory.GetFiles(lutsPath); + } + } + + public static nint ProbeD3DResource(nint lightingObject) + { + nint lutTexture = MemoryUtil.Read<nint>(lightingObject + 0x1C0); + nint d3dResource = 0x0; + if (lutTexture != 0x0) + { + if (Renderer.IsDirectX12) + { + d3dResource = MemoryUtil.Read<nint>(lutTexture + 0x10); + } + else + { + d3dResource = MemoryUtil.Read<nint>(lutTexture + 0x60); + if (d3dResource != 0x0) + { + d3dResource = MemoryUtil.Read<nint>(d3dResource + 0x18); + } + } } - return Directory.GetFiles(lutsPath); + return d3dResource; } // https://github.com/AsteriskAmpersand/CrappyLUTStudio--CLUTS-/blob/5af10daaa5f295b106cc5db09530a6fe5a4320d4/LUT.py#L35 @@ -6,22 +6,22 @@ using System.Numerics;
using System.Globalization;
using System.Runtime.CompilerServices;
-#if SHADER_FEATURES
using System.Runtime.InteropServices;
-#endif
#if ENABLE_ASSERTS
using System.Diagnostics;
#endif
using ImGuiNET;
using SharpPluginLoader.Core;
+using SharpPluginLoader.Core.Configuration;
+using SharpPluginLoader.Core.Memory;
+using SharpPluginLoader.Core.Entities;
+#if SHADER_FEATURES
using SharpPluginLoader.Core.Rendering;
+#endif
#if RESOURCE_ADJUSTMENT
using SharpPluginLoader.Core.Resources;
#endif
-using SharpPluginLoader.Core.Configuration;
-using SharpPluginLoader.Core.Memory;
-using SharpPluginLoader.Core.Entities;
// @TODO:
// - Configurable Broad Area Shadow Resolution.
@@ -1394,6 +1394,8 @@ namespace WorldTuningTool }
private static MtObject? sMhScene = null;
+ private static MtObject? sMhMain = null;
+ private static MtObject? sMhRender = null;
private static Parameter hqMode = newParameter<bool>("HQ Mode", 0xE9A3, ParameterType.BOOL);
@@ -1568,10 +1570,6 @@ namespace WorldTuningTool newFrameParameter<float>("Primary Shadow Radius", 0x1EC, ParameterType.FLOAT, pStep(0.0001f))
};
- private static MtObject? sLightProbes = null;
- private static Parameter[] lightProbesParameters = {
- newParameter<int>("Debug Mode", 0x98, ParameterType.INT, pStep(1))
- };
private delegate nint CreateLightingObject();
private delegate nint DestroyLightingObject(nint lightingObjectInternal, int unknownInt);
private Hook<CreateLightingObject>? createLightingObject;
@@ -1579,12 +1577,14 @@ namespace WorldTuningTool private nint lightingObject = 0x0;
private delegate void SetLightingParameters(nint lightingObjectInternal);
private Hook<SetLightingParameters>? setLightingParams;
+ private NativeAction<nint> setLightingParamsFunc;
private delegate void UpdateLightingParameters(nint stackOffset, nint lightingObjectInternal);
private Hook<UpdateLightingParameters>? updateLightingParams;
private Hook<UpdateLightingParameters>? updateLutBlend;
private static WorldLUT lut = new WorldLUT();
private static string selectedLut = "";
- private static bool selectedLutInavlid = false;
+ private static bool lutSelectionStarted = false;
+ private static bool selectedLutInvalid = false;
private static Parameter[] lightingParameters = {
newParameter<int>("Light Tone Map Type", 0x16C, ParameterType.INT, pMinMaxStep(1, 6, 1)),
newParameter<bool>("Light Compute Luminance", 0x170, ParameterType.BOOL),
@@ -1605,6 +1605,14 @@ namespace WorldTuningTool newParameter<float>("Volume Edge Sharpness", 0x198, ParameterType.FLOAT, pStep(0.00001f)),
newParameter<bool>("Volume Downsample", 0x210, ParameterType.BOOL)
};
+ private static Parameter[] brightnessParameters = {
+ newParameter<float>("Gamma Correct", 0x1C8, ParameterType.FLOAT, pStep(0.001f)),
+ newParameter<float>("Gamma Correct EX", 0x1CC, ParameterType.FLOAT, pStep(0.001f))
+ };
+ private static MtObject? sLightProbes = null;
+ private static Parameter[] lightProbesParameters = {
+ newParameter<int>("Debug Mode", 0x98, ParameterType.INT, pStep(1))
+ };
private delegate nint CreateBloomObject();
private delegate nint CreateBloomObject2(nint unknownPtr);
@@ -1707,8 +1715,6 @@ namespace WorldTuningTool newParameter<bool>("TAA Sharpend Ignore Edges", 0x19C, ParameterType.BOOL)
};
- private static MtObject? sMain = null;
-
private static Parameter[] allParameters = new Parameter[]{ hqMode }
.Concat(lodParameters)
.Concat(snowParameters)
@@ -2120,6 +2126,7 @@ namespace WorldTuningTool createLightingObject = Hook.Create<CreateLightingObject>(0x1424CDE20, CreateLightingObjectHook);
destroyLightingObject = Hook.Create<DestroyLightingObject>(0x1424CE380, DestroyLightingObjectHook); // nint, int
setLightingParams = Hook.Create<SetLightingParameters>(0x1424CF1C0, SetLightingParametersHook); // nint
+ setLightingParamsFunc = new NativeAction<nint>(0x1424CF1C0);
updateLutBlend = Hook.Create<UpdateLightingParameters>(0x1416D8DF0, UpdateLutBlendHook); // nint, nint
createBloomObject = Hook.Create<CreateBloomObject>(0x1424CB3C0, CreateBloomObjectHook);
@@ -2426,7 +2433,8 @@ namespace WorldTuningTool public void OnLoad()
{
- sMain = SingletonManager.GetSingleton("sMhMain")!;
+ sMhMain = SingletonManager.GetSingleton("sMhMain")!;
+ sMhRender = SingletonManager.GetSingleton("sMhRender")!;
sMhScene = SingletonManager.GetSingleton("sMhScene")!;
sLightProbes = SingletonManager.GetSingleton("sLightProbes")!;
Config config = getConfig();
@@ -2451,8 +2459,7 @@ namespace WorldTuningTool config.Overrides.Add(area, new List<Override>());
}
}
- List<Override> globalOverrides = config.Overrides[globalStage];
- foreach (Override ovG in globalOverrides)
+ foreach (Override ovG in config.Overrides[globalStage])
{
ovG.Set();
}
@@ -2495,35 +2502,44 @@ namespace WorldTuningTool {
HandleAreaChange(stage);
}
+
hqMode.Update(sMhScene!.Instance);
+
foreach (Parameter param in lodParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in passthroughParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in shadowCascadeParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in contactShadowParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in snowParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in ssaoParameters)
{
param.Update(sMhScene!.Instance);
}
+
foreach (Parameter param in sslrParameters)
{
param.Update(sMhScene!.Instance);
}
+
if (lightingObject != 0x0)
{
foreach (Parameter param in lightingParameters)
@@ -2531,10 +2547,17 @@ namespace WorldTuningTool param.Update(lightingObject);
}
}
+
foreach (Parameter param in lightProbesParameters)
{
param.Update(sLightProbes!.Instance);
}
+
+ foreach (Parameter param in brightnessParameters)
+ {
+ param.Update(sMhRender!.Instance);
+ }
+
if (bloomObject != 0x0)
{
foreach (Parameter param in bloomParameters)
@@ -2542,6 +2565,7 @@ namespace WorldTuningTool param.Update(bloomObject);
}
}
+
if (dofObject != 0x0)
{
foreach (Parameter param in dofParameters)
@@ -2552,6 +2576,7 @@ namespace WorldTuningTool }
}
}
+
if (motionBlurObject != 0x0)
{
foreach (Parameter param in motionBlurParameters)
@@ -2562,6 +2587,7 @@ namespace WorldTuningTool }
}
}
+
if (fxaaObject != 0x0)
{
foreach (Parameter param in fxaaParameters)
@@ -2569,6 +2595,7 @@ namespace WorldTuningTool param.Update(fxaaObject);
}
}
+
if (taaObject != 0x0)
{
foreach (Parameter param in taaParameters)
@@ -2863,7 +2890,6 @@ namespace WorldTuningTool setLightingParams!.Original(lightingObjectInternal);
if (lightingObject == lightingObjectInternal)
{
- // LUT texture should be set at this point.
selectedLut = "";
}
}
@@ -3146,14 +3172,9 @@ namespace WorldTuningTool ImGui.EndCombo();
}
ImGui.SameLine();
- if (ImGui.Button("Global"))
- {
- selectedStage = globalStage;
- }
- ImGui.SameLine();
Config config = getConfig();
- bool invalidStage = !config.Overrides.ContainsKey(currentStage);
- if (invalidStage)
+ bool errorStage = !config.Overrides.ContainsKey(currentStage);
+ if (errorStage)
{
ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true);
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * 0.5f);
@@ -3162,11 +3183,16 @@ namespace WorldTuningTool {
selectedStage = currentStage;
}
- if (invalidStage)
+ if (errorStage)
{
ImGui.PopStyleVar();
ImGui.PopItemFlag();
}
+ ImGui.SameLine();
+ if (ImGui.Button("Global"))
+ {
+ selectedStage = globalStage;
+ }
List<Override> selectedOverrides = config.Overrides[selectedStage];
if (ImGui.Button("Add override"))
@@ -3279,7 +3305,7 @@ namespace WorldTuningTool ImGui.Separator();
- // We now have to consider both global and stage overrides.
+ // From this point forward, we have to consider both globalOverrides and stageOverrides.
globalOverrides = config.Overrides[globalStage];
ImGui.PushID("Set");
@@ -3694,6 +3720,7 @@ namespace WorldTuningTool if (ImGui.CollapsingHeader("Sunlight and Shadows"))
{
shadowResParameter.Draw(width);
+ ImGui.Separator();
ImGui.Text($"shadowObject: 0x{shadowAddr:X}, shadowAddr: 0x{shadowObject:X}");
/*
if (ImGui.CollapsingHeader("Pass 1"))
@@ -3717,6 +3744,7 @@ namespace WorldTuningTool ImGui.PopID();
}
*/
+ ImGui.Separator();
ImGui.Text($"Address: 0x{sMhScene!.Instance:X}");
foreach (Parameter param in shadowCascadeParameters)
{
@@ -3802,59 +3830,77 @@ namespace WorldTuningTool {
if (lightingObject != 0x0)
{
- nint lutTexture = MemoryUtil.Read<nint>(lightingObject + 0x1C0);
- nint d3dResource = 0x0;
- if (lutTexture != 0x0)
+ ImGui.Text($"Address: 0x{lightingObject:X}");
+ if (ImGui.CollapsingHeader("LUT"))
{
- if (Renderer.IsDirectX12)
+ nint d3dResource = WorldLUT.ProbeD3DResource(lightingObject);
+ if (d3dResource != 0x0)
{
- d3dResource = MemoryUtil.Read<nint>(lutTexture + 0x10);
- }
- else
- {
- d3dResource = MemoryUtil.Read<nint>(lutTexture + 0x60);
- if (d3dResource != 0x0)
+ if (ImGui.Button("Reset"))
{
- d3dResource = MemoryUtil.Read<nint>(d3dResource + 0x18);
+ // Attempt to force check for reloading LUT to pass.
+ MemoryUtil.GetRef<float>(lightingObject + 0x1D4) = MemoryUtil.GetRef<float>(lightingObject + 0x1D0) + 1.0f;
}
- }
- }
- if (d3dResource != 0x0)
- {
- ImGui.SetNextItemWidth(width * 0.65f);
- bool prevLutWasInvalid = selectedLutInavlid;
- if (prevLutWasInvalid)
- {
- ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF);
- }
- if (ImGui.BeginCombo("LUT", selectedLut, ImGuiComboFlags.HeightLarge))
- {
+ ImGui.SameLine();
+ ImGui.SetNextItemWidth(width * 0.625f);
+ bool prevLutWasInvalid = selectedLutInvalid;
if (prevLutWasInvalid)
{
- ImGui.PopStyleColor();
+ ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF);
}
- foreach (string lutPath in lut.GetLUTs())
+ if (ImGui.BeginCombo("##LUT Files", selectedLut, ImGuiComboFlags.HeightLarge))
{
- string lutFile = Path.GetFileName(lutPath);
- bool isSelected = selectedLut == lutFile;
- if (ImGui.Selectable(lutFile, isSelected))
+ if (prevLutWasInvalid)
+ {
+ ImGui.PopStyleColor();
+ }
+ if (!lutSelectionStarted)
{
- selectedLutInavlid = !lut.OverwriteFromFile(d3dResource, lutPath);
- selectedLut = lutFile;
+ lut.ReloadLUTs();
+ lutSelectionStarted = true;
+ }
+ foreach (string lutPath in lut.GetLUTs())
+ {
+ string lutFile = Path.GetFileName(lutPath);
+ bool isSelected = selectedLut == lutFile;
+ if (ImGui.Selectable(lutFile, isSelected))
+ {
+ selectedLutInvalid = !lut.OverwriteFromFile(d3dResource, lutPath);
+ selectedLut = lutFile;
+ }
}
+ ImGui.EndCombo();
}
- ImGui.EndCombo();
+ else
+ {
+ if (prevLutWasInvalid)
+ {
+ ImGui.PopStyleColor();
+ }
+ lutSelectionStarted = false;
+ }
+ }
+ nint lutMap0 = MemoryUtil.Read<nint>(lightingObject + 0x1A8);
+ if (lutMap0 != 0x0)
+ {
+ ImGui.Text($"LUT Map 0: {Marshal.PtrToStringAnsi(lutMap0 + 0xC)!}");
}
- else if (prevLutWasInvalid)
+ nint lutMap1 = MemoryUtil.Read<nint>(lightingObject + 0x1B0);
+ if (lutMap1 != 0x0)
{
- ImGui.PopStyleColor();
+ ImGui.Text($"LUT Map 1: {Marshal.PtrToStringAnsi(lutMap1 + 0xC)!}");
}
}
- ImGui.Text($"Address: 0x{lightingObject:X}");
foreach (Parameter param in lightingParameters)
{
param.Draw(width);
}
+ ImGui.Separator();
+ }
+ ImGui.Text($"Address: 0x{sMhRender!.Instance:X}");
+ foreach (Parameter param in brightnessParameters)
+ {
+ param.Draw(width);
}
ImGui.Separator();
ImGui.Text($"Address: 0x{sLightProbes!.Instance:X}");
@@ -3947,58 +3993,63 @@ namespace WorldTuningTool ImGui.EndTooltip();
}
- if (ImGui.Checkbox("Continous SSLR Temporal Reset", ref continousSSLRTemporalReset))
+ if (ImGui.CollapsingHeader("Tests"))
{
- if (continousSSLRTemporalReset)
+ if (ImGui.Checkbox("Continous SSLR Temporal Reset", ref continousSSLRTemporalReset))
{
- forceSSLRTemporalReset.Enable();
+ if (continousSSLRTemporalReset)
+ {
+ forceSSLRTemporalReset.Enable();
+ }
+ else
+ {
+ forceSSLRTemporalReset.Disable();
+ }
}
- else
+ if (ImGui.BeginItemTooltip())
{
- forceSSLRTemporalReset.Disable();
+ ImGui.Text("Don't reference tBlendMap in SSLR resolve.");
+ ImGui.EndTooltip();
}
- }
- if (ImGui.BeginItemTooltip())
- {
- ImGui.Text("Don't reference tBlendMap in SSLR resolve.");
- ImGui.EndTooltip();
- }
- if (ImGui.Checkbox("Skip SSLR Mip Mapping", ref skipSSLRMipMapping))
- {
- if (skipSSLRMipMapping)
+ if (ImGui.Checkbox("Skip SSLR Mip Mapping", ref skipSSLRMipMapping))
{
- ssrRes4.Enable();
- }
- else
- {
- ssrRes4.Disable();
+ if (skipSSLRMipMapping)
+ {
+ ssrRes4.Enable();
+ }
+ else
+ {
+ ssrRes4.Disable();
+ }
}
- }
- if (ImGui.Checkbox("Force unknown _FULL_RES (Probably Useless)", ref unknownFullResPath))
- {
- if (unknownFullResPath)
+ if (ImGui.Checkbox("Force unknown _FULL_RES (Probably Useless)", ref unknownFullResPath))
{
- ssrRes3.Enable();
- }
- else
- {
- ssrRes3.Disable();
+ if (unknownFullResPath)
+ {
+ ssrRes3.Enable();
+ }
+ else
+ {
+ ssrRes3.Disable();
+ }
}
+
+ ImGui.Separator();
}
ImGui.PushItemWidth(width * 0.15f);
- ImGui.Text($"FPS: {MemoryUtil.GetRef<float>(sMain!.Instance + 0x68)}");
- ImGui.Text($"Delta Time: {MemoryUtil.GetRef<float>(sMain!.Instance + 0x94)}");
+ ImGui.Text($"FPS: {MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x68)}");
+ ImGui.Text($"Delta Time: {MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x94)}");
// Locations taken from MHW-DTI-Dumps/wip_dump_15_20_00.h.
- ImGui.InputFloat("Simulation FPS", ref MemoryUtil.GetRef<float>(sMain!.Instance + 0x58));
+ ImGui.InputFloat("Simulation FPS", ref MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x58));
if (ImGui.BeginItemTooltip())
{
ImGui.Text("This does not apply to jiggle physics.");
ImGui.EndTooltip();
}
- ImGui.InputFloat("Max FPS", ref MemoryUtil.GetRef<float>(sMain!.Instance + 0x5C));
+ ImGui.InputFloat("Max FPS", ref MemoryUtil.GetRef<float>(sMhMain!.Instance + 0x5C));
ImGui.PopItemWidth();
}
}
@@ -4031,7 +4082,15 @@ namespace WorldTuningTool public unsafe void OnCreateShader(ShaderInfo *info)
{
string hash = new string(info->DxbcHash);
- if (hash == "9ff245fb-4fd555e0-04d0ef15-84609fe1")
+ 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"))
{
diff --git a/Shaders/Original/alpha_as_luma.dxbc.xz b/Shaders/Original/alpha_as_luma.dxbc.xz Binary files differnew file mode 100644 index 0000000..3ec9fa8 --- /dev/null +++ b/Shaders/Original/alpha_as_luma.dxbc.xz diff --git a/Shaders/alpha_as_luma.hlsl b/Shaders/alpha_as_luma.hlsl new file mode 100644 index 0000000..525f3c6 --- /dev/null +++ b/Shaders/alpha_as_luma.hlsl @@ -0,0 +1,58 @@ +// https://stackoverflow.com/a/37624009
+float inverseGamma(float t)
+{
+ return ((t <= 0.0404482362771076) ? (t/12.92) : pow((t + 0.055)/1.055, 2.4));
+}
+
+// CIE L*a*b* f function (used to convert XYZ to L*a*b*)
+// http://en.wikipedia.org/wiki/Lab_color_space
+float LABF(float t)
+{
+ return ((t >= 8.85645167903563082e-3) ? pow(t, (1.0/3.0)) : (841.0/108.0)*t + (4.0/29.0));
+}
+
+float rgbToCIEL(float3 p)
+{
+ float r = inverseGamma(p.r);
+ float g = inverseGamma(p.g);
+ float b = inverseGamma(p.b);
+
+ // Observer = 2°, Illuminant = D65
+ float y = 0.2125862307855955516*r + 0.7151703037034108499*g + 0.07220049864333622685*b;
+
+ // At this point we've done RGBtoXYZ now do XYZ to Lab
+
+ // y /= WHITEPOINT_Y; The white point for y in D65 is 1.0
+ y = LABF(y);
+
+ // This is the "normal" conversion which produces values scaled to 100
+ // Lab.L = 116.0*y - 16.0;
+ return 1.16*y - 0.16;
+}
+
+// ---- Created with 3Dmigoto v1.4.9 on Sun Jun 28 13:42:41 2026
+
+cbuffer CBSystem : register(b3)
+{
+ uint4 iRegion : packoffset(c0);
+ float fSourceMipLevel : packoffset(c1) = {0};
+ float fGammaCorrect : packoffset(c1.y) = {0.454545468};
+ float fGammaCorrectEx : packoffset(c1.z) = {1};
+}
+
+SamplerState SSSystemCopy : register(s0);
+Texture2D<float4> tBaseMap : register(t0);
+
+void main(
+ float4 v0 : SV_POSITION0,
+ float2 v1 : TexCoord0,
+ out float4 o0 : SV_TARGET0)
+{
+ float4 r0;
+ r0.xyz = tBaseMap.SampleLevel(SSSystemCopy, v1.xy, fSourceMipLevel).xyz;
+ o0.w = rgbToCIEL(r0.xyz);
+ //o0.w = sqrt(dot(r0.xyz, float3(0.298999995, 0.587000012, 0.114)));
+ //o0.w = dot(r0.xyz, float3(0.298999995, 0.587000012, 0.114));
+ o0.xyz = r0.xyz;
+ return;
+}
|