diff --git a/src/games/thewitness/addon.cpp b/src/games/thewitness/addon.cpp index b2a0c549..f967c790 100644 --- a/src/games/thewitness/addon.cpp +++ b/src/games/thewitness/addon.cpp @@ -126,6 +126,28 @@ renodx::utils::settings::Settings settings = { .max = 100.f, .parse = [](float value) { return value * 0.02f; }, }, + new renodx::utils::settings::Setting{ + .key = "colorGradeBlowout", + .binding = &shader_injection.colorGradeBlowout, + .default_value = 0.f, + .label = "Blowout", + .section = "Color Grading", + .tooltip = "Controls highlight desaturation due to overexposure.", + .max = 100.f, + .is_enabled = []() { return shader_injection.toneMapType == 3; }, + .parse = [](float value) { return value * 0.01f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeFlare", + .binding = &shader_injection.colorGradeFlare, + .default_value = 0.f, + .label = "Flare", + .section = "Color Grading", + .tooltip = "Flare/Glare", + .max = 100.f, + .is_enabled = []() { return shader_injection.toneMapType == 3; }, + .parse = [](float value) { return value * 0.02f; }, + }, new renodx::utils::settings::Setting{ .key = "colorGradeLUTStrength", .binding = &shader_injection.colorGradeLUTStrength, @@ -145,6 +167,25 @@ renodx::utils::settings::Settings settings = { .max = 100.f, .parse = [](float value) { return value * 0.01f; }, }, + new renodx::utils::settings::Setting{ + .key = "fxAutoExposure", + .binding = &shader_injection.fxAutoExposure, + .default_value = 100.f, + .label = "Auto Exposure", + .section = "Effects", + .max = 100.f, + .parse = [](float value) { return value * 0.01f; }, + }, + new renodx::utils::settings::Setting{ + .key = "fxBloom", + .binding = &shader_injection.fxBloom, + .default_value = 50.f, + .label = "Bloom", + .section = "Effects", + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + }; void OnPresetOff() { @@ -160,6 +201,8 @@ void OnPresetOff() { renodx::utils::settings::UpdateSetting("colorGradeSaturation", 50.f); renodx::utils::settings::UpdateSetting("colorGradeLUTStrength", 100.f); renodx::utils::settings::UpdateSetting("colorGradeLUTScaling", 0.f); + renodx::utils::settings::UpdateSetting("fxAutoExposure", 100.f); + renodx::utils::settings::UpdateSetting("fxBloom", 50.f); } } // namespace diff --git a/src/games/thewitness/game_render_0x5F92E474.ps_4_0.hlsl b/src/games/thewitness/game_render_0x5F92E474.ps_4_0.hlsl index d71358f2..9a8459f9 100644 --- a/src/games/thewitness/game_render_0x5F92E474.ps_4_0.hlsl +++ b/src/games/thewitness/game_render_0x5F92E474.ps_4_0.hlsl @@ -1,26 +1,19 @@ -// ---- Created with 3Dmigoto v1.3.16 on Sat May 4 23:53:53 2024 +#include "./shared.h" + Texture2D t0 : register(t0); SamplerState s0_s : register(s0); -cbuffer cb0 : register(b0) -{ - float4 cb0[4]; -} - - - +cbuffer cb0 : register(b0) { float4 cb0[4]; } // 3Dmigoto declarations #define cmp - - -void main( - float4 v0 : TEXCOORD0, - float4 v1 : TEXCOORD1, - out float4 o0 : SV_Target0) -{ - float4 r0,r1,r2,r3,r4,r5,r6,r7,r8; +void main(float4 v0 + : TEXCOORD0, float4 v1 + : TEXCOORD1, out float4 o0 + : SV_Target0) { + float4 r0, r1, r2, r3, r4, r5, r6, r7, r8; uint4 bitmask, uiDest; float4 fDest; @@ -82,7 +75,7 @@ void main( r1.x = saturate(abs(r1.z) * r1.x); r1.z = r1.y ? cb0[0].x : 0; r2.w = r1.y ? 0 : cb0[0].y; - r3.yz = r2.yy * float2(0.5,0.5) + v0.xy; + r3.yz = r2.yy * float2(0.5, 0.5) + v0.xy; r3.y = r1.y ? v0.x : r3.y; r3.z = r1.y ? r3.z : v0.y; r4.x = r3.y + -r1.z; @@ -190,7 +183,7 @@ void main( r1.z = r1.y ? r1.z : r2.x; r2.x = -v0.y + r6.y; r1.w = r1.y ? r1.w : r2.x; - r2.xw = cmp(r3.yx < float2(0,0)); + r2.xw = cmp(r3.yx < float2(0, 0)); r3.x = r1.w + r1.z; r2.xz = cmp((int2)r2.zz != (int2)r2.xw); r2.w = 1 / r3.x; @@ -210,6 +203,11 @@ void main( } o0.xyzw = r0.xyzw; o0.rgb = inputColor; - o0.rgb *= 203.f/80.f; + + if (injectedData.toneMapGammaCorrection) { + o0.rgb = renodx::color::correct::GammaSafe(o0.rgb); + } + + o0.rgb *= injectedData.toneMapGameNits / 80.f; return; } \ No newline at end of file diff --git a/src/games/thewitness/lut_0x415DFB3A.ps_4_0.hlsl b/src/games/thewitness/lut_0x415DFB3A.ps_4_0.hlsl index 8ab6e029..41edd56d 100644 --- a/src/games/thewitness/lut_0x415DFB3A.ps_4_0.hlsl +++ b/src/games/thewitness/lut_0x415DFB3A.ps_4_0.hlsl @@ -1,3 +1,5 @@ +#include "./shared.h" + // ---- Created with 3Dmigoto v1.3.16 on Sat May 4 23:53:52 2024 Texture3D t5 : register(t5); @@ -23,27 +25,19 @@ SamplerState s1_s : register(s1); SamplerState s0_s : register(s0); -cbuffer cb1 : register(b1) -{ - float4 cb1[14]; -} - - - +cbuffer cb1 : register(b1) { float4 cb1[14]; } // 3Dmigoto declarations #define cmp - - -void main( - float2 v0 : TEXCOORD0, - float w0 : TEXCOORD4, - float2 v1 : TEXCOORD1, - float2 w1 : TEXCOORD2, - float2 v2 : TEXCOORD3, - out float4 o0 : SV_Target0) -{ - float4 r0,r1,r2; +void main(float2 v0 + : TEXCOORD0, float w0 + : TEXCOORD4, float2 v1 + : TEXCOORD1, float2 w1 + : TEXCOORD2, float2 v2 + : TEXCOORD3, out float4 o0 + : SV_Target0) { + float4 r0, r1, r2; uint4 bitmask, uiDest; float4 fDest; @@ -60,11 +54,12 @@ void main( r0.z = 0.000143612138 * r0.z; r0.z = min(16, r0.z); r0.xy = r0.xy * r0.zz; - r0.xyzw = t0.SampleGrad(s0_s, v0.xy, r0.xyxx, float4(0,0,0,0)).xyzw; + r0.xyzw = t0.SampleGrad(s0_s, v0.xy, r0.xyxx, float4(0, 0, 0, 0)).xyzw; } else { r0.xyzw = t0.Sample(s0_s, v0.xy).xyzw; } - float3 inputColor= r0.rgb; + float3 testColor = r0.rgb; + r1.xyzw = t3.Sample(s3_s, v0.xy).xyzw; r0.w = -cb1[13].x + r1.x; r0.w = cb1[13].y / r0.w; @@ -72,11 +67,21 @@ void main( r0.w = -cb1[13].z + r0.w; r1.w = cb1[13].w + -cb1[13].z; r0.w = saturate(r0.w / r1.w); + r1.xyz = r1.xyz + -r0.xyz; r0.xyz = r0.www * r1.xyz + r0.xyz; + // r0.xyz = w0.xzz * r0.xyz; - r0.xyz = w0.x * r0.xyz; - r0.xyz = min(float3(1024,1024,1024), r0.xyz); + // bad decompile + + // r0.xyz = w0.x * r0.xyz; + + r0.xyz *= lerp(1.f, w0.x, injectedData.fxAutoExposure); + + // r0.xyz = min(float3(1024, 1024, 1024), r0.xyz); + // remove clamp + + r0.xyz = min(float3(1024, 1024, 1024), r0.xyz); r0.w = max(r0.x, r0.y); r1.x = max(0.00999999978, r0.z); r0.w = max(r1.x, r0.w); @@ -99,28 +104,105 @@ void main( r1.y = 1 / r1.y; r1.x = r1.x * r1.y; r0.w = r1.x / r0.w; + + // Bloom r1.xyzw = t1.Sample(s1_s, w1.xy).xyzw; r1.xyz = cb1[9].xxx * r1.xyz; - r0.xyz = r0.xyz * r0.www + r1.xyz; - r0.w = cmp(0 < cb1[9].y); - if (r0.w != 0) { - r1.xyzw = t2.Sample(s2_s, w1.xy).xyzw; - r0.xyz = r1.xyz * cb1[9].yyy + r0.xyz; + + if (injectedData.toneMapType == 0.f) { + // Tonemap + r0.xyz = r0.xyz * r0.www + r1.xyz * injectedData.fxBloom; + r0.w = cmp(0 < cb1[9].y); + if (r0.w != 0) { + r1.xyzw = t2.Sample(s2_s, w1.xy).xyzw; + r0.xyz = r1.xyz * cb1[9].yyy + r0.xyz; + } + + float3 input_color = r0.xyz; + + r0.xyz = saturate(r0.xyz); + r0.xyz = log2(r0.xyz); + r0.xyz = float3(0.454545468, 0.454545468, 0.454545468) * r0.xyz; + r0.xyz = exp2(r0.xyz); + r1.xyzw = t4.Sample(s4_s, r0.xyz).xyzw; + r0.xyzw = t5.Sample(s5_s, r0.xyz).xyzw; + r0.xyz = r0.xyz + -r1.xyz; + r0.xyz = saturate(cb1[11].xxx * r0.xyz + r1.xyz); + + // r0.xyz = t * (b - a) + a + // r0.xyz = cb1[11].xxx * (r0.xyz + -r1.xyz) + (r1.xyz) + + r0.xyz = log2(r0.xyz); + r0.xyz = float3(2.20000005, 2.20000005, 2.20000005) * r0.xyz; + r0.xyz = exp2(r0.xyz); + + r0.xyz = lerp(input_color, r0.xyz, injectedData.colorGradeLUTStrength); + + } else { + float vanillaMidGray = 0.18f * r0.w; + // Add bloom to untonemapped + r0.xyz = r0.xyz + (r1.xyz * injectedData.fxBloom); + + // Add unknown to untonemapped + r0.w = cmp(0 < cb1[9].y); + if (r0.w != 0) { + r1.xyzw = t2.Sample(s2_s, w1.xy).xyzw; + r0.xyz = r1.xyz * cb1[9].yyy + r0.xyz; + } + + float3 untonemapped = r0.xyz; + + renodx::tonemap::Config config = renodx::tonemap::config::Create(); + config.type = injectedData.toneMapType; + config.peak_nits = injectedData.toneMapPeakNits; + config.game_nits = injectedData.toneMapGameNits; + config.gamma_correction = injectedData.toneMapGammaCorrection; + config.exposure = injectedData.colorGradeExposure; + config.highlights = injectedData.colorGradeHighlights; + config.shadows = injectedData.colorGradeShadows; + config.contrast = injectedData.colorGradeContrast; + config.saturation = injectedData.colorGradeSaturation; + config.mid_gray_value = vanillaMidGray; + config.mid_gray_nits = vanillaMidGray * 100.f; + + config.reno_drt_highlights = 1.4f; + config.reno_drt_shadows = 1.0f; + config.reno_drt_contrast = 1.00f; + config.reno_drt_saturation = 1.00f; + config.reno_drt_dechroma = injectedData.colorGradeBlowout; + config.reno_drt_flare = lerp(0, 0.10, pow(injectedData.colorGradeFlare, 10.f)); + + renodx::tonemap::config::DualToneMap dual_tone_map = + renodx::tonemap::config::ApplyToneMaps(untonemapped, config); + + float3 hdr_color = dual_tone_map.color_hdr; + float3 sdr_color = dual_tone_map.color_sdr; + + renodx::lut::Config lut_config = renodx::lut::config::Create( + s4_s, 1.f, injectedData.colorGradeLUTScaling, + renodx::lut::config::type::GAMMA_2_2, + renodx::lut::config::type::GAMMA_2_2); + + float3 lut_color_a = renodx::lut::Sample(t4, lut_config, sdr_color); + lut_config.lut_sampler = s5_s; + float3 lut_color_b = renodx::lut::Sample(t5, lut_config, sdr_color); + + float3 lut_color = lerp(lut_color_a, lut_color_b, cb1[11].x); + + float3 final_color = renodx::tonemap::UpgradeToneMap( + hdr_color, sdr_color, lut_color, injectedData.colorGradeLUTStrength); + + + r0.xyz = final_color; + + if (injectedData.toneMapType == 1.f) { + r0.xyz = untonemapped; + } } - r0.xyz = saturate(r0.xyz); - r0.xyz = log2(r0.xyz); - r0.xyz = float3(0.454545468,0.454545468,0.454545468) * r0.xyz; - r0.xyz = exp2(r0.xyz); - r1.xyzw = t4.Sample(s4_s, r0.xyz).xyzw; - r0.xyzw = t5.Sample(s5_s, r0.xyz).xyzw; - r0.xyz = r0.xyz + -r1.xyz; - r0.xyz = saturate(cb1[11].xxx * r0.xyz + r1.xyz); - r0.xyz = log2(r0.xyz); - r0.xyz = float3(2.20000005,2.20000005,2.20000005) * r0.xyz; - r0.xyz = exp2(r0.xyz); + r0.w = dot(v2.xy, v2.xy); r1.xy = cb1[7].zw * v0.xy; - r1.x = dot(r1.xy, float2(0.0671110004,0.00583699998)); + r1.x = dot(r1.xy, float2(0.0671110004, 0.00583699998)); r1.x = frac(r1.x); r1.x = 52.9829178 * r1.x; r1.x = frac(r1.x); @@ -143,9 +225,10 @@ void main( r1.xyz = r0.xyz * r1.xxx + -r0.xyz; r1.xyz = cb1[12].yyy * r1.xyz + r0.xyz; r0.xyz = r0.www ? r1.xyz : r0.xyz; - r0.w = saturate(dot(r0.xyz, float3(0.298999995,0.587000012,0.114))); + r0.w = saturate(dot(r0.xyz, float3(0.298999995, 0.587000012, 0.114))); o0.w = sqrt(r0.w); o0.xyz = r0.xyz; - // o0.rgb = inputColor.rgb; + + // o0.rgb = testColor.rgb; return; } \ No newline at end of file diff --git a/src/games/thewitness/shared.h b/src/games/thewitness/shared.h index 148f3d55..2eef2ba2 100644 --- a/src/games/thewitness/shared.h +++ b/src/games/thewitness/shared.h @@ -18,8 +18,12 @@ struct ShaderInjectData { float colorGradeShadows; float colorGradeContrast; float colorGradeSaturation; + float colorGradeBlowout; + float colorGradeFlare; float colorGradeLUTStrength; float colorGradeLUTScaling; + float fxAutoExposure; + float fxBloom; }; #ifndef __cplusplus