From 0351bbae1ced879246e27ffa1eaa1e7c0b5942cf Mon Sep 17 00:00:00 2001 From: Musa Haji <131800246+mqhaji@users.noreply.github.com> Date: Sat, 11 Jan 2025 10:39:26 -0500 Subject: [PATCH 01/12] feat(tonemap): add GTTonemap (#109) --- src/shaders/tonemap.hlsl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/shaders/tonemap.hlsl b/src/shaders/tonemap.hlsl index 542b2b11..9f117dbf 100644 --- a/src/shaders/tonemap.hlsl +++ b/src/shaders/tonemap.hlsl @@ -109,6 +109,41 @@ float3 ACESFittedAP1(float3 color) { return color; } +// Uchimura 2018, "Practical HDR and Wide Color Techniques in Gran Turismo SPORT" +// https://www.desmos.com/calculator/gslcdxvipg +// http://cdn2.gran-turismo.com/data/www/pdi_publications/PracticalHDRandWCGinGTS.pdf +#define GTTONEMAP_GENERATOR(T) \ + T GTTonemap(T x, \ + float P = 1.f, \ + float a = 1.f, \ + float m = 0.22f, \ + float l = 0.4f, \ + float c = 1.33f, \ + float b = 0.f) { \ + float l0 = ((P - m) * l) / a; \ + float L0 = m - (m / a); \ + float L1 = m + (1.0f - m) / a; \ + \ + T S0 = m + l0; \ + T S1 = m + a * l0; \ + T C2 = (a * P) / (P - S1); \ + T CP = -C2 / P; \ + \ + T w0 = 1.0f - smoothstep(0.0f, m, x); \ + T w2 = step(m + l0, x); \ + T w1 = 1.0f - w0 - w2; \ + \ + T T_ = m * pow(x / m, c) + b; \ + T S_ = P - (P - S1) * exp(CP * (x - S0)); \ + T L_ = m + a * (x - m); \ + \ + return T_ * w0 + L_ * w1 + S_ * w2; \ + } + +GTTONEMAP_GENERATOR(float) +GTTONEMAP_GENERATOR(float3) +#undef GTTONEMAP_GENERATOR + // https://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting // http://filmicworlds.com/blog/filmic-tonemapping-operators/ From a85ba85a361381e29addcc1aa9d20c3816d60f85 Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Sun, 22 Dec 2024 01:53:48 +0400 Subject: [PATCH 02/12] feat(stalker2): Add per channel option, refactor code to centralized common file --- src/games/stalker2/addon.cpp | 18 ++- src/games/stalker2/common.hlsl | 146 ++++++++++++++++++ .../crouch_vignette_0xFAD704A3.ps_6_6.hlsl | 8 +- .../stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl | 8 +- .../lutbuilder_0x6CFBD4C0.ps_6_6.hlsl | 35 +---- .../lutbuilder_0xB6CA5FD9.ps_6_6.hlsl | 37 +---- .../lutbuilder_0xBAA27141.ps_6_6.hlsl | 26 +--- .../stalker2/output_0x20685247.ps_6_6.hlsl | 2 +- .../stalker2/output_0x2DAD4682.ps_6_6.hlsl | 2 +- .../stalker2/output_0x39EF727B.ps_6_6.hlsl | 2 +- .../stalker2/output_0x4D3C673E.ps_6_6.hlsl | 2 +- .../stalker2/output_0xECD0D71A.ps_6_6.hlsl | 2 +- .../postprocess02_0xED411D4E.ps_6_6.hlsl | 8 +- .../radiation01_0x5590F787.ps_6_6.hlsl | 8 +- src/games/stalker2/shared.h | 1 + src/games/stalker2/tonemapper.hlsl | 77 --------- .../vignette02_0x04532088.ps_6_6.hlsl | 8 +- 17 files changed, 203 insertions(+), 187 deletions(-) create mode 100644 src/games/stalker2/common.hlsl delete mode 100644 src/games/stalker2/tonemapper.hlsl diff --git a/src/games/stalker2/addon.cpp b/src/games/stalker2/addon.cpp index b17c9e2e..183e2c6f 100644 --- a/src/games/stalker2/addon.cpp +++ b/src/games/stalker2/addon.cpp @@ -84,6 +84,17 @@ renodx::utils::settings::Settings settings = { .min = 48.f, .max = 500.f, }, + new renodx::utils::settings::Setting{ + .key = "ToneMapPerChannel", + .binding = &shader_injection.toneMapPerChannel, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Per Channel", + .section = "Tone Mapping", + .tooltip = "Applies tonemapping per-channel instead of by luminance (More accurate to SDR but less saturated)", + .labels = {"Off", "On"}, + .is_enabled = []() { return shader_injection.toneMapType == 3; }, + }, new renodx::utils::settings::Setting{ .key = "radiationOverlayStrength", .binding = &shader_injection.radiationOverlayStrength, @@ -148,7 +159,7 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.02f; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeBlowout", + .key = "ColorGradeBlowout", .binding = &shader_injection.colorGradeBlowout, .default_value = 50.f, .label = "Blowout", @@ -156,7 +167,7 @@ renodx::utils::settings::Settings settings = { .tooltip = "Controls highlight desaturation due to overexposure.", .max = 100.f, .is_enabled = []() { return shader_injection.toneMapType == 3; }, - .parse = [](float value) { return value * 0.01f; }, + .parse = [](float value) { return value * 0.02f - 1.f; }, }, new renodx::utils::settings::Setting{ .key = "colorGradeLUTStrength", @@ -170,7 +181,7 @@ renodx::utils::settings::Settings settings = { }, new renodx::utils::settings::Setting{ .value_type = renodx::utils::settings::SettingValueType::TEXT, - .label = " - Ingame HDR must be turned ON! \r\n - Lower contrast if game's too dark. \r\n - (Optional) Disable reshade's default add ons (Generic depth & Effect runtime sync) to restore lost performance", + .label = " - Ingame HDR must be turned ON! \r\n - Lower contrast if game's too dark. \r\n - Game's Gamma option still affects UI!. \r\n - (Optional) Disable reshade's default add ons (Generic depth & Effect runtime sync) to restore lost performance", .section = "Instructions", }, new renodx::utils::settings::Setting{ @@ -239,6 +250,7 @@ void OnPresetOff() { renodx::utils::settings::UpdateSetting("colorGradeContrast", 50.f); renodx::utils::settings::UpdateSetting("colorGradeSaturation", 50.f); renodx::utils::settings::UpdateSetting("colorGradeLUTStrength", 100.f); + renodx::utils::settings::UpdateSetting("colorGradeBlowout", 0.f); } } // namespace diff --git a/src/games/stalker2/common.hlsl b/src/games/stalker2/common.hlsl new file mode 100644 index 00000000..60b26aca --- /dev/null +++ b/src/games/stalker2/common.hlsl @@ -0,0 +1,146 @@ +#include "./shared.h" + +static const float DEFAULT_BRIGHTNESS = 0.f; // 50% +static const float DEFAULT_CONTRAST = 1.f; // 50% +static const float DEFAULT_GAMMA = 1.1f; // Approximately 44% + +float3 CorrectGamma(float3 color) { + color = renodx::color::correct::GammaSafe(color); + return color; +} + +float3 DecodedTosRGB(float3 input_linear) { + if (injectedData.toneMapType > 1.f) { + input_linear = renodx::color::srgb::EncodeSafe(saturate(input_linear)); + input_linear = saturate(input_linear); + } + return input_linear; +} + +float3 PQToDecoded(float3 input_pq) { + float3 output = input_pq; + if (injectedData.toneMapType > 1.f) { + output = renodx::color::pq::Decode(input_pq, injectedData.toneMapGameNits); + } + + return output; +} + +float3 UpgradePostProcess(float3 tonemappedRender, float3 post_processed, float lerpValue = 1.f) { + float3 output = post_processed; + if (injectedData.toneMapType == 1.f) { + output = tonemappedRender; + } else if (injectedData.toneMapType > 1.f) { + if (lerpValue == 0.f) { + output = renodx::color::pq::Encode(tonemappedRender, injectedData.toneMapGameNits); + } else { + post_processed = renodx::color::srgb::DecodeSafe(post_processed); + output = renodx::tonemap::UpgradeToneMap(tonemappedRender, saturate(tonemappedRender), saturate(post_processed), lerpValue); + output = renodx::color::pq::Encode(output, injectedData.toneMapGameNits); + } + } + + return output; +} + +// Adjust this function as needed +float3 ProcessLUT(SamplerState sampler, Texture2D texture, float3 color) { + renodx::lut::Config lut_config = renodx::lut::config::Create( + sampler, + injectedData.toneMapType == 2.f ? 0.f : injectedData.colorGradeLUTStrength, + 0.f, + renodx::lut::config::type::SRGB, + renodx::lut::config::type::SRGB, + 16.f); + + return renodx::lut::Sample(texture, lut_config, color); +} + +bool TonemapConditon(uint output_type = 3u) { + return injectedData.toneMapType != 0.f && (output_type >= 3u && output_type <= 6u); +} + +// Adjust this function as needed +void Tonemap(in float3 ap1_graded_color, in float3 ap1_aces_colored, out float3 hdr_color, out float3 sdr_color, inout float3 sdr_ap1_color) { + 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 = 1.f; + config.exposure = injectedData.colorGradeExposure; + config.highlights = injectedData.colorGradeHighlights; + config.shadows = injectedData.colorGradeShadows; + config.contrast = injectedData.colorGradeContrast; + config.saturation = injectedData.colorGradeSaturation; + + if (injectedData.toneMapPerChannel == 1.f) { + config.reno_drt_per_channel = true; + } + + config.reno_drt_highlights = 1.0f; + config.reno_drt_shadows = 1.0f; + // config.reno_drt_contrast = 1.1f; + config.reno_drt_saturation = 1.1f; + config.reno_drt_dechroma = 0; + config.reno_drt_blowout = injectedData.colorGradeBlowout; + // config.reno_drt_flare = 0.05f; + config.reno_drt_working_color_space = 2u; + + float3 bt709_graded_color = renodx::color::bt709::from::AP1(ap1_graded_color); + float3 bt709_aces_color = renodx::color::bt709::from::AP1(ap1_aces_colored); + + config.hue_correction_type = + renodx::tonemap::config::hue_correction_type::CUSTOM; + config.hue_correction_color = bt709_aces_color; + + // config.hue_correction_color = color; + /* if (injectedData.toneMapHueCorrectionMethod == 1.f) { + config.hue_correction_color = renodx::tonemap::ACESFittedAP1(bt709_graded_color); + } else if (injectedData.toneMapHueCorrectionMethod == 2.f) { + config.hue_correction_color = renodx::tonemap::uncharted2::BT709(bt709_graded_color * 2.f); + } else if (injectedData.toneMapHueCorrectionMethod == 3.f) { + config.hue_correction_color = bt709_aces_color; + } else { + config.hue_correction_type = + renodx::tonemap::config::hue_correction_type::INPUT; + } */ + + renodx::tonemap::config::DualToneMap dual_tone_map = renodx::tonemap::config::ApplyToneMaps(bt709_graded_color, config); + hdr_color = dual_tone_map.color_hdr; + sdr_color = dual_tone_map.color_sdr; + sdr_ap1_color = renodx::color::ap1::from::BT709(sdr_color); +} + +// CorrectGamma in final shader causes bugs to FSR3 FG +void FinalizeTonemap(inout float3 final_color, in float3 film_graded_color, in float3 hdr_color, in float3 sdr_color) { + final_color = saturate(film_graded_color); + + if (injectedData.toneMapType != 1.f) { + final_color = renodx::tonemap::UpgradeToneMap(hdr_color, sdr_color, final_color, 1.f); + } else { + final_color = hdr_color; + } + final_color = renodx::color::bt2020::from::BT709(final_color); + final_color = CorrectGamma(final_color); + final_color = renodx::color::pq::Encode(final_color, injectedData.toneMapGameNits); +} + +// For SDR -> HDR games +float3 FinalizeOutput(float3 color) { + color = renodx::color::gamma::DecodeSafe(color); + color *= injectedData.toneMapUINits; + color = min(color, injectedData.toneMapPeakNits); // Clamp UI or Videos + + color /= 80.f; // or PQ + return color; +} + +// For SDR -> HDR games +float3 ScalePaperWhite(float3 color) { + color = renodx::color::srgb::EncodeSafe(color); + color = renodx::color::gamma::DecodeSafe(color); + color *= injectedData.toneMapGameNits / injectedData.toneMapUINits; + color = renodx::color::gamma::EncodeSafe(color); + + return color.rgb; +} diff --git a/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl b/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl index 5fd6db44..13d96ce8 100644 --- a/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl +++ b/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D PostProcessInput_0_Texture : register(t0); @@ -45,8 +45,8 @@ float4 main( float4 _35 = PostProcessInput_0_Texture.Sample(PostProcessInput_0_Sampler, float2(((_21 * ($Globals_005x)) + ($Globals_004x)), ((_22 * ($Globals_005y)) + ($Globals_004y)))); if (injectedData.toneMapType > 0.f) { // We decode before they attempt to blend - tonemappedRender = pqToDecoded(_35.rgb); - srgb_input = decodedTosRGB(tonemappedRender); + tonemappedRender = PQToDecoded(_35.rgb); + srgb_input = DecodedTosRGB(tonemappedRender); _35.rgb = srgb_input; } float _45 = (abs(((UniformBufferConstants_Material_001y) * (_21 + -0.5f)))) * 2.0f; @@ -62,7 +62,7 @@ float4 main( post_srgb = SV_Target.rgb; if (injectedData.toneMapType > 0.f) { - output = upgradePostProcess(tonemappedRender, post_srgb); + output = UpgradePostProcess(tonemappedRender, post_srgb); return float4(output, 0.f); } SV_Target.w = 0.0f; diff --git a/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl b/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl index 4b4d04ec..0137fa76 100644 --- a/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl +++ b/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D UITexture : register(t0); @@ -81,13 +81,13 @@ float4 main( // _57 = _1; // _58 = _3; - // Scene will always be PQ sRGB bt709 + // We don't use finalize here because it messes up with FSR3 FG float4 _59 = SceneTexture.Sample(SceneSampler, float2(_7, _8)); float3 scene = _59.rgb; scene = renodx::color::pq::Decode(scene.rgb, injectedData.toneMapGameNits); - uiTexture.rgb = correctGamma(uiTexture.rgb); + uiTexture.rgb = CorrectGamma(uiTexture.rgb); - // Multiple by games because we're encoding PQ later + // Multiply by game's because we're encoding PQ later uiTexture.rgb = uiTexture.rgb * injectedData.toneMapUINits / injectedData.toneMapGameNits; _54 = uiTexture.r; diff --git a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl index cf7c5776..6c8c97d5 100644 --- a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D Textures_1 : register(t0); @@ -176,8 +176,7 @@ float4 main( // _6 = _4; // CustomEdit uint output_type = _RootShaderParameters_040w; - bool is_hdr = (output_type >= 3u && output_type <= 6u); - bool shouldTonemap = injectedData.toneMapType != 0.f && is_hdr; + bool shouldTonemap = TonemapConditon(output_type); uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; float _9 = TEXCOORD.y; @@ -958,15 +957,7 @@ float4 main( float _723 = _RootShaderParameters_037z; float _724 = _722 - _723; if (shouldTonemap) { - renodx::tonemap::Config config = getCommonConfig(); - config.hue_correction_color = ap1_aces_colored; - - float3 config_color = renodx::color::bt709::from::AP1(ap1_graded_color); - - renodx::tonemap::config::DualToneMap dual_tone_map = renodx::tonemap::config::ApplyToneMaps(config_color, config); - hdr_color = dual_tone_map.color_hdr; - sdr_color = dual_tone_map.color_sdr; - sdr_ap1_color = renodx::color::ap1::from::BT709(sdr_color); + Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); } else { bool _725 = (_718 > 0.800000011920929f); float _726 = _RootShaderParameters_037x; @@ -1167,15 +1158,8 @@ float4 main( float _1013; // custom branch if (shouldTonemap) { - renodx::lut::Config lut_config = renodx::lut::config::Create( - Samplers_1, - injectedData.toneMapType == 2.f ? 0.f : injectedData.colorGradeLUTStrength, - 1.f, // We don't need to scale LUTs, but might as well - renodx::lut::config::type::SRGB, - renodx::lut::config::type::SRGB, - 16.f); + float3 post_lut_color = ProcessLUT(Samplers_1, Textures_1, lut_input_color); - float3 post_lut_color = renodx::lut::Sample(Textures_1, lut_config, lut_input_color); _1011 = post_lut_color.r; _1012 = post_lut_color.g; _1013 = post_lut_color.b; @@ -1371,16 +1355,7 @@ float4 main( float3 final_color = film_graded_color; // We return sRGB bt709 color if (shouldTonemap) { - final_color = saturate(film_graded_color); - - if (injectedData.toneMapType != 1.f) { - final_color = renodx::tonemap::UpgradeToneMap(hdr_color, sdr_color, final_color, 1.f); - } else { - final_color = hdr_color; - } - final_color = renodx::color::bt2020::from::BT709(final_color); - final_color = correctGamma(final_color); - final_color = renodx::color::pq::Encode(final_color, injectedData.toneMapGameNits); + FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); return float4(final_color, 0.f); } diff --git a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl index 21eda6f8..eac9cca8 100644 --- a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl @@ -1,5 +1,6 @@ +#include "./common.hlsl" #include "./shared.h" -#include "./tonemapper.hlsl" + Texture2D Textures_1 : register(t0); @@ -197,8 +198,7 @@ float4 main( // _6 = _4; // CustomEdit uint output_type = _RootShaderParameters_040w; - bool is_hdr = (output_type >= 3u && output_type <= 6u); - bool shouldTonemap = injectedData.toneMapType != 0.f && is_hdr; + bool shouldTonemap = TonemapConditon(output_type); uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; float _9 = TEXCOORD.y; @@ -1232,15 +1232,7 @@ float4 main( float _977 = _RootShaderParameters_037z; float _978 = _976 - _977; if (shouldTonemap) { - renodx::tonemap::Config config = getCommonConfig(); - config.hue_correction_color = ap1_aces_colored; - - float3 config_color = renodx::color::bt709::from::AP1(ap1_graded_color); - - renodx::tonemap::config::DualToneMap dual_tone_map = renodx::tonemap::config::ApplyToneMaps(config_color, config); - hdr_color = dual_tone_map.color_hdr; - sdr_color = dual_tone_map.color_sdr; - sdr_ap1_color = renodx::color::ap1::from::BT709(sdr_color); + Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); } else { bool _979 = (_972 > 0.800000011920929f); float _980 = _RootShaderParameters_037x; @@ -1444,15 +1436,7 @@ float4 main( // We skip ACES cuz the LUT exasexacerbates the contrast if (injectedData.toneMapType > 1.f) { - renodx::lut::Config lut_config = renodx::lut::config::Create( - Samplers_1, - injectedData.toneMapType == 2.f ? 0.f : injectedData.colorGradeLUTStrength, - 1.f, // (LUT Scaling) We don't need to scale the LUTs here, but might as well - renodx::lut::config::type::SRGB, - renodx::lut::config::type::SRGB, - 16.f); - - float3 post_lut_color = renodx::lut::Sample(Textures_1, lut_config, lut_input_color); + float3 post_lut_color = ProcessLUT(Samplers_1, Textures_1, lut_input_color); _1265 = post_lut_color.r; _1266 = post_lut_color.g; @@ -1644,16 +1628,7 @@ float4 main( float3 final_color = film_graded_color; // We return sRGB bt709 color if (shouldTonemap) { - final_color = saturate(film_graded_color); - - if (injectedData.toneMapType != 1.f) { - final_color = renodx::tonemap::UpgradeToneMap(hdr_color, sdr_color, final_color, 1.f); - } else { - final_color = hdr_color; - } - final_color = renodx::color::bt2020::from::BT709(final_color); - final_color = correctGamma(final_color); - final_color = renodx::color::pq::Encode(final_color, injectedData.toneMapGameNits); + FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); return float4(final_color, 0.f); } diff --git a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl index 2ad69430..3ae5a82f 100644 --- a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl @@ -1,6 +1,7 @@ +#include "./common.hlsl" #include "./shared.h" -#include "./tonemapper.hlsl" + cbuffer _RootShaderParameters : register(b0) { float _RootShaderParameters_008x : packoffset(c008.x); @@ -168,8 +169,7 @@ float4 main( // _3 = _1; // _4 = _2; uint output_type = _RootShaderParameters_040w; - bool is_hdr = (output_type >= 3u && output_type <= 6u); - bool shouldTonemap = injectedData.toneMapType != 0.f && is_hdr; + bool shouldTonemap = TonemapConditon(output_type); uint _5 = SV_RenderTargetArrayIndex; float _6 = TEXCOORD.x; float _7 = TEXCOORD.y; @@ -948,14 +948,7 @@ float4 main( float _721 = _RootShaderParameters_037z; float _722 = _720 - _721; if (shouldTonemap) { - renodx::tonemap::Config config = getCommonConfig(); - - float3 config_color = renodx::color::bt709::from::AP1(ap1_graded_color); - - renodx::tonemap::config::DualToneMap dual_tone_map = renodx::tonemap::config::ApplyToneMaps(config_color, config); - hdr_color = dual_tone_map.color_hdr; - sdr_color = dual_tone_map.color_sdr; - sdr_ap1_color = renodx::color::ap1::from::BT709(sdr_color); + Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); } else { bool _723 = (_716 > 0.800000011920929f); float _724 = _RootShaderParameters_037x; @@ -1218,16 +1211,7 @@ float4 main( float3 final_color = film_graded_color; // We return sRGB bt709 color if (shouldTonemap) { - final_color = saturate(film_graded_color); - - if (injectedData.toneMapType != 1.f) { - final_color = renodx::tonemap::UpgradeToneMap(hdr_color, sdr_color, final_color, 1.f); - } else { - final_color = hdr_color; - } - final_color = renodx::color::bt2020::from::BT709(final_color); - final_color = correctGamma(final_color); - final_color = renodx::color::pq::Encode(final_color, injectedData.toneMapGameNits); + FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); return float4(final_color, 0.f); } diff --git a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl index cd72e585..2b6a78b8 100644 --- a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl index 508b32f5..804151cd 100644 --- a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl index f3374694..ec4ce441 100644 --- a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl index 675e8317..59df8af0 100644 --- a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl index 24a28e67..8db25213 100644 --- a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl +++ b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl b/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl index d0da3407..1aa6a634 100644 --- a/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl +++ b/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D SceneTexturesStruct_SceneDepthTexture : register(t0); @@ -450,8 +450,8 @@ float4 main( // We decode before they attempt to blend if (injectedData.toneMapType > 0.f) { // We decode before they attempt to blend - tonemappedRender = pqToDecoded(_351.rgb); - srgb_input = decodedTosRGB(tonemappedRender); + tonemappedRender = PQToDecoded(_351.rgb); + srgb_input = DecodedTosRGB(tonemappedRender); _351.rgb = srgb_input; } @@ -482,7 +482,7 @@ float4 main( post_srgb = float3(_373, _374, _375); if (injectedData.toneMapType > 0.f) { - output = upgradePostProcess(tonemappedRender, post_srgb); + output = UpgradePostProcess(tonemappedRender, post_srgb); return float4(output, 0.f); } diff --git a/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl b/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl index bc570667..08772e3e 100644 --- a/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl +++ b/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D Material_Texture2D_0 : register(t0); @@ -193,8 +193,8 @@ float4 main( float4 _136 = PostProcessInput_0_Texture.Sample(PostProcessInput_0_Sampler, float2(_132, _133)); if (injectedData.toneMapType > 0.f) { // We decode before they attempt to blend - tonemappedRender = pqToDecoded(_136.rgb); - srgb_input = decodedTosRGB(tonemappedRender); + tonemappedRender = PQToDecoded(_136.rgb); + srgb_input = DecodedTosRGB(tonemappedRender); _136.rgb = srgb_input; } @@ -407,7 +407,7 @@ float4 main( float _341 = max(_338, 0.0f); post_srgb = float3(_339, _340, _341); if (injectedData.toneMapType > 0.f) { - output = upgradePostProcess(tonemappedRender, post_srgb, injectedData.radiationOverlayStrength); + output = UpgradePostProcess(tonemappedRender, post_srgb, injectedData.radiationOverlayStrength); return float4(output, 0.f); } diff --git a/src/games/stalker2/shared.h b/src/games/stalker2/shared.h index f949a2a4..06e995eb 100644 --- a/src/games/stalker2/shared.h +++ b/src/games/stalker2/shared.h @@ -12,6 +12,7 @@ struct ShaderInjectData { float toneMapPeakNits; float toneMapGameNits; float toneMapUINits; + float toneMapPerChannel; float radiationOverlayStrength; float vignetteStrength; float colorGradeExposure; diff --git a/src/games/stalker2/tonemapper.hlsl b/src/games/stalker2/tonemapper.hlsl deleted file mode 100644 index 963c33e0..00000000 --- a/src/games/stalker2/tonemapper.hlsl +++ /dev/null @@ -1,77 +0,0 @@ -#include "./shared.h" - -static const float DEFAULT_BRIGHTNESS = 0.f; // 50% -static const float DEFAULT_CONTRAST = 1.f; // 50% -static const float DEFAULT_GAMMA = 1.1f; // Approximately 44% - -renodx::tonemap::Config getCommonConfig() { - float vanillaMidGray = 0.18f; - float renoDRTContrast = 1.f; - float renoDRTFlare = 0.f; - float renoDRTShadows = 1.f; - float renoDRTDechroma = injectedData.colorGradeBlowout; - float renoDRTSaturation = 1.f; - float renoDRTHighlights = 1.f; - - 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 = 1.f; - // We apply these in final shader - config.exposure = injectedData.colorGradeExposure; - config.highlights = injectedData.colorGradeHighlights; - config.shadows = injectedData.colorGradeShadows; - config.contrast = injectedData.colorGradeContrast; - config.saturation = injectedData.colorGradeSaturation; - - config.reno_drt_highlights = renoDRTHighlights; - config.reno_drt_shadows = renoDRTShadows; - config.reno_drt_contrast = renoDRTContrast; - config.reno_drt_saturation = renoDRTSaturation; - config.reno_drt_dechroma = renoDRTDechroma; - config.mid_gray_value = vanillaMidGray; - config.mid_gray_nits = vanillaMidGray * 100.f; - config.reno_drt_flare = renoDRTFlare; - return config; -} - -float3 correctGamma(float3 color) { - color = renodx::color::correct::GammaSafe(color); - return color; -} - -float3 decodedTosRGB(float3 input_linear) { - if (injectedData.toneMapType > 1.f) { - input_linear = renodx::color::srgb::EncodeSafe(saturate(input_linear)); - input_linear = saturate(input_linear); - } - return input_linear; -} - -float3 pqToDecoded(float3 input_pq) { - float3 output = input_pq; - if (injectedData.toneMapType > 1.f) { - output = renodx::color::pq::Decode(input_pq, injectedData.toneMapGameNits); - } - - return output; -} - -float3 upgradePostProcess(float3 tonemappedRender, float3 post_processed, float lerpValue = 1.f) { - float3 output = post_processed; - if (injectedData.toneMapType == 1.f) { - output = tonemappedRender; - } else if (injectedData.toneMapType > 1.f) { - if (lerpValue == 0.f) { - output = renodx::color::pq::Encode(tonemappedRender, injectedData.toneMapGameNits); - } else { - post_processed = renodx::color::srgb::DecodeSafe(post_processed); - output = renodx::tonemap::UpgradeToneMap(tonemappedRender, saturate(tonemappedRender), saturate(post_processed), lerpValue); - output = renodx::color::pq::Encode(output, injectedData.toneMapGameNits); - } - } - - return output; -} diff --git a/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl b/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl index bfa28acc..a02184d1 100644 --- a/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl +++ b/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl @@ -1,5 +1,5 @@ #include "./shared.h" -#include "./tonemapper.hlsl" +#include "./common.hlsl" Texture2D SceneTexturesStruct_SceneDepthTexture : register(t0); @@ -187,8 +187,8 @@ float4 main( float4 _125 = PostProcessInput_0_Texture.Sample(PostProcessInput_0_Sampler, float2(_121, _122)); if (injectedData.toneMapType > 0.f) { // We decode before they attempt to blend - tonemappedRender = pqToDecoded(_125.rgb); - srgb_input = decodedTosRGB(tonemappedRender); + tonemappedRender = PQToDecoded(_125.rgb); + srgb_input = DecodedTosRGB(tonemappedRender); _125.rgb = srgb_input; } @@ -277,7 +277,7 @@ float4 main( post_srgb = float3(_208, _209, _210); if (injectedData.toneMapType > 0.f) { - output = upgradePostProcess(tonemappedRender, post_srgb, injectedData.vignetteStrength); + output = UpgradePostProcess(tonemappedRender, post_srgb, injectedData.vignetteStrength); return float4(output, 0.f); } From d5601b0b87f63ddd7f0f841b9e2737e1fc961391 Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Sun, 22 Dec 2024 16:49:19 +0400 Subject: [PATCH 03/12] feat(stalker2): Rework lutbuilders, remove ACES, and decrease gamma --- src/games/stalker2/addon.cpp | 21 +- src/games/stalker2/common.hlsl | 147 +++-- .../lutbuilder_0x6CFBD4C0.ps_6_6.hlsl | 555 ++++++++---------- .../lutbuilder_0xB6CA5FD9.ps_6_6.hlsl | 553 ++++++++--------- .../lutbuilder_0xBAA27141.ps_6_6.hlsl | 36 +- .../stalker2/output_0x20685247.ps_6_6.hlsl | 6 - .../stalker2/output_0x2DAD4682.ps_6_6.hlsl | 9 +- .../stalker2/output_0x39EF727B.ps_6_6.hlsl | 6 - .../stalker2/output_0x4D3C673E.ps_6_6.hlsl | 6 - .../stalker2/output_0xECD0D71A.ps_6_6.hlsl | 4 - src/games/stalker2/shared.h | 2 - 11 files changed, 614 insertions(+), 731 deletions(-) diff --git a/src/games/stalker2/addon.cpp b/src/games/stalker2/addon.cpp index 183e2c6f..91c7a084 100644 --- a/src/games/stalker2/addon.cpp +++ b/src/games/stalker2/addon.cpp @@ -44,12 +44,14 @@ renodx::utils::settings::Settings settings = { .key = "toneMapType", .binding = &shader_injection.toneMapType, .value_type = renodx::utils::settings::SettingValueType::INTEGER, - .default_value = 3.f, + .default_value = 2.f, .can_reset = true, .label = "Tone Mapper", .section = "Tone Mapping", .tooltip = "Sets the tone mapper type", - .labels = {"Vanilla", "None", "ACES", "RenoDRT"}, + .labels = {"Vanilla", "None", "RenoDRT"}, + .parse = [](float value) { return value == 2.f ? 3.f : value; }, // Override ACES + }, new renodx::utils::settings::Setting{ .key = "toneMapPeakNits", @@ -88,7 +90,7 @@ renodx::utils::settings::Settings settings = { .key = "ToneMapPerChannel", .binding = &shader_injection.toneMapPerChannel, .value_type = renodx::utils::settings::SettingValueType::INTEGER, - .default_value = 0.f, + .default_value = 1.f, .label = "Per Channel", .section = "Tone Mapping", .tooltip = "Applies tonemapping per-channel instead of by luminance (More accurate to SDR but less saturated)", @@ -169,19 +171,9 @@ renodx::utils::settings::Settings settings = { .is_enabled = []() { return shader_injection.toneMapType == 3; }, .parse = [](float value) { return value * 0.02f - 1.f; }, }, - new renodx::utils::settings::Setting{ - .key = "colorGradeLUTStrength", - .binding = &shader_injection.colorGradeLUTStrength, - .default_value = 100.f, - .label = "LUT Strength", - .section = "Color Grading", - .max = 100.f, - .is_enabled = []() { return shader_injection.toneMapType > 1.f; }, - .parse = [](float value) { return value * 0.01f; }, - }, new renodx::utils::settings::Setting{ .value_type = renodx::utils::settings::SettingValueType::TEXT, - .label = " - Ingame HDR must be turned ON! \r\n - Lower contrast if game's too dark. \r\n - Game's Gamma option still affects UI!. \r\n - (Optional) Disable reshade's default add ons (Generic depth & Effect runtime sync) to restore lost performance", + .label = " - Ingame HDR must be turned ON! \r\n - Game's Gamma option still affects UI!. \r\n - (Optional) Disable reshade's default add ons (Generic depth & Effect runtime sync) to restore lost performance", .section = "Instructions", }, new renodx::utils::settings::Setting{ @@ -249,7 +241,6 @@ void OnPresetOff() { renodx::utils::settings::UpdateSetting("colorGradeShadows", 50.f); renodx::utils::settings::UpdateSetting("colorGradeContrast", 50.f); renodx::utils::settings::UpdateSetting("colorGradeSaturation", 50.f); - renodx::utils::settings::UpdateSetting("colorGradeLUTStrength", 100.f); renodx::utils::settings::UpdateSetting("colorGradeBlowout", 0.f); } diff --git a/src/games/stalker2/common.hlsl b/src/games/stalker2/common.hlsl index 60b26aca..0923ab5f 100644 --- a/src/games/stalker2/common.hlsl +++ b/src/games/stalker2/common.hlsl @@ -2,7 +2,7 @@ static const float DEFAULT_BRIGHTNESS = 0.f; // 50% static const float DEFAULT_CONTRAST = 1.f; // 50% -static const float DEFAULT_GAMMA = 1.1f; // Approximately 44% +static const float DEFAULT_GAMMA = 1.f; // Approximately 44% float3 CorrectGamma(float3 color) { color = renodx::color::correct::GammaSafe(color); @@ -26,6 +26,60 @@ float3 PQToDecoded(float3 input_pq) { return output; } +float3 RenoDRTSmoothClamp(float3 untonemapped) { + renodx::tonemap::renodrt::Config renodrt_config = + renodx::tonemap::renodrt::config::Create(); + renodrt_config.nits_peak = 100.f; + renodrt_config.mid_gray_value = 0.18f; + renodrt_config.mid_gray_nits = 18.f; + renodrt_config.exposure = 1.f; + renodrt_config.highlights = 1.f; + renodrt_config.shadows = 1.f; + renodrt_config.contrast = 1.05f; + renodrt_config.saturation = 1.05f; + renodrt_config.dechroma = 0.f; + renodrt_config.flare = 0.f; + renodrt_config.hue_correction_strength = 0.f; + renodrt_config.tone_map_method = + renodx::tonemap::renodrt::config::tone_map_method::DANIELE; + renodrt_config.working_color_space = 2u; + + return renodx::tonemap::renodrt::BT709(untonemapped, renodrt_config); +} + +float UpgradeToneMapRatio(float ap1_color_hdr, float ap1_color_sdr, float ap1_post_process_color) { + if (ap1_color_hdr < ap1_color_sdr) { + // If substracting (user contrast or paperwhite) scale down instead + // Should only apply on mismatched HDR + return ap1_color_hdr / ap1_color_sdr; + } else { + float ap1_delta = ap1_color_hdr - ap1_color_sdr; + ap1_delta = max(0, ap1_delta); // Cleans up NaN + const float ap1_new = ap1_post_process_color + ap1_delta; + + const bool ap1_valid = (ap1_post_process_color > 0); // Cleans up NaN and ignore black + return ap1_valid ? (ap1_new / ap1_post_process_color) : 0; + } +} +float3 UpgradeToneMapPerChannel(float3 color_hdr, float3 color_sdr, float3 post_process_color, float post_process_strength) { + // float ratio = 1.f; + + float3 bt2020_hdr = max(0, renodx::color::bt2020::from::BT709(color_hdr)); + float3 bt2020_sdr = max(0, renodx::color::bt2020::from::BT709(color_sdr)); + float3 bt2020_post_process = max(0, renodx::color::bt2020::from::BT709(post_process_color)); + + float3 ratio = float3( + UpgradeToneMapRatio(bt2020_hdr.r, bt2020_sdr.r, bt2020_post_process.r), + UpgradeToneMapRatio(bt2020_hdr.g, bt2020_sdr.g, bt2020_post_process.g), + UpgradeToneMapRatio(bt2020_hdr.b, bt2020_sdr.b, bt2020_post_process.b)); + + float3 color_scaled = max(0, bt2020_post_process * ratio); + color_scaled = renodx::color::bt709::from::BT2020(color_scaled); + float peak_correction = saturate(1.f - renodx::color::y::from::BT2020(bt2020_post_process)); + color_scaled = renodx::color::correct::Hue(color_scaled, post_process_color, peak_correction); + return lerp(color_hdr, color_scaled, post_process_strength); +} + float3 UpgradePostProcess(float3 tonemappedRender, float3 post_processed, float lerpValue = 1.f) { float3 output = post_processed; if (injectedData.toneMapType == 1.f) { @@ -43,11 +97,10 @@ float3 UpgradePostProcess(float3 tonemappedRender, float3 post_processed, float return output; } -// Adjust this function as needed float3 ProcessLUT(SamplerState sampler, Texture2D texture, float3 color) { renodx::lut::Config lut_config = renodx::lut::config::Create( sampler, - injectedData.toneMapType == 2.f ? 0.f : injectedData.colorGradeLUTStrength, + 1.f, 0.f, renodx::lut::config::type::SRGB, renodx::lut::config::type::SRGB, @@ -56,13 +109,13 @@ float3 ProcessLUT(SamplerState sampler, Texture2D texture, float3 color) { return renodx::lut::Sample(texture, lut_config, color); } -bool TonemapConditon(uint output_type = 3u) { +bool ShouldTonemap(uint output_type = 3u) { return injectedData.toneMapType != 0.f && (output_type >= 3u && output_type <= 6u); } -// Adjust this function as needed -void Tonemap(in float3 ap1_graded_color, in float3 ap1_aces_colored, out float3 hdr_color, out float3 sdr_color, inout float3 sdr_ap1_color) { +float3 ToneMap(float3 bt709) { renodx::tonemap::Config config = renodx::tonemap::config::Create(); + // We override ACES config.type = injectedData.toneMapType; config.peak_nits = injectedData.toneMapPeakNits; config.game_nits = injectedData.toneMapGameNits; @@ -73,74 +126,52 @@ void Tonemap(in float3 ap1_graded_color, in float3 ap1_aces_colored, out float3 config.contrast = injectedData.colorGradeContrast; config.saturation = injectedData.colorGradeSaturation; - if (injectedData.toneMapPerChannel == 1.f) { - config.reno_drt_per_channel = true; - } - + // Default inverts smooth clamp config.reno_drt_highlights = 1.0f; config.reno_drt_shadows = 1.0f; - // config.reno_drt_contrast = 1.1f; + config.reno_drt_contrast = 1.f; + // config.reno_drt_saturation = 1.05f; + // 1.1f better matches ACES config.reno_drt_saturation = 1.1f; config.reno_drt_dechroma = 0; config.reno_drt_blowout = injectedData.colorGradeBlowout; - // config.reno_drt_flare = 0.05f; + // Flare darkens too much (stalker2) + // config.reno_drt_flare = 0.10f * injectedData.colorGradeFlare; config.reno_drt_working_color_space = 2u; + config.reno_drt_per_channel = injectedData.toneMapPerChannel != 0; - float3 bt709_graded_color = renodx::color::bt709::from::AP1(ap1_graded_color); - float3 bt709_aces_color = renodx::color::bt709::from::AP1(ap1_aces_colored); + float3 output_color = renodx::tonemap::config::Apply(bt709, config); - config.hue_correction_type = - renodx::tonemap::config::hue_correction_type::CUSTOM; - config.hue_correction_color = bt709_aces_color; - - // config.hue_correction_color = color; - /* if (injectedData.toneMapHueCorrectionMethod == 1.f) { - config.hue_correction_color = renodx::tonemap::ACESFittedAP1(bt709_graded_color); - } else if (injectedData.toneMapHueCorrectionMethod == 2.f) { - config.hue_correction_color = renodx::tonemap::uncharted2::BT709(bt709_graded_color * 2.f); - } else if (injectedData.toneMapHueCorrectionMethod == 3.f) { - config.hue_correction_color = bt709_aces_color; - } else { - config.hue_correction_type = - renodx::tonemap::config::hue_correction_type::INPUT; - } */ - - renodx::tonemap::config::DualToneMap dual_tone_map = renodx::tonemap::config::ApplyToneMaps(bt709_graded_color, config); - hdr_color = dual_tone_map.color_hdr; - sdr_color = dual_tone_map.color_sdr; - sdr_ap1_color = renodx::color::ap1::from::BT709(sdr_color); + return output_color; } -// CorrectGamma in final shader causes bugs to FSR3 FG -void FinalizeTonemap(inout float3 final_color, in float3 film_graded_color, in float3 hdr_color, in float3 sdr_color) { - final_color = saturate(film_graded_color); - - if (injectedData.toneMapType != 1.f) { - final_color = renodx::tonemap::UpgradeToneMap(hdr_color, sdr_color, final_color, 1.f); - } else { - final_color = hdr_color; - } - final_color = renodx::color::bt2020::from::BT709(final_color); - final_color = CorrectGamma(final_color); - final_color = renodx::color::pq::Encode(final_color, injectedData.toneMapGameNits); -} - -// For SDR -> HDR games -float3 FinalizeOutput(float3 color) { +float3 FinalizeTonemap(float3 color, bool is_hdr10 = true) { color = renodx::color::gamma::DecodeSafe(color); color *= injectedData.toneMapUINits; color = min(color, injectedData.toneMapPeakNits); // Clamp UI or Videos - color /= 80.f; // or PQ + color /= 80.f; + return color; } -// For SDR -> HDR games -float3 ScalePaperWhite(float3 color) { - color = renodx::color::srgb::EncodeSafe(color); - color = renodx::color::gamma::DecodeSafe(color); - color *= injectedData.toneMapGameNits / injectedData.toneMapUINits; - color = renodx::color::gamma::EncodeSafe(color); +float4 LutBuilderToneMap(float3 untonemapped_ap1, float3 tonemapped_bt709) { + float3 untonemapped_bt709 = renodx::color::bt709::from::AP1(untonemapped_ap1); + + float3 neutral_sdr_color = RenoDRTSmoothClamp(untonemapped_bt709); + + float3 untonemapped_graded = UpgradeToneMapPerChannel( + untonemapped_bt709, + neutral_sdr_color, + tonemapped_bt709, + 1); + + float3 color = ToneMap(untonemapped_graded); - return color.rgb; + // Correct gamma in final shader causes issues with FSR3 FG + color = renodx::color::bt2020::from::BT709(color); + color = CorrectGamma(color); + color = renodx::color::pq::Encode(color, injectedData.toneMapGameNits); + color *= 1.f / 1.05f; + return float4(color, 0.f); } diff --git a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl index 6c8c97d5..2205284c 100644 --- a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl @@ -1,5 +1,5 @@ -#include "./shared.h" #include "./common.hlsl" +#include "./shared.h" Texture2D Textures_1 : register(t0); @@ -176,7 +176,8 @@ float4 main( // _6 = _4; // CustomEdit uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = TonemapConditon(output_type); + bool shouldTonemap = ShouldTonemap(output_type); + uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; float _9 = TEXCOORD.y; @@ -346,7 +347,6 @@ float4 main( _106 = _102; _107 = _103; } - float3 input_color = float3(_105, _106, _107); // CustomEdit float _109 = UniformBufferConstants_WorkingColorSpace_008x; float _110 = UniformBufferConstants_WorkingColorSpace_008y; @@ -786,7 +786,7 @@ float4 main( float _571 = _568 + _531; float _572 = _569 + _533; float _573 = _570 + _535; - float3 ap1_graded_color = float3(_571, _572, _573); // CustomEdit + float3 untonmapped_ap1 = float3(_571, _572, _573); // CustomEdit float _574 = _571 * 0.6954522132873535f; float _575 = mad(0.14067868888378143f, _572, _574); @@ -939,15 +939,6 @@ float4 main( float _713 = _710 + _705; float _714 = _711 + _705; - float3 ap1_aces_colored = float3(_712, _713, _714); // CustomEdit - - // Now SDR Tonemapping/Split - // Early out with cbuffer - // (Unreal runs the entire SDR process even if discarding) - float3 sdr_color; - float3 hdr_color; - float3 sdr_ap1_color; - float _716 = _RootShaderParameters_037w; float _717 = _716 + 1.0f; float _718 = _RootShaderParameters_037y; @@ -956,165 +947,156 @@ float4 main( float _722 = _721 + 1.0f; float _723 = _RootShaderParameters_037z; float _724 = _722 - _723; - if (shouldTonemap) { - Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); + + bool _725 = (_718 > 0.800000011920929f); + float _726 = _RootShaderParameters_037x; + if (_725) { + float _728 = 0.8199999928474426f - _718; + float _729 = _728 / _726; + float _730 = _729 + -0.7447274923324585f; + _742 = _730; } else { - bool _725 = (_718 > 0.800000011920929f); - float _726 = _RootShaderParameters_037x; - if (_725) { - float _728 = 0.8199999928474426f - _718; - float _729 = _728 / _726; - float _730 = _729 + -0.7447274923324585f; - _742 = _730; - } else { - float _732 = _716 + 0.18000000715255737f; - float _733 = _732 / _719; - float _734 = 2.0f - _733; - float _735 = _733 / _734; - float _736 = log2(_735); - float _737 = _736 * 0.3465735912322998f; - float _738 = _719 / _726; - float _739 = _737 * _738; - float _740 = -0.7447274923324585f - _739; - _742 = _740; - } - float _743 = 1.0f - _718; - float _744 = _743 / _726; - float _745 = _744 - _742; - float _746 = _723 / _726; - float _747 = _746 - _745; - float _748 = log2(_712); - float _749 = log2(_713); - float _750 = log2(_714); - float _751 = _748 * 0.3010300099849701f; - float _752 = _749 * 0.3010300099849701f; - float _753 = _750 * 0.3010300099849701f; - float _754 = _751 + _745; - float _755 = _752 + _745; - float _756 = _753 + _745; - float _757 = _726 * _754; - float _758 = _726 * _755; - float _759 = _726 * _756; - float _760 = _719 * 2.0f; - float _761 = _726 * -2.0f; - float _762 = _761 / _719; - float _763 = _751 - _742; - float _764 = _752 - _742; - float _765 = _753 - _742; - float _766 = _763 * 1.4426950216293335f; - float _767 = _766 * _762; - float _768 = _764 * 1.4426950216293335f; - float _769 = _768 * _762; - float _770 = _765 * 1.4426950216293335f; - float _771 = _770 * _762; - float _772 = exp2(_767); - float _773 = exp2(_769); - float _774 = exp2(_771); - float _775 = _772 + 1.0f; - float _776 = _773 + 1.0f; - float _777 = _774 + 1.0f; - float _778 = _760 / _775; - float _779 = _760 / _776; - float _780 = _760 / _777; - float _781 = _778 - _716; - float _782 = _779 - _716; - float _783 = _780 - _716; - float _784 = _724 * 2.0f; - float _785 = _726 * 2.0f; - float _786 = _785 / _724; - float _787 = _751 - _747; - float _788 = _752 - _747; - float _789 = _753 - _747; - float _790 = _787 * 1.4426950216293335f; - float _791 = _790 * _786; - float _792 = _788 * 1.4426950216293335f; - float _793 = _792 * _786; - float _794 = _789 * 1.4426950216293335f; - float _795 = _794 * _786; - float _796 = exp2(_791); - float _797 = exp2(_793); - float _798 = exp2(_795); - float _799 = _796 + 1.0f; - float _800 = _797 + 1.0f; - float _801 = _798 + 1.0f; - float _802 = _784 / _799; - float _803 = _784 / _800; - float _804 = _784 / _801; - float _805 = _722 - _802; - float _806 = _722 - _803; - float _807 = _722 - _804; - bool _808 = (_751 < _742); - bool _809 = (_752 < _742); - bool _810 = (_753 < _742); - float _811 = _808 ? _781 : _757; - float _812 = _809 ? _782 : _758; - float _813 = _810 ? _783 : _759; - bool _814 = (_751 > _747); - bool _815 = (_752 > _747); - bool _816 = (_753 > _747); - float _817 = _814 ? _805 : _757; - float _818 = _815 ? _806 : _758; - float _819 = _816 ? _807 : _759; - float _820 = _747 - _742; - float _821 = _763 / _820; - float _822 = _764 / _820; - float _823 = _765 / _820; - float _824 = saturate(_821); - float _825 = saturate(_822); - float _826 = saturate(_823); - bool _827 = (_747 < _742); - float _828 = 1.0f - _824; - float _829 = 1.0f - _825; - float _830 = 1.0f - _826; - float _831 = _827 ? _828 : _824; - float _832 = _827 ? _829 : _825; - float _833 = _827 ? _830 : _826; - float _834 = _831 * 2.0f; - float _835 = _832 * 2.0f; - float _836 = _833 * 2.0f; - float _837 = 3.0f - _834; - float _838 = 3.0f - _835; - float _839 = 3.0f - _836; - float _840 = _817 - _811; - float _841 = _818 - _812; - float _842 = _819 - _813; - float _843 = _831 * _831; - float _844 = _843 * _840; - float _845 = _844 * _837; - float _846 = _832 * _832; - float _847 = _846 * _841; - float _848 = _847 * _838; - float _849 = _833 * _833; - float _850 = _849 * _842; - float _851 = _850 * _839; - float _852 = _845 + _811; - float _853 = _848 + _812; - float _854 = _851 + _813; - float _855 = dot(float3(_852, _853, _854), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); - float _856 = _852 - _855; - float _857 = _853 - _855; - float _858 = _854 - _855; - float _859 = _856 * 0.9300000071525574f; - float _860 = _857 * 0.9300000071525574f; - float _861 = _858 * 0.9300000071525574f; - float _862 = _859 + _855; - float _863 = _860 + _855; - float _864 = _861 + _855; - float _865 = max(0.0f, _862); - float _866 = max(0.0f, _863); - float _867 = max(0.0f, _864); - sdr_ap1_color = float3(_865, _866, _867); - // end of FilmToneMap + float _732 = _716 + 0.18000000715255737f; + float _733 = _732 / _719; + float _734 = 2.0f - _733; + float _735 = _733 / _734; + float _736 = log2(_735); + float _737 = _736 * 0.3465735912322998f; + float _738 = _719 / _726; + float _739 = _737 * _738; + float _740 = -0.7447274923324585f - _739; + _742 = _740; } + float _743 = 1.0f - _718; + float _744 = _743 / _726; + float _745 = _744 - _742; + float _746 = _723 / _726; + float _747 = _746 - _745; + float _748 = log2(_712); + float _749 = log2(_713); + float _750 = log2(_714); + float _751 = _748 * 0.3010300099849701f; + float _752 = _749 * 0.3010300099849701f; + float _753 = _750 * 0.3010300099849701f; + float _754 = _751 + _745; + float _755 = _752 + _745; + float _756 = _753 + _745; + float _757 = _726 * _754; + float _758 = _726 * _755; + float _759 = _726 * _756; + float _760 = _719 * 2.0f; + float _761 = _726 * -2.0f; + float _762 = _761 / _719; + float _763 = _751 - _742; + float _764 = _752 - _742; + float _765 = _753 - _742; + float _766 = _763 * 1.4426950216293335f; + float _767 = _766 * _762; + float _768 = _764 * 1.4426950216293335f; + float _769 = _768 * _762; + float _770 = _765 * 1.4426950216293335f; + float _771 = _770 * _762; + float _772 = exp2(_767); + float _773 = exp2(_769); + float _774 = exp2(_771); + float _775 = _772 + 1.0f; + float _776 = _773 + 1.0f; + float _777 = _774 + 1.0f; + float _778 = _760 / _775; + float _779 = _760 / _776; + float _780 = _760 / _777; + float _781 = _778 - _716; + float _782 = _779 - _716; + float _783 = _780 - _716; + float _784 = _724 * 2.0f; + float _785 = _726 * 2.0f; + float _786 = _785 / _724; + float _787 = _751 - _747; + float _788 = _752 - _747; + float _789 = _753 - _747; + float _790 = _787 * 1.4426950216293335f; + float _791 = _790 * _786; + float _792 = _788 * 1.4426950216293335f; + float _793 = _792 * _786; + float _794 = _789 * 1.4426950216293335f; + float _795 = _794 * _786; + float _796 = exp2(_791); + float _797 = exp2(_793); + float _798 = exp2(_795); + float _799 = _796 + 1.0f; + float _800 = _797 + 1.0f; + float _801 = _798 + 1.0f; + float _802 = _784 / _799; + float _803 = _784 / _800; + float _804 = _784 / _801; + float _805 = _722 - _802; + float _806 = _722 - _803; + float _807 = _722 - _804; + bool _808 = (_751 < _742); + bool _809 = (_752 < _742); + bool _810 = (_753 < _742); + float _811 = _808 ? _781 : _757; + float _812 = _809 ? _782 : _758; + float _813 = _810 ? _783 : _759; + bool _814 = (_751 > _747); + bool _815 = (_752 > _747); + bool _816 = (_753 > _747); + float _817 = _814 ? _805 : _757; + float _818 = _815 ? _806 : _758; + float _819 = _816 ? _807 : _759; + float _820 = _747 - _742; + float _821 = _763 / _820; + float _822 = _764 / _820; + float _823 = _765 / _820; + float _824 = saturate(_821); + float _825 = saturate(_822); + float _826 = saturate(_823); + bool _827 = (_747 < _742); + float _828 = 1.0f - _824; + float _829 = 1.0f - _825; + float _830 = 1.0f - _826; + float _831 = _827 ? _828 : _824; + float _832 = _827 ? _829 : _825; + float _833 = _827 ? _830 : _826; + float _834 = _831 * 2.0f; + float _835 = _832 * 2.0f; + float _836 = _833 * 2.0f; + float _837 = 3.0f - _834; + float _838 = 3.0f - _835; + float _839 = 3.0f - _836; + float _840 = _817 - _811; + float _841 = _818 - _812; + float _842 = _819 - _813; + float _843 = _831 * _831; + float _844 = _843 * _840; + float _845 = _844 * _837; + float _846 = _832 * _832; + float _847 = _846 * _841; + float _848 = _847 * _838; + float _849 = _833 * _833; + float _850 = _849 * _842; + float _851 = _850 * _839; + float _852 = _845 + _811; + float _853 = _848 + _812; + float _854 = _851 + _813; + float _855 = dot(float3(_852, _853, _854), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); + float _856 = _852 - _855; + float _857 = _853 - _855; + float _858 = _854 - _855; + float _859 = _856 * 0.9300000071525574f; + float _860 = _857 * 0.9300000071525574f; + float _861 = _858 * 0.9300000071525574f; + float _862 = _859 + _855; + float _863 = _860 + _855; + float _864 = _861 + _855; + float _865 = max(0.0f, _862); + float _866 = max(0.0f, _863); + float _867 = max(0.0f, _864); float _868 = _RootShaderParameters_036w; - /* float _869 = _865 - _571; + float _869 = _865 - _571; float _870 = _866 - _572; - float _871 = _867 - _573; */ - float _869 = sdr_ap1_color.r - _571; - float _870 = sdr_ap1_color.g - _572; - float _871 = sdr_ap1_color.b - _573; - // CustomEdit + float _871 = _867 - _573; float _872 = _868 * _869; float _873 = _868 * _870; @@ -1152,135 +1134,115 @@ float4 main( float _905 = max(0.0f, _898); float _906 = max(0.0f, _901); float _907 = max(0.0f, _904); - float3 lut_input_color = float3(_905, _906, _907); // CustomEdit - float _1011; // custom branch - float _1012; // custom branch - float _1013; // custom branch - - if (shouldTonemap) { - float3 post_lut_color = ProcessLUT(Samplers_1, Textures_1, lut_input_color); - _1011 = post_lut_color.r; - _1012 = post_lut_color.g; - _1013 = post_lut_color.b; + float _908 = saturate(_905); + float _909 = saturate(_906); + float _910 = saturate(_907); + bool _911 = (_908 < 0.0031306699384003878f); + if (_911) { + float _913 = _908 * 12.920000076293945f; + _921 = _913; } else { - /* Vanilla HDR lut sampler produces a different image than sRGB SDR, - so I'm always using RenoDX Sampler. - I assume it's because devs have some weird custom tonemapping values. */ - // Original LUT sampler - float _908 = saturate(_905); - float _909 = saturate(_906); - float _910 = saturate(_907); - bool _911 = (_908 < 0.0031306699384003878f); - if (_911) { - float _913 = _908 * 12.920000076293945f; - _921 = _913; - } else { - float _915 = log2(_908); - float _916 = _915 * 0.4166666567325592f; - float _917 = exp2(_916); - float _918 = _917 * 1.0549999475479126f; - float _919 = _918 + -0.054999999701976776f; - _921 = _919; - } - bool _922 = (_909 < 0.0031306699384003878f); - if (_922) { - float _924 = _909 * 12.920000076293945f; - _932 = _924; - } else { - float _926 = log2(_909); - float _927 = _926 * 0.4166666567325592f; - float _928 = exp2(_927); - float _929 = _928 * 1.0549999475479126f; - float _930 = _929 + -0.054999999701976776f; - _932 = _930; - } - bool _933 = (_910 < 0.0031306699384003878f); - if (_933) { - float _935 = _910 * 12.920000076293945f; - _943 = _935; - } else { - float _937 = log2(_910); - float _938 = _937 * 0.4166666567325592f; - float _939 = exp2(_938); - float _940 = _939 * 1.0549999475479126f; - float _941 = _940 + -0.054999999701976776f; - _943 = _941; - } - float _944 = _921 * 0.9375f; - float _945 = _932 * 0.9375f; - float _946 = _944 + 0.03125f; - float _947 = _945 + 0.03125f; - float _949 = _RootShaderParameters_005x; - float _950 = _949 * _921; - float _951 = _949 * _932; - float _952 = _949 * _943; - float _953 = _RootShaderParameters_005y; - float _954 = _943 * 15.0f; - float _955 = floor(_954); - float _956 = _954 - _955; - float _957 = _946 + _955; - float _958 = _957 * 0.0625f; - // _959 = _1; - // _960 = _2; - float4 _961 = Textures_1.Sample(Samplers_1, float2(_958, _947)); - float _962 = _961.x; - float _963 = _961.y; - float _964 = _961.z; - float _965 = _958 + 0.0625f; - // _966 = _1; - // _967 = _2; - float4 _968 = Textures_1.Sample(Samplers_1, float2(_965, _947)); - float _969 = _968.x; - float _970 = _968.y; - float _971 = _968.z; - float _972 = _969 - _962; - float _973 = _970 - _963; - float _974 = _971 - _964; - float _975 = _972 * _956; - float _976 = _973 * _956; - float _977 = _974 * _956; - float _978 = _975 + _962; - float _979 = _976 + _963; - float _980 = _977 + _964; - float _981 = _978 * _953; - float _982 = _979 * _953; - float _983 = _980 * _953; - float _984 = _981 + _950; - float _985 = _982 + _951; - float _986 = _983 + _952; - float _987 = max(6.103519990574569e-05f, _984); - float _988 = max(6.103519990574569e-05f, _985); - float _989 = max(6.103519990574569e-05f, _986); - float _990 = _987 * 0.07739938050508499f; - float _991 = _988 * 0.07739938050508499f; - float _992 = _989 * 0.07739938050508499f; - float _993 = _987 * 0.9478672742843628f; - float _994 = _988 * 0.9478672742843628f; - float _995 = _989 * 0.9478672742843628f; - float _996 = _993 + 0.05213269963860512f; - float _997 = _994 + 0.05213269963860512f; - float _998 = _995 + 0.05213269963860512f; - float _999 = log2(_996); - float _1000 = log2(_997); - float _1001 = log2(_998); - float _1002 = _999 * 2.4000000953674316f; - float _1003 = _1000 * 2.4000000953674316f; - float _1004 = _1001 * 2.4000000953674316f; - float _1005 = exp2(_1002); - float _1006 = exp2(_1003); - float _1007 = exp2(_1004); - bool _1008 = (_987 > 0.040449999272823334f); - bool _1009 = (_988 > 0.040449999272823334f); - bool _1010 = (_989 > 0.040449999272823334f); - /* float _1011 = _1008 ? _1005 : _990; - float _1012 = _1009 ? _1006 : _991; - float _1013 = _1010 ? _1007 : _992; */ - // CustomEdit - _1011 = _1008 ? _1005 : _990; - _1012 = _1009 ? _1006 : _991; - _1013 = _1010 ? _1007 : _992; + float _915 = log2(_908); + float _916 = _915 * 0.4166666567325592f; + float _917 = exp2(_916); + float _918 = _917 * 1.0549999475479126f; + float _919 = _918 + -0.054999999701976776f; + _921 = _919; } + bool _922 = (_909 < 0.0031306699384003878f); + if (_922) { + float _924 = _909 * 12.920000076293945f; + _932 = _924; + } else { + float _926 = log2(_909); + float _927 = _926 * 0.4166666567325592f; + float _928 = exp2(_927); + float _929 = _928 * 1.0549999475479126f; + float _930 = _929 + -0.054999999701976776f; + _932 = _930; + } + bool _933 = (_910 < 0.0031306699384003878f); + if (_933) { + float _935 = _910 * 12.920000076293945f; + _943 = _935; + } else { + float _937 = log2(_910); + float _938 = _937 * 0.4166666567325592f; + float _939 = exp2(_938); + float _940 = _939 * 1.0549999475479126f; + float _941 = _940 + -0.054999999701976776f; + _943 = _941; + } + float _944 = _921 * 0.9375f; + float _945 = _932 * 0.9375f; + float _946 = _944 + 0.03125f; + float _947 = _945 + 0.03125f; + float _949 = _RootShaderParameters_005x; + float _950 = _949 * _921; + float _951 = _949 * _932; + float _952 = _949 * _943; + float _953 = _RootShaderParameters_005y; + float _954 = _943 * 15.0f; + float _955 = floor(_954); + float _956 = _954 - _955; + float _957 = _946 + _955; + float _958 = _957 * 0.0625f; + // _959 = _1; + // _960 = _2; + float4 _961 = Textures_1.Sample(Samplers_1, float2(_958, _947)); + float _962 = _961.x; + float _963 = _961.y; + float _964 = _961.z; + float _965 = _958 + 0.0625f; + // _966 = _1; + // _967 = _2; + float4 _968 = Textures_1.Sample(Samplers_1, float2(_965, _947)); + float _969 = _968.x; + float _970 = _968.y; + float _971 = _968.z; + float _972 = _969 - _962; + float _973 = _970 - _963; + float _974 = _971 - _964; + float _975 = _972 * _956; + float _976 = _973 * _956; + float _977 = _974 * _956; + float _978 = _975 + _962; + float _979 = _976 + _963; + float _980 = _977 + _964; + float _981 = _978 * _953; + float _982 = _979 * _953; + float _983 = _980 * _953; + float _984 = _981 + _950; + float _985 = _982 + _951; + float _986 = _983 + _952; + float _987 = max(6.103519990574569e-05f, _984); + float _988 = max(6.103519990574569e-05f, _985); + float _989 = max(6.103519990574569e-05f, _986); + float _990 = _987 * 0.07739938050508499f; + float _991 = _988 * 0.07739938050508499f; + float _992 = _989 * 0.07739938050508499f; + float _993 = _987 * 0.9478672742843628f; + float _994 = _988 * 0.9478672742843628f; + float _995 = _989 * 0.9478672742843628f; + float _996 = _993 + 0.05213269963860512f; + float _997 = _994 + 0.05213269963860512f; + float _998 = _995 + 0.05213269963860512f; + float _999 = log2(_996); + float _1000 = log2(_997); + float _1001 = log2(_998); + float _1002 = _999 * 2.4000000953674316f; + float _1003 = _1000 * 2.4000000953674316f; + float _1004 = _1001 * 2.4000000953674316f; + float _1005 = exp2(_1002); + float _1006 = exp2(_1003); + float _1007 = exp2(_1004); + bool _1008 = (_987 > 0.040449999272823334f); + bool _1009 = (_988 > 0.040449999272823334f); + bool _1010 = (_989 > 0.040449999272823334f); + float _1011 = _1008 ? _1005 : _990; + float _1012 = _1009 ? _1006 : _991; + float _1013 = _1010 ? _1007 : _992; float _1015 = _RootShaderParameters_039x; float _1016 = _1015 * _1011; @@ -1334,7 +1296,7 @@ float4 main( float _1062 = _1059 + _1053; float _1064 = _RootShaderParameters_040y; - if (injectedData.toneMapType > 0.f) { + if (shouldTonemap) { _1064 = DEFAULT_GAMMA; } float _1065 = max(0.0f, _1048); @@ -1352,11 +1314,8 @@ float4 main( // CustomEdit float3 film_graded_color = float3(_1074, _1075, _1076); - float3 final_color = film_graded_color; - // We return sRGB bt709 color if (shouldTonemap) { - FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); - return float4(final_color, 0.f); + return LutBuilderToneMap(untonmapped_ap1, film_graded_color); } uint _1078 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl index eac9cca8..44de9fab 100644 --- a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl @@ -1,7 +1,6 @@ #include "./common.hlsl" #include "./shared.h" - Texture2D Textures_1 : register(t0); cbuffer _RootShaderParameters : register(b0) { @@ -198,7 +197,7 @@ float4 main( // _6 = _4; // CustomEdit uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = TonemapConditon(output_type); + bool shouldTonemap = ShouldTonemap(output_type); uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; float _9 = TEXCOORD.y; @@ -369,7 +368,6 @@ float4 main( _106 = _102; _107 = _103; } - float3 input_color = float3(_105, _106, _107); // CustomEdit float _109 = UniformBufferConstants_WorkingColorSpace_004x; float _110 = UniformBufferConstants_WorkingColorSpace_004y; @@ -1061,7 +1059,7 @@ float4 main( float _825 = _822 + _785; float _826 = _823 + _787; float _827 = _824 + _789; - float3 ap1_graded_color = float3(_825, _826, _827); // CustomEdit + float3 untonmapped_ap1 = float3(_825, _826, _827); // CustomEdit float _828 = _825 * 0.6954522132873535f; float _829 = mad(0.14067868888378143f, _826, _828); @@ -1214,15 +1212,6 @@ float4 main( float _967 = _964 + _959; float _968 = _965 + _959; - float3 ap1_aces_colored = float3(_966, _967, _968); // CustomEdit - - // Now SDR Tonemapping/Split - // Early out with cbuffer - // (Unreal runs the entire SDR process even if discarding) - float3 sdr_color; - float3 hdr_color; - float3 sdr_ap1_color; - float _970 = _RootShaderParameters_037w; float _971 = _970 + 1.0f; float _972 = _RootShaderParameters_037y; @@ -1231,166 +1220,155 @@ float4 main( float _976 = _975 + 1.0f; float _977 = _RootShaderParameters_037z; float _978 = _976 - _977; - if (shouldTonemap) { - Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); + bool _979 = (_972 > 0.800000011920929f); + float _980 = _RootShaderParameters_037x; + if (_979) { + float _982 = 0.8199999928474426f - _972; + float _983 = _982 / _980; + float _984 = _983 + -0.7447274923324585f; + _996 = _984; } else { - bool _979 = (_972 > 0.800000011920929f); - float _980 = _RootShaderParameters_037x; - if (_979) { - float _982 = 0.8199999928474426f - _972; - float _983 = _982 / _980; - float _984 = _983 + -0.7447274923324585f; - _996 = _984; - } else { - float _986 = _970 + 0.18000000715255737f; - float _987 = _986 / _973; - float _988 = 2.0f - _987; - float _989 = _987 / _988; - float _990 = log2(_989); - float _991 = _990 * 0.3465735912322998f; - float _992 = _973 / _980; - float _993 = _991 * _992; - float _994 = -0.7447274923324585f - _993; - _996 = _994; - } - float _997 = 1.0f - _972; - float _998 = _997 / _980; - float _999 = _998 - _996; - float _1000 = _977 / _980; - float _1001 = _1000 - _999; - float _1002 = log2(_966); - float _1003 = log2(_967); - float _1004 = log2(_968); - float _1005 = _1002 * 0.3010300099849701f; - float _1006 = _1003 * 0.3010300099849701f; - float _1007 = _1004 * 0.3010300099849701f; - float _1008 = _1005 + _999; - float _1009 = _1006 + _999; - float _1010 = _1007 + _999; - float _1011 = _980 * _1008; - float _1012 = _980 * _1009; - float _1013 = _980 * _1010; - float _1014 = _973 * 2.0f; - float _1015 = _980 * -2.0f; - float _1016 = _1015 / _973; - float _1017 = _1005 - _996; - float _1018 = _1006 - _996; - float _1019 = _1007 - _996; - float _1020 = _1017 * 1.4426950216293335f; - float _1021 = _1020 * _1016; - float _1022 = _1018 * 1.4426950216293335f; - float _1023 = _1022 * _1016; - float _1024 = _1019 * 1.4426950216293335f; - float _1025 = _1024 * _1016; - float _1026 = exp2(_1021); - float _1027 = exp2(_1023); - float _1028 = exp2(_1025); - float _1029 = _1026 + 1.0f; - float _1030 = _1027 + 1.0f; - float _1031 = _1028 + 1.0f; - float _1032 = _1014 / _1029; - float _1033 = _1014 / _1030; - float _1034 = _1014 / _1031; - float _1035 = _1032 - _970; - float _1036 = _1033 - _970; - float _1037 = _1034 - _970; - float _1038 = _978 * 2.0f; - float _1039 = _980 * 2.0f; - float _1040 = _1039 / _978; - float _1041 = _1005 - _1001; - float _1042 = _1006 - _1001; - float _1043 = _1007 - _1001; - float _1044 = _1041 * 1.4426950216293335f; - float _1045 = _1044 * _1040; - float _1046 = _1042 * 1.4426950216293335f; - float _1047 = _1046 * _1040; - float _1048 = _1043 * 1.4426950216293335f; - float _1049 = _1048 * _1040; - float _1050 = exp2(_1045); - float _1051 = exp2(_1047); - float _1052 = exp2(_1049); - float _1053 = _1050 + 1.0f; - float _1054 = _1051 + 1.0f; - float _1055 = _1052 + 1.0f; - float _1056 = _1038 / _1053; - float _1057 = _1038 / _1054; - float _1058 = _1038 / _1055; - float _1059 = _976 - _1056; - float _1060 = _976 - _1057; - float _1061 = _976 - _1058; - bool _1062 = (_1005 < _996); - bool _1063 = (_1006 < _996); - bool _1064 = (_1007 < _996); - float _1065 = _1062 ? _1035 : _1011; - float _1066 = _1063 ? _1036 : _1012; - float _1067 = _1064 ? _1037 : _1013; - bool _1068 = (_1005 > _1001); - bool _1069 = (_1006 > _1001); - bool _1070 = (_1007 > _1001); - float _1071 = _1068 ? _1059 : _1011; - float _1072 = _1069 ? _1060 : _1012; - float _1073 = _1070 ? _1061 : _1013; - float _1074 = _1001 - _996; - float _1075 = _1017 / _1074; - float _1076 = _1018 / _1074; - float _1077 = _1019 / _1074; - float _1078 = saturate(_1075); - float _1079 = saturate(_1076); - float _1080 = saturate(_1077); - bool _1081 = (_1001 < _996); - float _1082 = 1.0f - _1078; - float _1083 = 1.0f - _1079; - float _1084 = 1.0f - _1080; - float _1085 = _1081 ? _1082 : _1078; - float _1086 = _1081 ? _1083 : _1079; - float _1087 = _1081 ? _1084 : _1080; - float _1088 = _1085 * 2.0f; - float _1089 = _1086 * 2.0f; - float _1090 = _1087 * 2.0f; - float _1091 = 3.0f - _1088; - float _1092 = 3.0f - _1089; - float _1093 = 3.0f - _1090; - float _1094 = _1071 - _1065; - float _1095 = _1072 - _1066; - float _1096 = _1073 - _1067; - float _1097 = _1085 * _1085; - float _1098 = _1097 * _1094; - float _1099 = _1098 * _1091; - float _1100 = _1086 * _1086; - float _1101 = _1100 * _1095; - float _1102 = _1101 * _1092; - float _1103 = _1087 * _1087; - float _1104 = _1103 * _1096; - float _1105 = _1104 * _1093; - float _1106 = _1099 + _1065; - float _1107 = _1102 + _1066; - float _1108 = _1105 + _1067; - float _1109 = dot(float3(_1106, _1107, _1108), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); - float _1110 = _1106 - _1109; - float _1111 = _1107 - _1109; - float _1112 = _1108 - _1109; - float _1113 = _1110 * 0.9300000071525574f; - float _1114 = _1111 * 0.9300000071525574f; - float _1115 = _1112 * 0.9300000071525574f; - float _1116 = _1113 + _1109; - float _1117 = _1114 + _1109; - float _1118 = _1115 + _1109; - float _1119 = max(0.0f, _1116); - float _1120 = max(0.0f, _1117); - float _1121 = max(0.0f, _1118); - - sdr_ap1_color = float3(_1119, _1120, _1121); - // end of FilmToneMap + float _986 = _970 + 0.18000000715255737f; + float _987 = _986 / _973; + float _988 = 2.0f - _987; + float _989 = _987 / _988; + float _990 = log2(_989); + float _991 = _990 * 0.3465735912322998f; + float _992 = _973 / _980; + float _993 = _991 * _992; + float _994 = -0.7447274923324585f - _993; + _996 = _994; } + float _997 = 1.0f - _972; + float _998 = _997 / _980; + float _999 = _998 - _996; + float _1000 = _977 / _980; + float _1001 = _1000 - _999; + float _1002 = log2(_966); + float _1003 = log2(_967); + float _1004 = log2(_968); + float _1005 = _1002 * 0.3010300099849701f; + float _1006 = _1003 * 0.3010300099849701f; + float _1007 = _1004 * 0.3010300099849701f; + float _1008 = _1005 + _999; + float _1009 = _1006 + _999; + float _1010 = _1007 + _999; + float _1011 = _980 * _1008; + float _1012 = _980 * _1009; + float _1013 = _980 * _1010; + float _1014 = _973 * 2.0f; + float _1015 = _980 * -2.0f; + float _1016 = _1015 / _973; + float _1017 = _1005 - _996; + float _1018 = _1006 - _996; + float _1019 = _1007 - _996; + float _1020 = _1017 * 1.4426950216293335f; + float _1021 = _1020 * _1016; + float _1022 = _1018 * 1.4426950216293335f; + float _1023 = _1022 * _1016; + float _1024 = _1019 * 1.4426950216293335f; + float _1025 = _1024 * _1016; + float _1026 = exp2(_1021); + float _1027 = exp2(_1023); + float _1028 = exp2(_1025); + float _1029 = _1026 + 1.0f; + float _1030 = _1027 + 1.0f; + float _1031 = _1028 + 1.0f; + float _1032 = _1014 / _1029; + float _1033 = _1014 / _1030; + float _1034 = _1014 / _1031; + float _1035 = _1032 - _970; + float _1036 = _1033 - _970; + float _1037 = _1034 - _970; + float _1038 = _978 * 2.0f; + float _1039 = _980 * 2.0f; + float _1040 = _1039 / _978; + float _1041 = _1005 - _1001; + float _1042 = _1006 - _1001; + float _1043 = _1007 - _1001; + float _1044 = _1041 * 1.4426950216293335f; + float _1045 = _1044 * _1040; + float _1046 = _1042 * 1.4426950216293335f; + float _1047 = _1046 * _1040; + float _1048 = _1043 * 1.4426950216293335f; + float _1049 = _1048 * _1040; + float _1050 = exp2(_1045); + float _1051 = exp2(_1047); + float _1052 = exp2(_1049); + float _1053 = _1050 + 1.0f; + float _1054 = _1051 + 1.0f; + float _1055 = _1052 + 1.0f; + float _1056 = _1038 / _1053; + float _1057 = _1038 / _1054; + float _1058 = _1038 / _1055; + float _1059 = _976 - _1056; + float _1060 = _976 - _1057; + float _1061 = _976 - _1058; + bool _1062 = (_1005 < _996); + bool _1063 = (_1006 < _996); + bool _1064 = (_1007 < _996); + float _1065 = _1062 ? _1035 : _1011; + float _1066 = _1063 ? _1036 : _1012; + float _1067 = _1064 ? _1037 : _1013; + bool _1068 = (_1005 > _1001); + bool _1069 = (_1006 > _1001); + bool _1070 = (_1007 > _1001); + float _1071 = _1068 ? _1059 : _1011; + float _1072 = _1069 ? _1060 : _1012; + float _1073 = _1070 ? _1061 : _1013; + float _1074 = _1001 - _996; + float _1075 = _1017 / _1074; + float _1076 = _1018 / _1074; + float _1077 = _1019 / _1074; + float _1078 = saturate(_1075); + float _1079 = saturate(_1076); + float _1080 = saturate(_1077); + bool _1081 = (_1001 < _996); + float _1082 = 1.0f - _1078; + float _1083 = 1.0f - _1079; + float _1084 = 1.0f - _1080; + float _1085 = _1081 ? _1082 : _1078; + float _1086 = _1081 ? _1083 : _1079; + float _1087 = _1081 ? _1084 : _1080; + float _1088 = _1085 * 2.0f; + float _1089 = _1086 * 2.0f; + float _1090 = _1087 * 2.0f; + float _1091 = 3.0f - _1088; + float _1092 = 3.0f - _1089; + float _1093 = 3.0f - _1090; + float _1094 = _1071 - _1065; + float _1095 = _1072 - _1066; + float _1096 = _1073 - _1067; + float _1097 = _1085 * _1085; + float _1098 = _1097 * _1094; + float _1099 = _1098 * _1091; + float _1100 = _1086 * _1086; + float _1101 = _1100 * _1095; + float _1102 = _1101 * _1092; + float _1103 = _1087 * _1087; + float _1104 = _1103 * _1096; + float _1105 = _1104 * _1093; + float _1106 = _1099 + _1065; + float _1107 = _1102 + _1066; + float _1108 = _1105 + _1067; + float _1109 = dot(float3(_1106, _1107, _1108), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); + float _1110 = _1106 - _1109; + float _1111 = _1107 - _1109; + float _1112 = _1108 - _1109; + float _1113 = _1110 * 0.9300000071525574f; + float _1114 = _1111 * 0.9300000071525574f; + float _1115 = _1112 * 0.9300000071525574f; + float _1116 = _1113 + _1109; + float _1117 = _1114 + _1109; + float _1118 = _1115 + _1109; + float _1119 = max(0.0f, _1116); + float _1120 = max(0.0f, _1117); + float _1121 = max(0.0f, _1118); float _1122 = _RootShaderParameters_036w; - /* float _1123 = _1119 - _825; + float _1123 = _1119 - _825; float _1124 = _1120 - _826; - float _1125 = _1121 - _827; */ - float _1123 = sdr_ap1_color.r - _825; - float _1124 = sdr_ap1_color.g - _826; - float _1125 = sdr_ap1_color.b - _827; - // CustomEdit + float _1125 = _1121 - _827; float _1126 = _1122 * _1123; float _1127 = _1122 * _1124; @@ -1428,137 +1406,115 @@ float4 main( float _1159 = max(0.0f, _1152); float _1160 = max(0.0f, _1155); float _1161 = max(0.0f, _1158); - float3 lut_input_color = float3(_1159, _1160, _1161); // CustomEdit - - float _1265; // custom branch - float _1266; // custom branch - float _1267; // custom branch - - // We skip ACES cuz the LUT exasexacerbates the contrast - if (injectedData.toneMapType > 1.f) { - float3 post_lut_color = ProcessLUT(Samplers_1, Textures_1, lut_input_color); - _1265 = post_lut_color.r; - _1266 = post_lut_color.g; - _1267 = post_lut_color.b; + float _1162 = saturate(_1159); + float _1163 = saturate(_1160); + float _1164 = saturate(_1161); + bool _1165 = (_1162 < 0.0031306699384003878f); + if (_1165) { + float _1167 = _1162 * 12.920000076293945f; + _1175 = _1167; } else { - /* Vanilla HDR lut sampler produces a different image than sRGB SDR, - so I'm always using RenoDX Sampler. - I assume it's because devs have some weird custom tonemapping values. */ - // Original LUT sampler - float _1162 = saturate(_1159); - float _1163 = saturate(_1160); - float _1164 = saturate(_1161); - bool _1165 = (_1162 < 0.0031306699384003878f); - if (_1165) { - float _1167 = _1162 * 12.920000076293945f; - _1175 = _1167; - } else { - float _1169 = log2(_1162); - float _1170 = _1169 * 0.4166666567325592f; - float _1171 = exp2(_1170); - float _1172 = _1171 * 1.0549999475479126f; - float _1173 = _1172 + -0.054999999701976776f; - _1175 = _1173; - } - bool _1176 = (_1163 < 0.0031306699384003878f); - if (_1176) { - float _1178 = _1163 * 12.920000076293945f; - _1186 = _1178; - } else { - float _1180 = log2(_1163); - float _1181 = _1180 * 0.4166666567325592f; - float _1182 = exp2(_1181); - float _1183 = _1182 * 1.0549999475479126f; - float _1184 = _1183 + -0.054999999701976776f; - _1186 = _1184; - } - bool _1187 = (_1164 < 0.0031306699384003878f); - if (_1187) { - float _1189 = _1164 * 12.920000076293945f; - _1197 = _1189; - } else { - float _1191 = log2(_1164); - float _1192 = _1191 * 0.4166666567325592f; - float _1193 = exp2(_1192); - float _1194 = _1193 * 1.0549999475479126f; - float _1195 = _1194 + -0.054999999701976776f; - _1197 = _1195; - } - float _1198 = _1175 * 0.9375f; - float _1199 = _1186 * 0.9375f; - float _1200 = _1198 + 0.03125f; - float _1201 = _1199 + 0.03125f; - float _1203 = _RootShaderParameters_005x; - float _1204 = _1203 * _1175; - float _1205 = _1203 * _1186; - float _1206 = _1203 * _1197; - float _1207 = _RootShaderParameters_005y; - float _1208 = _1197 * 15.0f; - float _1209 = floor(_1208); - float _1210 = _1208 - _1209; - float _1211 = _1200 + _1209; - float _1212 = _1211 * 0.0625f; - // _1213 = _1; - // _1214 = _2; - float4 _1215 = Textures_1.Sample(Samplers_1, float2(_1212, _1201)); - float _1216 = _1215.x; - float _1217 = _1215.y; - float _1218 = _1215.z; - float _1219 = _1212 + 0.0625f; - // _1220 = _1; - // _1221 = _2; - float4 _1222 = Textures_1.Sample(Samplers_1, float2(_1219, _1201)); - float _1223 = _1222.x; - float _1224 = _1222.y; - float _1225 = _1222.z; - float _1226 = _1223 - _1216; - float _1227 = _1224 - _1217; - float _1228 = _1225 - _1218; - float _1229 = _1226 * _1210; - float _1230 = _1227 * _1210; - float _1231 = _1228 * _1210; - float _1232 = _1229 + _1216; - float _1233 = _1230 + _1217; - float _1234 = _1231 + _1218; - float _1235 = _1232 * _1207; - float _1236 = _1233 * _1207; - float _1237 = _1234 * _1207; - float _1238 = _1235 + _1204; - float _1239 = _1236 + _1205; - float _1240 = _1237 + _1206; - float _1241 = max(6.103519990574569e-05f, _1238); - float _1242 = max(6.103519990574569e-05f, _1239); - float _1243 = max(6.103519990574569e-05f, _1240); - float _1244 = _1241 * 0.07739938050508499f; - float _1245 = _1242 * 0.07739938050508499f; - float _1246 = _1243 * 0.07739938050508499f; - float _1247 = _1241 * 0.9478672742843628f; - float _1248 = _1242 * 0.9478672742843628f; - float _1249 = _1243 * 0.9478672742843628f; - float _1250 = _1247 + 0.05213269963860512f; - float _1251 = _1248 + 0.05213269963860512f; - float _1252 = _1249 + 0.05213269963860512f; - float _1253 = log2(_1250); - float _1254 = log2(_1251); - float _1255 = log2(_1252); - float _1256 = _1253 * 2.4000000953674316f; - float _1257 = _1254 * 2.4000000953674316f; - float _1258 = _1255 * 2.4000000953674316f; - float _1259 = exp2(_1256); - float _1260 = exp2(_1257); - float _1261 = exp2(_1258); - bool _1262 = (_1241 > 0.040449999272823334f); - bool _1263 = (_1242 > 0.040449999272823334f); - bool _1264 = (_1243 > 0.040449999272823334f); - /* float _1265 = _1262 ? _1259 : _1244; - float _1266 = _1263 ? _1260 : _1245; - float _1267 = _1264 ? _1261 : _1246; */ - // CustomEdit - _1265 = _1262 ? _1259 : _1244; - _1266 = _1263 ? _1260 : _1245; - _1267 = _1264 ? _1261 : _1246; + float _1169 = log2(_1162); + float _1170 = _1169 * 0.4166666567325592f; + float _1171 = exp2(_1170); + float _1172 = _1171 * 1.0549999475479126f; + float _1173 = _1172 + -0.054999999701976776f; + _1175 = _1173; + } + bool _1176 = (_1163 < 0.0031306699384003878f); + if (_1176) { + float _1178 = _1163 * 12.920000076293945f; + _1186 = _1178; + } else { + float _1180 = log2(_1163); + float _1181 = _1180 * 0.4166666567325592f; + float _1182 = exp2(_1181); + float _1183 = _1182 * 1.0549999475479126f; + float _1184 = _1183 + -0.054999999701976776f; + _1186 = _1184; + } + bool _1187 = (_1164 < 0.0031306699384003878f); + if (_1187) { + float _1189 = _1164 * 12.920000076293945f; + _1197 = _1189; + } else { + float _1191 = log2(_1164); + float _1192 = _1191 * 0.4166666567325592f; + float _1193 = exp2(_1192); + float _1194 = _1193 * 1.0549999475479126f; + float _1195 = _1194 + -0.054999999701976776f; + _1197 = _1195; } + float _1198 = _1175 * 0.9375f; + float _1199 = _1186 * 0.9375f; + float _1200 = _1198 + 0.03125f; + float _1201 = _1199 + 0.03125f; + float _1203 = _RootShaderParameters_005x; + float _1204 = _1203 * _1175; + float _1205 = _1203 * _1186; + float _1206 = _1203 * _1197; + float _1207 = _RootShaderParameters_005y; + float _1208 = _1197 * 15.0f; + float _1209 = floor(_1208); + float _1210 = _1208 - _1209; + float _1211 = _1200 + _1209; + float _1212 = _1211 * 0.0625f; + // _1213 = _1; + // _1214 = _2; + float4 _1215 = Textures_1.Sample(Samplers_1, float2(_1212, _1201)); + float _1216 = _1215.x; + float _1217 = _1215.y; + float _1218 = _1215.z; + float _1219 = _1212 + 0.0625f; + // _1220 = _1; + // _1221 = _2; + float4 _1222 = Textures_1.Sample(Samplers_1, float2(_1219, _1201)); + float _1223 = _1222.x; + float _1224 = _1222.y; + float _1225 = _1222.z; + float _1226 = _1223 - _1216; + float _1227 = _1224 - _1217; + float _1228 = _1225 - _1218; + float _1229 = _1226 * _1210; + float _1230 = _1227 * _1210; + float _1231 = _1228 * _1210; + float _1232 = _1229 + _1216; + float _1233 = _1230 + _1217; + float _1234 = _1231 + _1218; + float _1235 = _1232 * _1207; + float _1236 = _1233 * _1207; + float _1237 = _1234 * _1207; + float _1238 = _1235 + _1204; + float _1239 = _1236 + _1205; + float _1240 = _1237 + _1206; + float _1241 = max(6.103519990574569e-05f, _1238); + float _1242 = max(6.103519990574569e-05f, _1239); + float _1243 = max(6.103519990574569e-05f, _1240); + float _1244 = _1241 * 0.07739938050508499f; + float _1245 = _1242 * 0.07739938050508499f; + float _1246 = _1243 * 0.07739938050508499f; + float _1247 = _1241 * 0.9478672742843628f; + float _1248 = _1242 * 0.9478672742843628f; + float _1249 = _1243 * 0.9478672742843628f; + float _1250 = _1247 + 0.05213269963860512f; + float _1251 = _1248 + 0.05213269963860512f; + float _1252 = _1249 + 0.05213269963860512f; + float _1253 = log2(_1250); + float _1254 = log2(_1251); + float _1255 = log2(_1252); + float _1256 = _1253 * 2.4000000953674316f; + float _1257 = _1254 * 2.4000000953674316f; + float _1258 = _1255 * 2.4000000953674316f; + float _1259 = exp2(_1256); + float _1260 = exp2(_1257); + float _1261 = exp2(_1258); + bool _1262 = (_1241 > 0.040449999272823334f); + bool _1263 = (_1242 > 0.040449999272823334f); + bool _1264 = (_1243 > 0.040449999272823334f); + float _1265 = _1262 ? _1259 : _1244; + float _1266 = _1263 ? _1260 : _1245; + float _1267 = _1264 ? _1261 : _1246; float _1269 = _RootShaderParameters_039x; float _1270 = _1269 * _1265; @@ -1625,11 +1581,8 @@ float4 main( // CustomEdit float3 film_graded_color = float3(_1328, _1329, _1330); - float3 final_color = film_graded_color; - // We return sRGB bt709 color if (shouldTonemap) { - FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); - return float4(final_color, 0.f); + return LutBuilderToneMap(untonmapped_ap1, film_graded_color); } uint _1332 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl index 3ae5a82f..657d3c76 100644 --- a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl @@ -169,7 +169,7 @@ float4 main( // _3 = _1; // _4 = _2; uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = TonemapConditon(output_type); + bool shouldTonemap = ShouldTonemap(output_type); uint _5 = SV_RenderTargetArrayIndex; float _6 = TEXCOORD.x; float _7 = TEXCOORD.y; @@ -336,7 +336,6 @@ float4 main( _104 = _100; _105 = _101; } - float3 input_color = float3(_103, _104, _105); // CustomEdit float _107 = UniformBufferConstants_WorkingColorSpace_008x; float _108 = UniformBufferConstants_WorkingColorSpace_008y; @@ -776,7 +775,7 @@ float4 main( float _569 = _566 + _529; float _570 = _567 + _531; float _571 = _568 + _533; - float3 ap1_graded_color = float3(_569, _570, _571); // CustomEdit + float3 untonmapped_ap1 = float3(_569, _570, _571); // CustomEdit float _572 = _569 * 0.6954522132873535f; float _573 = mad(0.14067868888378143f, _570, _572); @@ -929,16 +928,6 @@ float4 main( float _711 = _708 + _703; float _712 = _709 + _703; - float3 ap1_aces_colored = float3(_710, _711, _712); // CustomEdit - - // Now SDR Tonemapping/Split - // Early out with cbuffer - // (Unreal runs the entire SDR process even if discarding) - - float3 sdr_color; - float3 hdr_color; - float3 sdr_ap1_color; - float _714 = _RootShaderParameters_037w; float _715 = _714 + 1.0f; float _716 = _RootShaderParameters_037y; @@ -947,9 +936,7 @@ float4 main( float _720 = _719 + 1.0f; float _721 = _RootShaderParameters_037z; float _722 = _720 - _721; - if (shouldTonemap) { - Tonemap(ap1_graded_color, ap1_aces_colored, hdr_color, sdr_color, sdr_ap1_color); - } else { + bool _723 = (_716 > 0.800000011920929f); float _724 = _RootShaderParameters_037x; if (_723) { @@ -1094,18 +1081,12 @@ float4 main( float _863 = max(0.0f, _860); float _864 = max(0.0f, _861); float _865 = max(0.0f, _862); - sdr_ap1_color = float3(_863, _864, _865); - // end of FilmToneMap - } + float _866 = _RootShaderParameters_036w; - /* float _867 = _863 - _569; + float _867 = _863 - _569; float _868 = _864 - _570; - float _869 = _865 - _571; */ - float _867 = sdr_ap1_color.r - _569; - float _868 = sdr_ap1_color.g - _570; - float _869 = sdr_ap1_color.b - _571; - // CustomEdit + float _869 = _865 - _571; float _870 = _866 * _867; float _871 = _866 * _868; @@ -1208,11 +1189,8 @@ float4 main( // CustomEdit float3 film_graded_color = float3(_966, _967, _968); - float3 final_color = film_graded_color; - // We return sRGB bt709 color if (shouldTonemap) { - FinalizeTonemap(final_color, film_graded_color, hdr_color, sdr_ap1_color); - return float4(final_color, 0.f); + return LutBuilderToneMap(untonmapped_ap1, film_graded_color); } uint _970 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl index 2b6a78b8..7e8d8e92 100644 --- a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl @@ -86,7 +86,6 @@ float4 main( noperspective float4 SV_Position: SV_Position) : SV_Target { float4 SV_Target; - float3 post_lut; float4 _39 = ColorTexture.Sample(ColorSampler, float2((min((max((TEXCOORD.x), (cb0_015x))), (cb0_015z))), (min((max((TEXCOORD.y), (cb0_015y))), (cb0_015w))))); float _45 = (UniformBufferConstants_View_140w) * (_39.x); @@ -118,11 +117,6 @@ float4 main( float _207 = exp2(((log2((_196 * ((((UniformBufferConstants_View_140w) * (_152.y)) * (((cb0_045y) * (_176.y)) + 1.0f)) + (((_113 * _46) * (cb0_044y)) * (_125.y)))))) * 0.1593017578125f)); float _208 = exp2(((log2((_196 * ((((UniformBufferConstants_View_140w) * (_152.z)) * (((cb0_045z) * (_176.z)) + 1.0f)) + (((_113 * _47) * (cb0_044z)) * (_125.z)))))) * 0.1593017578125f)); float4 _244 = ColorGradingLUT.Sample(ColorGradingLUTSampler, float3((((exp2(((log2(((1.0f / ((_206 * 18.6875f) + 1.0f)) * ((_206 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_207 * 18.6875f) + 1.0f)) * ((_207 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_208 * 18.6875f) + 1.0f)) * ((_208 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f))); - post_lut = _244.rgb; - // Code after sampling - if (injectedData.toneMapType != 0.f) { - return float4(post_lut, 0.f); - } float _257 = ((frac(((sin((((TEXCOORD_2.w) * 543.3099975585938f) + (TEXCOORD_2.z)))) * 493013.0f))) * 0.00390625f) + -0.001953125f; float _258 = _257 + ((_244.x) * 1.0499999523162842f); float _259 = _257 + ((_244.y) * 1.0499999523162842f); diff --git a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl index 804151cd..d6ecbd6e 100644 --- a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl @@ -1,5 +1,6 @@ -#include "./shared.h" #include "./common.hlsl" +#include "./shared.h" + Texture2D ColorTexture : register(t0); @@ -87,7 +88,6 @@ float4 main( noperspective float4 SV_Position: SV_Position) : SV_Target { float4 SV_Target; - float3 post_lut; float4 _41 = ColorTexture.Sample(ColorSampler, float2((min((max((TEXCOORD.x), (cb0_015x))), (cb0_015z))), (min((max((TEXCOORD.y), (cb0_015y))), (cb0_015w))))); float _47 = (UniformBufferConstants_View_140w) * (_41.x); @@ -128,11 +128,6 @@ float4 main( float _218 = exp2(((log2((_207 * ((((UniformBufferConstants_View_140w) * (_154.y)) * (((cb0_045y) * (_178.y)) + 1.0f)) + (((_115 * _48) * (cb0_044y)) * (_127.y)))))) * 0.1593017578125f)); float _219 = exp2(((log2((_207 * ((((UniformBufferConstants_View_140w) * (_154.z)) * (((cb0_045z) * (_178.z)) + 1.0f)) + (((_115 * _49) * (cb0_044z)) * (_127.z)))))) * 0.1593017578125f)); float4 _255 = ColorGradingLUT.Sample(ColorGradingLUTSampler, float3((((exp2(((log2(((1.0f / ((_217 * 18.6875f) + 1.0f)) * ((_217 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_218 * 18.6875f) + 1.0f)) * ((_218 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_219 * 18.6875f) + 1.0f)) * ((_219 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f))); - post_lut = _255.rgb; - // Code after sampling - if (injectedData.toneMapType != 0.f) { - return float4(post_lut, 0.f); - } float _268 = ((frac(((sin((((TEXCOORD_2.w) * 543.3099975585938f) + (TEXCOORD_2.z)))) * 493013.0f))) * 0.00390625f) + -0.001953125f; float _269 = _268 + ((_255.x) * 1.0499999523162842f); float _270 = _268 + ((_255.y) * 1.0499999523162842f); diff --git a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl index ec4ce441..45845b16 100644 --- a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl @@ -100,7 +100,6 @@ float4 main( noperspective float4 SV_Position: SV_Position) : SV_Target { float4 SV_Target; - float3 post_lut; float _41 = ((cb0_048z) * (TEXCOORD_3.x)) + (cb0_048x); float _42 = ((cb0_048w) * (TEXCOORD_3.y)) + (cb0_048y); @@ -146,11 +145,6 @@ float4 main( float _318 = exp2(((log2((_307 * ((((UniformBufferConstants_View_140w) * (_254.y)) * (((cb0_045y) * (_278.y)) + 1.0f)) + (((_215 * _148) * (cb0_044y)) * (_227.y)))))) * 0.1593017578125f)); float _319 = exp2(((log2((_307 * ((((UniformBufferConstants_View_140w) * (_254.z)) * (((cb0_045z) * (_278.z)) + 1.0f)) + (((_215 * _149) * (cb0_044z)) * (_227.z)))))) * 0.1593017578125f)); float4 _355 = ColorGradingLUT.Sample(ColorGradingLUTSampler, float3((((exp2(((log2(((1.0f / ((_317 * 18.6875f) + 1.0f)) * ((_317 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_318 * 18.6875f) + 1.0f)) * ((_318 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_319 * 18.6875f) + 1.0f)) * ((_319 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f))); - post_lut = _355.rgb; - // Code after sampling - if (injectedData.toneMapType != 0.f) { - return float4(post_lut, 0.f); - } float _368 = ((frac(((sin((((TEXCOORD_2.w) * 543.3099975585938f) + (TEXCOORD_2.z)))) * 493013.0f))) * 0.00390625f) + -0.001953125f; float _369 = _368 + ((_355.x) * 1.0499999523162842f); float _370 = _368 + ((_355.y) * 1.0499999523162842f); diff --git a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl index 59df8af0..61608cd5 100644 --- a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl @@ -103,7 +103,6 @@ float4 main( noperspective float4 SV_Position: SV_Position) : SV_Target { float4 SV_Target; - float3 post_lut; float _41 = ((cb0_048z) * (TEXCOORD_3.x)) + (cb0_048x); float _42 = ((cb0_048w) * (TEXCOORD_3.y)) + (cb0_048y); @@ -165,11 +164,6 @@ float4 main( float _441 = exp2(((log2((_430 * ((((UniformBufferConstants_View_140w) * (_377.y)) * (((cb0_045y) * (_401.y)) + 1.0f)) + ((((((((((_259 - (_217 * 4.0f)) + _281) + _217) - ((ddx_fine(_217)) * _235)) + _217) - ((ddy_fine(_217)) * _239)) * _314) + _217) * (cb0_044y)) * (_350.y)))))) * 0.1593017578125f)); float _442 = exp2(((log2((_430 * ((((UniformBufferConstants_View_140w) * (_377.z)) * (((cb0_045z) * (_401.z)) + 1.0f)) + ((((((((((_260 - (_218 * 4.0f)) + _282) + _218) - ((ddx_fine(_218)) * _235)) + _218) - ((ddy_fine(_218)) * _239)) * _314) + _218) * (cb0_044z)) * (_350.z)))))) * 0.1593017578125f)); float4 _478 = ColorGradingLUT.Sample(ColorGradingLUTSampler, float3((((exp2(((log2(((1.0f / ((_440 * 18.6875f) + 1.0f)) * ((_440 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_441 * 18.6875f) + 1.0f)) * ((_441 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f), (((exp2(((log2(((1.0f / ((_442 * 18.6875f) + 1.0f)) * ((_442 * 18.8515625f) + 0.8359375f)))) * 78.84375f))) * 0.96875f) + 0.015625f))); - post_lut = _478.rgb; - // Code after sampling - if (injectedData.toneMapType != 0.f) { - return float4(post_lut, 0.f); - } float _491 = ((frac(((sin((((TEXCOORD_2.w) * 543.3099975585938f) + (TEXCOORD_2.z)))) * 493013.0f))) * 0.00390625f) + -0.001953125f; float _492 = _491 + ((_478.x) * 1.0499999523162842f); float _493 = _491 + ((_478.y) * 1.0499999523162842f); diff --git a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl index 8db25213..f071f5a3 100644 --- a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl +++ b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl @@ -92,7 +92,6 @@ float4 main( noperspective float4 SV_Position: SV_Position) : SV_Target { float4 SV_Target; - float3 post_lut; // texture _1 = ColorGradingLUT; // texture _2 = BloomDirtMaskTexture; // texture _3 = BlurredLogLum; @@ -457,9 +456,6 @@ float4 main( // _377 = _8; float4 _378 = ColorGradingLUT.Sample(ColorGradingLUTSampler, float3(_373, _374, _375)); - post_lut = _378.rgb; // PQ encoded sRGB bt709 - return float4(post_lut, 0.f); - float _379 = _378.x; float _380 = _378.y; float _381 = _378.z; diff --git a/src/games/stalker2/shared.h b/src/games/stalker2/shared.h index 06e995eb..235a12e1 100644 --- a/src/games/stalker2/shared.h +++ b/src/games/stalker2/shared.h @@ -21,7 +21,6 @@ struct ShaderInjectData { float colorGradeContrast; float colorGradeSaturation; float colorGradeBlowout; - float colorGradeLUTStrength; }; #ifndef __cplusplus cbuffer injectedBuffer : register(b0, space50) { @@ -40,7 +39,6 @@ cbuffer injectedBuffer : register(b0, space50) { 1.f, // colorGradeContrast 1.f, // colorGradeSaturation 0.5f, // colorGradeBlowout - 1.f, // colorGradeLUTStrength }; */ #endif From 7a0f38ca6192ff9d0a5a2d88cefcbe662555e734 Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Tue, 24 Dec 2024 16:58:08 +0400 Subject: [PATCH 04/12] feat(stalker2): Adjust blowout and tonemapping. --- src/games/stalker2/addon.cpp | 6 +-- src/games/stalker2/common.hlsl | 39 ++++++++++++++----- .../crouch_vignette_0xFAD704A3.ps_6_6.hlsl | 1 - .../stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl | 38 ++++-------------- .../lutbuilder_0x6CFBD4C0.ps_6_6.hlsl | 1 - .../lutbuilder_0xB6CA5FD9.ps_6_6.hlsl | 1 - .../lutbuilder_0xBAA27141.ps_6_6.hlsl | 2 - .../stalker2/output_0x20685247.ps_6_6.hlsl | 1 - .../stalker2/output_0x2DAD4682.ps_6_6.hlsl | 2 - .../stalker2/output_0x39EF727B.ps_6_6.hlsl | 1 - .../stalker2/output_0x4D3C673E.ps_6_6.hlsl | 1 - .../stalker2/output_0xECD0D71A.ps_6_6.hlsl | 1 - .../postprocess02_0xED411D4E.ps_6_6.hlsl | 1 - .../radiation01_0x5590F787.ps_6_6.hlsl | 1 - .../vignette02_0x04532088.ps_6_6.hlsl | 1 - 15 files changed, 40 insertions(+), 57 deletions(-) diff --git a/src/games/stalker2/addon.cpp b/src/games/stalker2/addon.cpp index 91c7a084..54dbbc6a 100644 --- a/src/games/stalker2/addon.cpp +++ b/src/games/stalker2/addon.cpp @@ -86,7 +86,7 @@ renodx::utils::settings::Settings settings = { .min = 48.f, .max = 500.f, }, - new renodx::utils::settings::Setting{ + /* new renodx::utils::settings::Setting{ .key = "ToneMapPerChannel", .binding = &shader_injection.toneMapPerChannel, .value_type = renodx::utils::settings::SettingValueType::INTEGER, @@ -96,7 +96,7 @@ renodx::utils::settings::Settings settings = { .tooltip = "Applies tonemapping per-channel instead of by luminance (More accurate to SDR but less saturated)", .labels = {"Off", "On"}, .is_enabled = []() { return shader_injection.toneMapType == 3; }, - }, + }, */ new renodx::utils::settings::Setting{ .key = "radiationOverlayStrength", .binding = &shader_injection.radiationOverlayStrength, @@ -161,7 +161,7 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.02f; }, }, new renodx::utils::settings::Setting{ - .key = "ColorGradeBlowout", + .key = "colorGradeBlowout", .binding = &shader_injection.colorGradeBlowout, .default_value = 50.f, .label = "Blowout", diff --git a/src/games/stalker2/common.hlsl b/src/games/stalker2/common.hlsl index 0923ab5f..ded59ff3 100644 --- a/src/games/stalker2/common.hlsl +++ b/src/games/stalker2/common.hlsl @@ -2,7 +2,7 @@ static const float DEFAULT_BRIGHTNESS = 0.f; // 50% static const float DEFAULT_CONTRAST = 1.f; // 50% -static const float DEFAULT_GAMMA = 1.f; // Approximately 44% +static const float DEFAULT_GAMMA = 1.f; float3 CorrectGamma(float3 color) { color = renodx::color::correct::GammaSafe(color); @@ -42,7 +42,7 @@ float3 RenoDRTSmoothClamp(float3 untonemapped) { renodrt_config.hue_correction_strength = 0.f; renodrt_config.tone_map_method = renodx::tonemap::renodrt::config::tone_map_method::DANIELE; - renodrt_config.working_color_space = 2u; + renodrt_config.working_color_space = 1u; return renodx::tonemap::renodrt::BT709(untonemapped, renodrt_config); } @@ -89,7 +89,7 @@ float3 UpgradePostProcess(float3 tonemappedRender, float3 post_processed, float output = renodx::color::pq::Encode(tonemappedRender, injectedData.toneMapGameNits); } else { post_processed = renodx::color::srgb::DecodeSafe(post_processed); - output = renodx::tonemap::UpgradeToneMap(tonemappedRender, saturate(tonemappedRender), saturate(post_processed), lerpValue); + output = UpgradeToneMapPerChannel(tonemappedRender, saturate(tonemappedRender), saturate(post_processed), lerpValue); output = renodx::color::pq::Encode(output, injectedData.toneMapGameNits); } } @@ -129,22 +129,43 @@ float3 ToneMap(float3 bt709) { // Default inverts smooth clamp config.reno_drt_highlights = 1.0f; config.reno_drt_shadows = 1.0f; - config.reno_drt_contrast = 1.f; - // config.reno_drt_saturation = 1.05f; - // 1.1f better matches ACES - config.reno_drt_saturation = 1.1f; + config.reno_drt_contrast = 1.05f; + config.reno_drt_saturation = 1.05f; config.reno_drt_dechroma = 0; config.reno_drt_blowout = injectedData.colorGradeBlowout; // Flare darkens too much (stalker2) // config.reno_drt_flare = 0.10f * injectedData.colorGradeFlare; - config.reno_drt_working_color_space = 2u; - config.reno_drt_per_channel = injectedData.toneMapPerChannel != 0; + config.reno_drt_working_color_space = 1u; + config.reno_drt_per_channel = true; float3 output_color = renodx::tonemap::config::Apply(bt709, config); return output_color; } +float4 FinalizeUEOutput(float4 scene, float4 ui, bool is_hdr10 = true, bool only_correct_ui = false) { + scene.rgb = renodx::color::pq::Decode(scene.rgb, injectedData.toneMapGameNits); + + ui.rgb = renodx::color::srgb::Decode(ui.rgb); + ui.rgb = renodx::color::bt2020::from::BT709(ui.rgb); + if (only_correct_ui) { + ui.rgb = CorrectGamma(ui.rgb); + } + ui.rgb = ui.rgb * injectedData.toneMapUINits / injectedData.toneMapGameNits; + + if (is_hdr10) { + scene.rgb = lerp(scene.rgb, ui.rgb, ui.a); + if (!only_correct_ui) { + scene.rgb = CorrectGamma(scene.rgb); + } + scene.rgb = renodx::color::pq::Encode(scene.rgb, injectedData.toneMapGameNits); + + return float4(scene.rgb, ui.a); + } else { + return scene; + } +} + float3 FinalizeTonemap(float3 color, bool is_hdr10 = true) { color = renodx::color::gamma::DecodeSafe(color); color *= injectedData.toneMapUINits; diff --git a/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl b/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl index 13d96ce8..bfafdb0e 100644 --- a/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl +++ b/src/games/stalker2/crouch_vignette_0xFAD704A3.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D PostProcessInput_0_Texture : register(t0); diff --git a/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl b/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl index 0137fa76..e49f871e 100644 --- a/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl +++ b/src/games/stalker2/final00_0xA7EFB8C2.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D UITexture : register(t0); @@ -77,32 +76,18 @@ float4 main( float _54 = _53 * _45; float _55 = _53 * _48; float _56 = _53 * _51; - float3 uiTexture = float3(_54, _55, _56); // _57 = _1; // _58 = _3; // We don't use finalize here because it messes up with FSR3 FG float4 _59 = SceneTexture.Sample(SceneSampler, float2(_7, _8)); - float3 scene = _59.rgb; - scene = renodx::color::pq::Decode(scene.rgb, injectedData.toneMapGameNits); - uiTexture.rgb = CorrectGamma(uiTexture.rgb); - - // Multiply by game's because we're encoding PQ later - uiTexture.rgb = uiTexture.rgb * injectedData.toneMapUINits / injectedData.toneMapGameNits; - - _54 = uiTexture.r; - _55 = uiTexture.g; - _56 = uiTexture.b; + return FinalizeUEOutput(_59, _11, true, true); float _60 = _59.x; float _61 = _59.y; float _62 = _59.z; - _60 = scene.r; - _61 = scene.g; - _62 = scene.b; - - /* float _63 = log2(_60); + float _63 = log2(_60); float _64 = log2(_61); float _65 = log2(_62); float _66 = _63 * 0.012683313339948654f; @@ -137,26 +122,20 @@ float4 main( float _95 = exp2(_92); float _96 = _93 * 10000.0f; float _97 = _94 * 10000.0f; - float _98 = _95 * 10000.0f; */ + float _98 = _95 * 10000.0f; float _99 = $Globals_007z; _99 = 1.f; // Disable game's UI level setting bool _100 = (_15 > 0.0f); bool _101 = (_15 < 1.0f); bool _102 = _100 && _101; - /* float _119 = _96; + float _119 = _96; float _120 = _97; - float _121 = _98; */ - float _119 = scene.r; - float _120 = scene.g; - float _121 = scene.b; + float _121 = _98; if (_102) { - /* float _104 = max(_96, 0.0f); + float _104 = max(_96, 0.0f); float _105 = max(_97, 0.0f); - float _106 = max(_98, 0.0f); */ - float _104 = max(scene.r, 0.0f); - float _105 = max(scene.g, 0.0f); - float _106 = max(scene.b, 0.0f); + float _106 = max(_98, 0.0f); float _107 = dot(float3(_104, _105, _106), float3(0.26269999146461487f, 0.6779999732971191f, 0.059300001710653305f)); float _108 = _107 / _99; float _109 = _108 + 1.0f; @@ -184,9 +163,6 @@ float4 main( float _129 = _123 + _126; float _130 = _124 + _127; float _131 = _125 + _128; - float3 output = float3(_129, _130, _131); - output = renodx::color::pq::Encode(output.rgb, injectedData.toneMapGameNits); - return float4(output, _15); float _132 = _129 * 9.999999747378752e-05f; float _133 = _130 * 9.999999747378752e-05f; diff --git a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl index 2205284c..b177a3c2 100644 --- a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl @@ -1,5 +1,4 @@ #include "./common.hlsl" -#include "./shared.h" Texture2D Textures_1 : register(t0); diff --git a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl index 44de9fab..dada0377 100644 --- a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl @@ -1,5 +1,4 @@ #include "./common.hlsl" -#include "./shared.h" Texture2D Textures_1 : register(t0); diff --git a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl index 657d3c76..b217a3bf 100644 --- a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl @@ -1,7 +1,5 @@ #include "./common.hlsl" -#include "./shared.h" - cbuffer _RootShaderParameters : register(b0) { float _RootShaderParameters_008x : packoffset(c008.x); diff --git a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl index 7e8d8e92..9a2f9364 100644 --- a/src/games/stalker2/output_0x20685247.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x20685247.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl index d6ecbd6e..94593189 100644 --- a/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x2DAD4682.ps_6_6.hlsl @@ -1,6 +1,4 @@ #include "./common.hlsl" -#include "./shared.h" - Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl index 45845b16..c1e131a3 100644 --- a/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x39EF727B.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl index 61608cd5..c2157c7c 100644 --- a/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl +++ b/src/games/stalker2/output_0x4D3C673E.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl index f071f5a3..0c0cd5e2 100644 --- a/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl +++ b/src/games/stalker2/output_0xECD0D71A.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D ColorTexture : register(t0); diff --git a/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl b/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl index 1aa6a634..38a0061c 100644 --- a/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl +++ b/src/games/stalker2/postprocess02_0xED411D4E.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D SceneTexturesStruct_SceneDepthTexture : register(t0); diff --git a/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl b/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl index 08772e3e..93ce558d 100644 --- a/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl +++ b/src/games/stalker2/radiation01_0x5590F787.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D Material_Texture2D_0 : register(t0); diff --git a/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl b/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl index a02184d1..c61a1b05 100644 --- a/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl +++ b/src/games/stalker2/vignette02_0x04532088.ps_6_6.hlsl @@ -1,4 +1,3 @@ -#include "./shared.h" #include "./common.hlsl" Texture2D SceneTexturesStruct_SceneDepthTexture : register(t0); From 216cb5fd3a6f5478eb15b40c4c5a86689142b6f4 Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Thu, 26 Dec 2024 17:29:31 +0400 Subject: [PATCH 05/12] refactor(stalker2): Adjust untonemapped_ap1, and cb index --- src/games/stalker2/addon.cpp | 10 +- .../lutbuilder_0x6CFBD4C0.ps_6_6.hlsl | 15 +- .../lutbuilder_0xB6CA5FD9.ps_6_6.hlsl | 13 +- .../lutbuilder_0xBAA27141.ps_6_6.hlsl | 301 +++++++++--------- src/games/stalker2/shared.h | 16 +- 5 files changed, 168 insertions(+), 187 deletions(-) diff --git a/src/games/stalker2/addon.cpp b/src/games/stalker2/addon.cpp index 54dbbc6a..c697acc6 100644 --- a/src/games/stalker2/addon.cpp +++ b/src/games/stalker2/addon.cpp @@ -263,19 +263,17 @@ BOOL APIENTRY DllMain(HMODULE h_module, DWORD fdw_reason, LPVOID lpv_reserved) { renodx::mods::swapchain::SetUseHDR10(true); renodx::mods::shader::force_pipeline_cloning = true; renodx::mods::shader::expected_constant_buffer_space = 50; - renodx::mods::swapchain::use_resize_buffer = true; - renodx::mods::swapchain::use_resize_buffer_on_demand = true; - renodx::mods::swapchain::force_borderless = false; - renodx::mods::swapchain::prevent_full_screen = false; + renodx::mods::shader::expected_constant_buffer_index = 13; + renodx::mods::shader::allow_multiple_push_constants = true; /* renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({ .old_format = reshade::api::format::r8g8b8a8_unorm, .new_format = reshade::api::format::r16g16b16a16_float, }); */ - renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({.old_format = reshade::api::format::r10g10b10a2_unorm, + /* renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({.old_format = reshade::api::format::r10g10b10a2_unorm, .new_format = reshade::api::format::r16g16b16a16_float, - .dimensions = {32, 32, 32}}); + .dimensions = {32, 32, 32}}); */ break; case DLL_PROCESS_DETACH: diff --git a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl index b177a3c2..15fce84a 100644 --- a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl @@ -1,4 +1,5 @@ #include "./common.hlsl" +#include "./shared.h" Texture2D Textures_1 : register(t0); @@ -173,9 +174,6 @@ float4 main( // cbuffer _4 = _RootShaderParameters; // _5 = _3; // _6 = _4; - // CustomEdit - uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = ShouldTonemap(output_type); uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; @@ -750,6 +748,9 @@ float4 main( float _533 = _532 + _525; float _534 = _529 + _523; float _535 = _534 + _526; + + float3 untonemapped_ap1 = float3(_531, _533, _535); // CustomEdit + float _537 = UniformBufferConstants_WorkingColorSpace_012x; float _538 = UniformBufferConstants_WorkingColorSpace_012y; float _539 = UniformBufferConstants_WorkingColorSpace_012z; @@ -785,7 +786,6 @@ float4 main( float _571 = _568 + _531; float _572 = _569 + _533; float _573 = _570 + _535; - float3 untonmapped_ap1 = float3(_571, _572, _573); // CustomEdit float _574 = _571 * 0.6954522132873535f; float _575 = mad(0.14067868888378143f, _572, _574); @@ -1295,7 +1295,7 @@ float4 main( float _1062 = _1059 + _1053; float _1064 = _RootShaderParameters_040y; - if (shouldTonemap) { + if (injectedData.toneMapType != 0) { _1064 = DEFAULT_GAMMA; } float _1065 = max(0.0f, _1048); @@ -1312,9 +1312,8 @@ float4 main( float _1076 = exp2(_1073); // CustomEdit - float3 film_graded_color = float3(_1074, _1075, _1076); - if (shouldTonemap) { - return LutBuilderToneMap(untonmapped_ap1, film_graded_color); + if (injectedData.toneMapType != 0) { + return LutBuilderToneMap(untonemapped_ap1, float3(_1074, _1075, _1076)); } uint _1078 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl index dada0377..0bf60485 100644 --- a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl @@ -1,4 +1,5 @@ #include "./common.hlsl" +#include "./shared.h" Texture2D Textures_1 : register(t0); @@ -194,9 +195,6 @@ float4 main( // cbuffer _4 = _RootShaderParameters; // _5 = _3; // _6 = _4; - // CustomEdit - uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = ShouldTonemap(output_type); uint _7 = SV_RenderTargetArrayIndex; float _8 = TEXCOORD.x; float _9 = TEXCOORD.y; @@ -1042,6 +1040,9 @@ float4 main( float _809 = mad(_800, _787, _808); float _810 = mad(_801, _789, _809); float _811 = _RootShaderParameters_036y; + + float3 untonemapped_ap1 = float3(_785, _787, _789); // CustomEdit + float _812 = _785 * 0.9386394023895264f; float _813 = mad(-4.540197551250458e-09f, _787, _812); float _814 = mad(0.061360642313957214f, _789, _813); @@ -1058,7 +1059,6 @@ float4 main( float _825 = _822 + _785; float _826 = _823 + _787; float _827 = _824 + _789; - float3 untonmapped_ap1 = float3(_825, _826, _827); // CustomEdit float _828 = _825 * 0.6954522132873535f; float _829 = mad(0.14067868888378143f, _826, _828); @@ -1579,9 +1579,8 @@ float4 main( float _1330 = exp2(_1327); // CustomEdit - float3 film_graded_color = float3(_1328, _1329, _1330); - if (shouldTonemap) { - return LutBuilderToneMap(untonmapped_ap1, film_graded_color); + if (injectedData.toneMapType != 0) { + return LutBuilderToneMap(untonemapped_ap1, float3(_1328, _1329, _1330)); } uint _1332 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl index b217a3bf..d04352ad 100644 --- a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl @@ -1,5 +1,6 @@ #include "./common.hlsl" +#include "./shared.h" cbuffer _RootShaderParameters : register(b0) { float _RootShaderParameters_008x : packoffset(c008.x); @@ -166,8 +167,6 @@ float4 main( // cbuffer _2 = _RootShaderParameters; // _3 = _1; // _4 = _2; - uint output_type = _RootShaderParameters_040w; - bool shouldTonemap = ShouldTonemap(output_type); uint _5 = SV_RenderTargetArrayIndex; float _6 = TEXCOORD.x; float _7 = TEXCOORD.y; @@ -757,6 +756,9 @@ float4 main( float _553 = mad(_544, _531, _552); float _554 = mad(_545, _533, _553); float _555 = _RootShaderParameters_036y; + + float3 untonemapped_ap1 = float3(_529, _531, _533); // CustomEdit + float _556 = _529 * 0.9386394023895264f; float _557 = mad(-4.540197551250458e-09f, _531, _556); float _558 = mad(0.061360642313957214f, _533, _557); @@ -773,7 +775,6 @@ float4 main( float _569 = _566 + _529; float _570 = _567 + _531; float _571 = _568 + _533; - float3 untonmapped_ap1 = float3(_569, _570, _571); // CustomEdit float _572 = _569 * 0.6954522132873535f; float _573 = mad(0.14067868888378143f, _570, _572); @@ -935,151 +936,150 @@ float4 main( float _721 = _RootShaderParameters_037z; float _722 = _720 - _721; - bool _723 = (_716 > 0.800000011920929f); - float _724 = _RootShaderParameters_037x; - if (_723) { - float _726 = 0.8199999928474426f - _716; - float _727 = _726 / _724; - float _728 = _727 + -0.7447274923324585f; - _740 = _728; - } else { - float _730 = _714 + 0.18000000715255737f; - float _731 = _730 / _717; - float _732 = 2.0f - _731; - float _733 = _731 / _732; - float _734 = log2(_733); - float _735 = _734 * 0.3465735912322998f; - float _736 = _717 / _724; - float _737 = _735 * _736; - float _738 = -0.7447274923324585f - _737; - _740 = _738; - } - float _741 = 1.0f - _716; - float _742 = _741 / _724; - float _743 = _742 - _740; - float _744 = _721 / _724; - float _745 = _744 - _743; - float _746 = log2(_710); - float _747 = log2(_711); - float _748 = log2(_712); - float _749 = _746 * 0.3010300099849701f; - float _750 = _747 * 0.3010300099849701f; - float _751 = _748 * 0.3010300099849701f; - float _752 = _749 + _743; - float _753 = _750 + _743; - float _754 = _751 + _743; - float _755 = _724 * _752; - float _756 = _724 * _753; - float _757 = _724 * _754; - float _758 = _717 * 2.0f; - float _759 = _724 * -2.0f; - float _760 = _759 / _717; - float _761 = _749 - _740; - float _762 = _750 - _740; - float _763 = _751 - _740; - float _764 = _761 * 1.4426950216293335f; - float _765 = _764 * _760; - float _766 = _762 * 1.4426950216293335f; - float _767 = _766 * _760; - float _768 = _763 * 1.4426950216293335f; - float _769 = _768 * _760; - float _770 = exp2(_765); - float _771 = exp2(_767); - float _772 = exp2(_769); - float _773 = _770 + 1.0f; - float _774 = _771 + 1.0f; - float _775 = _772 + 1.0f; - float _776 = _758 / _773; - float _777 = _758 / _774; - float _778 = _758 / _775; - float _779 = _776 - _714; - float _780 = _777 - _714; - float _781 = _778 - _714; - float _782 = _722 * 2.0f; - float _783 = _724 * 2.0f; - float _784 = _783 / _722; - float _785 = _749 - _745; - float _786 = _750 - _745; - float _787 = _751 - _745; - float _788 = _785 * 1.4426950216293335f; - float _789 = _788 * _784; - float _790 = _786 * 1.4426950216293335f; - float _791 = _790 * _784; - float _792 = _787 * 1.4426950216293335f; - float _793 = _792 * _784; - float _794 = exp2(_789); - float _795 = exp2(_791); - float _796 = exp2(_793); - float _797 = _794 + 1.0f; - float _798 = _795 + 1.0f; - float _799 = _796 + 1.0f; - float _800 = _782 / _797; - float _801 = _782 / _798; - float _802 = _782 / _799; - float _803 = _720 - _800; - float _804 = _720 - _801; - float _805 = _720 - _802; - bool _806 = (_749 < _740); - bool _807 = (_750 < _740); - bool _808 = (_751 < _740); - float _809 = _806 ? _779 : _755; - float _810 = _807 ? _780 : _756; - float _811 = _808 ? _781 : _757; - bool _812 = (_749 > _745); - bool _813 = (_750 > _745); - bool _814 = (_751 > _745); - float _815 = _812 ? _803 : _755; - float _816 = _813 ? _804 : _756; - float _817 = _814 ? _805 : _757; - float _818 = _745 - _740; - float _819 = _761 / _818; - float _820 = _762 / _818; - float _821 = _763 / _818; - float _822 = saturate(_819); - float _823 = saturate(_820); - float _824 = saturate(_821); - bool _825 = (_745 < _740); - float _826 = 1.0f - _822; - float _827 = 1.0f - _823; - float _828 = 1.0f - _824; - float _829 = _825 ? _826 : _822; - float _830 = _825 ? _827 : _823; - float _831 = _825 ? _828 : _824; - float _832 = _829 * 2.0f; - float _833 = _830 * 2.0f; - float _834 = _831 * 2.0f; - float _835 = 3.0f - _832; - float _836 = 3.0f - _833; - float _837 = 3.0f - _834; - float _838 = _815 - _809; - float _839 = _816 - _810; - float _840 = _817 - _811; - float _841 = _829 * _829; - float _842 = _841 * _838; - float _843 = _842 * _835; - float _844 = _830 * _830; - float _845 = _844 * _839; - float _846 = _845 * _836; - float _847 = _831 * _831; - float _848 = _847 * _840; - float _849 = _848 * _837; - float _850 = _843 + _809; - float _851 = _846 + _810; - float _852 = _849 + _811; - float _853 = dot(float3(_850, _851, _852), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); - float _854 = _850 - _853; - float _855 = _851 - _853; - float _856 = _852 - _853; - float _857 = _854 * 0.9300000071525574f; - float _858 = _855 * 0.9300000071525574f; - float _859 = _856 * 0.9300000071525574f; - float _860 = _857 + _853; - float _861 = _858 + _853; - float _862 = _859 + _853; - float _863 = max(0.0f, _860); - float _864 = max(0.0f, _861); - float _865 = max(0.0f, _862); - + bool _723 = (_716 > 0.800000011920929f); + float _724 = _RootShaderParameters_037x; + if (_723) { + float _726 = 0.8199999928474426f - _716; + float _727 = _726 / _724; + float _728 = _727 + -0.7447274923324585f; + _740 = _728; + } else { + float _730 = _714 + 0.18000000715255737f; + float _731 = _730 / _717; + float _732 = 2.0f - _731; + float _733 = _731 / _732; + float _734 = log2(_733); + float _735 = _734 * 0.3465735912322998f; + float _736 = _717 / _724; + float _737 = _735 * _736; + float _738 = -0.7447274923324585f - _737; + _740 = _738; + } + float _741 = 1.0f - _716; + float _742 = _741 / _724; + float _743 = _742 - _740; + float _744 = _721 / _724; + float _745 = _744 - _743; + float _746 = log2(_710); + float _747 = log2(_711); + float _748 = log2(_712); + float _749 = _746 * 0.3010300099849701f; + float _750 = _747 * 0.3010300099849701f; + float _751 = _748 * 0.3010300099849701f; + float _752 = _749 + _743; + float _753 = _750 + _743; + float _754 = _751 + _743; + float _755 = _724 * _752; + float _756 = _724 * _753; + float _757 = _724 * _754; + float _758 = _717 * 2.0f; + float _759 = _724 * -2.0f; + float _760 = _759 / _717; + float _761 = _749 - _740; + float _762 = _750 - _740; + float _763 = _751 - _740; + float _764 = _761 * 1.4426950216293335f; + float _765 = _764 * _760; + float _766 = _762 * 1.4426950216293335f; + float _767 = _766 * _760; + float _768 = _763 * 1.4426950216293335f; + float _769 = _768 * _760; + float _770 = exp2(_765); + float _771 = exp2(_767); + float _772 = exp2(_769); + float _773 = _770 + 1.0f; + float _774 = _771 + 1.0f; + float _775 = _772 + 1.0f; + float _776 = _758 / _773; + float _777 = _758 / _774; + float _778 = _758 / _775; + float _779 = _776 - _714; + float _780 = _777 - _714; + float _781 = _778 - _714; + float _782 = _722 * 2.0f; + float _783 = _724 * 2.0f; + float _784 = _783 / _722; + float _785 = _749 - _745; + float _786 = _750 - _745; + float _787 = _751 - _745; + float _788 = _785 * 1.4426950216293335f; + float _789 = _788 * _784; + float _790 = _786 * 1.4426950216293335f; + float _791 = _790 * _784; + float _792 = _787 * 1.4426950216293335f; + float _793 = _792 * _784; + float _794 = exp2(_789); + float _795 = exp2(_791); + float _796 = exp2(_793); + float _797 = _794 + 1.0f; + float _798 = _795 + 1.0f; + float _799 = _796 + 1.0f; + float _800 = _782 / _797; + float _801 = _782 / _798; + float _802 = _782 / _799; + float _803 = _720 - _800; + float _804 = _720 - _801; + float _805 = _720 - _802; + bool _806 = (_749 < _740); + bool _807 = (_750 < _740); + bool _808 = (_751 < _740); + float _809 = _806 ? _779 : _755; + float _810 = _807 ? _780 : _756; + float _811 = _808 ? _781 : _757; + bool _812 = (_749 > _745); + bool _813 = (_750 > _745); + bool _814 = (_751 > _745); + float _815 = _812 ? _803 : _755; + float _816 = _813 ? _804 : _756; + float _817 = _814 ? _805 : _757; + float _818 = _745 - _740; + float _819 = _761 / _818; + float _820 = _762 / _818; + float _821 = _763 / _818; + float _822 = saturate(_819); + float _823 = saturate(_820); + float _824 = saturate(_821); + bool _825 = (_745 < _740); + float _826 = 1.0f - _822; + float _827 = 1.0f - _823; + float _828 = 1.0f - _824; + float _829 = _825 ? _826 : _822; + float _830 = _825 ? _827 : _823; + float _831 = _825 ? _828 : _824; + float _832 = _829 * 2.0f; + float _833 = _830 * 2.0f; + float _834 = _831 * 2.0f; + float _835 = 3.0f - _832; + float _836 = 3.0f - _833; + float _837 = 3.0f - _834; + float _838 = _815 - _809; + float _839 = _816 - _810; + float _840 = _817 - _811; + float _841 = _829 * _829; + float _842 = _841 * _838; + float _843 = _842 * _835; + float _844 = _830 * _830; + float _845 = _844 * _839; + float _846 = _845 * _836; + float _847 = _831 * _831; + float _848 = _847 * _840; + float _849 = _848 * _837; + float _850 = _843 + _809; + float _851 = _846 + _810; + float _852 = _849 + _811; + float _853 = dot(float3(_850, _851, _852), float3(0.2722287178039551f, 0.6740817427635193f, 0.053689517080783844f)); + float _854 = _850 - _853; + float _855 = _851 - _853; + float _856 = _852 - _853; + float _857 = _854 * 0.9300000071525574f; + float _858 = _855 * 0.9300000071525574f; + float _859 = _856 * 0.9300000071525574f; + float _860 = _857 + _853; + float _861 = _858 + _853; + float _862 = _859 + _853; + float _863 = max(0.0f, _860); + float _864 = max(0.0f, _861); + float _865 = max(0.0f, _862); float _866 = _RootShaderParameters_036w; float _867 = _863 - _569; @@ -1186,9 +1186,8 @@ float4 main( float _968 = exp2(_965); // CustomEdit - float3 film_graded_color = float3(_966, _967, _968); - if (shouldTonemap) { - return LutBuilderToneMap(untonmapped_ap1, film_graded_color); + if (injectedData.toneMapType != 0) { + return LutBuilderToneMap(untonemapped_ap1, float3(_966, _967, _968)); } uint _970 = _RootShaderParameters_040w; diff --git a/src/games/stalker2/shared.h b/src/games/stalker2/shared.h index 235a12e1..14417af3 100644 --- a/src/games/stalker2/shared.h +++ b/src/games/stalker2/shared.h @@ -23,23 +23,9 @@ struct ShaderInjectData { float colorGradeBlowout; }; #ifndef __cplusplus -cbuffer injectedBuffer : register(b0, space50) { +cbuffer injectedBuffer : register(b13, space50) { ShaderInjectData injectedData : packoffset(c0); } -/* static const ShaderInjectData injectedData = { - 2.f, // toneMapType - 800.f, // toneMapPeakNits - 200.f, // toneMapGameNits - 150.f, // toneMapUINits - 1.f, // radiationOverlayStrength - 1.f, // vignette - 1.f, // colorGradeExposure - 1.f, // colorGradeHighlights - 1.f, // colorGradeShadows - 1.f, // colorGradeContrast - 1.f, // colorGradeSaturation - 0.5f, // colorGradeBlowout -}; */ #endif #endif // SRC_STALKER2_SHARED_H_ From 6e3089d020ac80a2725caeb67f00f718d0ba4017 Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Tue, 7 Jan 2025 16:53:16 +0400 Subject: [PATCH 06/12] feat(stalker2): Switch to UpgradeToneMapByLuminance --- src/games/stalker2/addon.cpp | 6 +- src/games/stalker2/common.hlsl | 55 +++++++++++++------ .../lutbuilder_0x6CFBD4C0.ps_6_6.hlsl | 1 - .../lutbuilder_0xB6CA5FD9.ps_6_6.hlsl | 1 - .../lutbuilder_0xBAA27141.ps_6_6.hlsl | 1 - 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/games/stalker2/addon.cpp b/src/games/stalker2/addon.cpp index c697acc6..72caed3b 100644 --- a/src/games/stalker2/addon.cpp +++ b/src/games/stalker2/addon.cpp @@ -164,12 +164,12 @@ renodx::utils::settings::Settings settings = { .key = "colorGradeBlowout", .binding = &shader_injection.colorGradeBlowout, .default_value = 50.f, - .label = "Blowout", + .label = "Highlight saturation", .section = "Color Grading", - .tooltip = "Controls highlight desaturation due to overexposure.", + .tooltip = "Controls highlight saturation due to overexposure.", .max = 100.f, .is_enabled = []() { return shader_injection.toneMapType == 3; }, - .parse = [](float value) { return value * 0.02f - 1.f; }, + .parse = [](float value) { return (value * -0.02f) + 1.f; }, }, new renodx::utils::settings::Setting{ .value_type = renodx::utils::settings::SettingValueType::TEXT, diff --git a/src/games/stalker2/common.hlsl b/src/games/stalker2/common.hlsl index ded59ff3..2f5eef06 100644 --- a/src/games/stalker2/common.hlsl +++ b/src/games/stalker2/common.hlsl @@ -40,25 +40,23 @@ float3 RenoDRTSmoothClamp(float3 untonemapped) { renodrt_config.dechroma = 0.f; renodrt_config.flare = 0.f; renodrt_config.hue_correction_strength = 0.f; - renodrt_config.tone_map_method = - renodx::tonemap::renodrt::config::tone_map_method::DANIELE; - renodrt_config.working_color_space = 1u; + renodrt_config.working_color_space = 0u; return renodx::tonemap::renodrt::BT709(untonemapped, renodrt_config); } -float UpgradeToneMapRatio(float ap1_color_hdr, float ap1_color_sdr, float ap1_post_process_color) { - if (ap1_color_hdr < ap1_color_sdr) { +float UpgradeToneMapRatio(float color_hdr, float color_sdr, float post_process_color) { + if (color_hdr < color_sdr) { // If substracting (user contrast or paperwhite) scale down instead // Should only apply on mismatched HDR - return ap1_color_hdr / ap1_color_sdr; + return color_hdr / color_sdr; } else { - float ap1_delta = ap1_color_hdr - ap1_color_sdr; - ap1_delta = max(0, ap1_delta); // Cleans up NaN - const float ap1_new = ap1_post_process_color + ap1_delta; + float delta = color_hdr - color_sdr; + delta = max(0, delta); // Cleans up NaN + const float new_value = post_process_color + delta; - const bool ap1_valid = (ap1_post_process_color > 0); // Cleans up NaN and ignore black - return ap1_valid ? (ap1_new / ap1_post_process_color) : 0; + const bool valid = (post_process_color > 0); // Cleans up NaN and ignore black + return valid ? (new_value / post_process_color) : 0; } } float3 UpgradeToneMapPerChannel(float3 color_hdr, float3 color_sdr, float3 post_process_color, float post_process_strength) { @@ -80,6 +78,24 @@ float3 UpgradeToneMapPerChannel(float3 color_hdr, float3 color_sdr, float3 post_ return lerp(color_hdr, color_scaled, post_process_strength); } +float3 UpgradeToneMapByLuminance(float3 color_hdr, float3 color_sdr, float3 post_process_color, float post_process_strength) { + // float ratio = 1.f; + + float3 bt2020_hdr = max(0, renodx::color::bt2020::from::BT709(color_hdr)); + float3 bt2020_sdr = max(0, renodx::color::bt2020::from::BT709(color_sdr)); + float3 bt2020_post_process = max(0, renodx::color::bt2020::from::BT709(post_process_color)); + + float ratio = UpgradeToneMapRatio( + renodx::color::y::from::BT2020(bt2020_hdr), + renodx::color::y::from::BT2020(bt2020_sdr), + renodx::color::y::from::BT2020(bt2020_post_process)); + + float3 color_scaled = max(0, bt2020_post_process * ratio); + color_scaled = renodx::color::bt709::from::BT2020(color_scaled); + color_scaled = renodx::color::correct::Hue(color_scaled, post_process_color); + return lerp(color_hdr, color_scaled, post_process_strength); +} + float3 UpgradePostProcess(float3 tonemappedRender, float3 post_processed, float lerpValue = 1.f) { float3 output = post_processed; if (injectedData.toneMapType == 1.f) { @@ -135,8 +151,8 @@ float3 ToneMap(float3 bt709) { config.reno_drt_blowout = injectedData.colorGradeBlowout; // Flare darkens too much (stalker2) // config.reno_drt_flare = 0.10f * injectedData.colorGradeFlare; - config.reno_drt_working_color_space = 1u; - config.reno_drt_per_channel = true; + config.reno_drt_working_color_space = 2u; + config.reno_drt_per_channel = false; float3 output_color = renodx::tonemap::config::Apply(bt709, config); @@ -176,20 +192,27 @@ float3 FinalizeTonemap(float3 color, bool is_hdr10 = true) { return color; } -float4 LutBuilderToneMap(float3 untonemapped_ap1, float3 tonemapped_bt709) { +float3 UpgradeToneMapAP1(float3 untonemapped_ap1, float3 tonemapped_bt709) { float3 untonemapped_bt709 = renodx::color::bt709::from::AP1(untonemapped_ap1); float3 neutral_sdr_color = RenoDRTSmoothClamp(untonemapped_bt709); - float3 untonemapped_graded = UpgradeToneMapPerChannel( + float3 untonemapped_graded; + + untonemapped_graded = UpgradeToneMapByLuminance( untonemapped_bt709, neutral_sdr_color, tonemapped_bt709, 1); - float3 color = ToneMap(untonemapped_graded); + return ToneMap(untonemapped_graded); +} + +float4 LutBuilderToneMap(float3 untonemapped_ap1, float3 tonemapped_bt709) { + float3 color = UpgradeToneMapAP1(untonemapped_ap1, tonemapped_bt709); // Correct gamma in final shader causes issues with FSR3 FG + color = renodx::color::bt709::clamp::BT2020(color); color = renodx::color::bt2020::from::BT709(color); color = CorrectGamma(color); color = renodx::color::pq::Encode(color, injectedData.toneMapGameNits); diff --git a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl index 15fce84a..2b2b462c 100644 --- a/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0x6CFBD4C0.ps_6_6.hlsl @@ -1,5 +1,4 @@ #include "./common.hlsl" -#include "./shared.h" Texture2D Textures_1 : register(t0); diff --git a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl index 0bf60485..76e10687 100644 --- a/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xB6CA5FD9.ps_6_6.hlsl @@ -1,5 +1,4 @@ #include "./common.hlsl" -#include "./shared.h" Texture2D Textures_1 : register(t0); diff --git a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl index d04352ad..685aa300 100644 --- a/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl +++ b/src/games/stalker2/lutbuilder_0xBAA27141.ps_6_6.hlsl @@ -1,6 +1,5 @@ #include "./common.hlsl" -#include "./shared.h" cbuffer _RootShaderParameters : register(b0) { float _RootShaderParameters_008x : packoffset(c008.x); From 6c9e9565173ce84e9174eca5789e9f972654979e Mon Sep 17 00:00:00 2001 From: Mohanned Hassan Date: Fri, 3 Jan 2025 15:14:41 +0400 Subject: [PATCH 07/12] feat(tacticalbreachwizards): Add mod --- src/games/tacticalbreachwizards/DICE.hlsl | 252 ++++++++++++ ...LUT3DBakerNoTonemap_0x995B320A.cs_5_0.hlsl | 139 +++++++ src/games/tacticalbreachwizards/addon.cpp | 359 ++++++++++++++++++ src/games/tacticalbreachwizards/common.hlsl | 162 ++++++++ .../glow_composite_0xD863ED6A.ps_4_0.hlsl | 40 ++ .../output_0xC8C2F1A0.ps_4_0.hlsl | 117 ++++++ .../output_0xEB23B0ED.ps_5_0.hlsl | 39 ++ src/games/tacticalbreachwizards/shared.h | 35 ++ .../swap_chain_proxy_pixel_shader.ps_4_0.hlsl | 12 + ...swap_chain_proxy_vertex_shader.vs_4_0.hlsl | 6 + 10 files changed, 1161 insertions(+) create mode 100644 src/games/tacticalbreachwizards/DICE.hlsl create mode 100644 src/games/tacticalbreachwizards/LUT3DBakerNoTonemap_0x995B320A.cs_5_0.hlsl create mode 100644 src/games/tacticalbreachwizards/addon.cpp create mode 100644 src/games/tacticalbreachwizards/common.hlsl create mode 100644 src/games/tacticalbreachwizards/glow_composite_0xD863ED6A.ps_4_0.hlsl create mode 100644 src/games/tacticalbreachwizards/output_0xC8C2F1A0.ps_4_0.hlsl create mode 100644 src/games/tacticalbreachwizards/output_0xEB23B0ED.ps_5_0.hlsl create mode 100644 src/games/tacticalbreachwizards/shared.h create mode 100644 src/games/tacticalbreachwizards/swap_chain_proxy_pixel_shader.ps_4_0.hlsl create mode 100644 src/games/tacticalbreachwizards/swap_chain_proxy_vertex_shader.vs_4_0.hlsl diff --git a/src/games/tacticalbreachwizards/DICE.hlsl b/src/games/tacticalbreachwizards/DICE.hlsl new file mode 100644 index 00000000..55ae6160 --- /dev/null +++ b/src/games/tacticalbreachwizards/DICE.hlsl @@ -0,0 +1,252 @@ +#include "./shared.h" + +static const float HDR10_MaxWhiteNits = 10000.0f; +static const float FLT_MAX = asfloat(0x7F7FFFFF); // 3.402823466e+38f + +float max3(float a, float b, float c) { + return max(a, max(b, c)); +} + +float max3(float3 v) { + return max3(v.x, v.y, v.z); +} + +static const float PQ_constant_M1 = 0.1593017578125f; +static const float PQ_constant_M2 = 78.84375f; +static const float PQ_constant_C1 = 0.8359375f; +static const float PQ_constant_C2 = 18.8515625f; +static const float PQ_constant_C3 = 18.6875f; + +// PQ (Perceptual Quantizer - ST.2084) encode/decode used for HDR10 BT.2100. +// Clamp type: +// 0 None +// 1 Remove negative numbers +// 2 Remove numbers beyond 0-1 +// 3 Mirror negative numbers +float3 Linear_to_PQ(float3 LinearColor, int clampType = 0) { + float3 LinearColorSign = sign(LinearColor); + if (clampType == 1) { + LinearColor = max(LinearColor, 0.f); + } else if (clampType == 2) { + LinearColor = saturate(LinearColor); + } else if (clampType == 3) { + LinearColor = abs(LinearColor); + } + float3 colorPow = pow(LinearColor, PQ_constant_M1); + float3 numerator = PQ_constant_C1 + PQ_constant_C2 * colorPow; + float3 denominator = 1.f + PQ_constant_C3 * colorPow; + float3 pq = pow(numerator / denominator, PQ_constant_M2); + if (clampType == 3) { + return pq * LinearColorSign; + } + return pq; +} + +float3 PQ_to_Linear(float3 ST2084Color, int clampType = 0) { + float3 ST2084ColorSign = sign(ST2084Color); + if (clampType == 1) { + ST2084Color = max(ST2084Color, 0.f); + } else if (clampType == 2) { + ST2084Color = saturate(ST2084Color); + } else if (clampType == 3) { + ST2084Color = abs(ST2084Color); + } + float3 colorPow = pow(ST2084Color, 1.f / PQ_constant_M2); + float3 numerator = max(colorPow - PQ_constant_C1, 0.f); + float3 denominator = PQ_constant_C2 - (PQ_constant_C3 * colorPow); + float3 linearColor = pow(numerator / denominator, 1.f / PQ_constant_M1); + if (clampType == 3) { + return linearColor * ST2084ColorSign; + } + return linearColor; +} + +// Applies exponential ("Photographic") luminance/luma compression. +// The pow can modulate the curve without changing the values around the edges. +// The max is the max possible range to compress from, to not lose any output +// range if the input range was limited. +float rangeCompress(float X, float Max = asfloat(0x7F7FFFFF)) { + // Branches are for static parameters optimizations + if (Max == FLT_MAX) { + // This does e^X. We expect X to be between 0 and 1. + return 1.f - exp(-X); + } + const float lostRange = exp(-Max); + const float restoreRangeScale = 1.f / (1.f - lostRange); + return (1.f - exp(-X)) * restoreRangeScale; +} + +// Refurbished DICE HDR tonemapper (per channel or luminance). +// Expects "InValue" to be >= "ShoulderStart" and "OutMaxValue" to be > +// "ShoulderStart". +float luminanceCompress(float InValue, float OutMaxValue, + float ShoulderStart = 0.f, + bool ConsiderMaxValue = false, + float InMaxValue = asfloat(0x7F7FFFFF)) { + const float compressableValue = InValue - ShoulderStart; + const float compressableRange = InMaxValue - ShoulderStart; + const float compressedRange = OutMaxValue - ShoulderStart; + const float possibleOutValue = + ShoulderStart + compressedRange * rangeCompress(compressableValue / compressedRange, ConsiderMaxValue ? (compressableRange / compressedRange) : FLT_MAX); +#if 1 + return possibleOutValue; +#else // Enable this branch if "InValue" can be smaller than "ShoulderStart" + return (InValue <= ShoulderStart) ? InValue : possibleOutValue; +#endif +} + +#define DICE_TYPE_BY_LUMINANCE_RGB 0 +// Doing the DICE compression in PQ (either on luminance or each color channel) +// produces a curve that is closer to our "perception" and leaves more detail +// highlights without overly compressing them +#define DICE_TYPE_BY_LUMINANCE_PQ 1 +// Modern HDR displays clip individual rgb channels beyond their "white" peak +// brightness, like, if the peak brightness is 700 nits, any r g b color beyond +// a value of 700/80 will be clipped (not acknowledged, it won't make a +// difference). Tonemapping by luminance, is generally more perception accurate +// but can then generate rgb colors "out of range". This setting fixes them up, +// though it's optional as it's working based on assumptions on how current +// displays work, which might not be true anymore in the future. Note that this +// can create some steep (rough, quickly changing) gradients on very bright +// colors. +#define DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE 2 +// This might look more like classic SDR tonemappers and is closer to how modern +// TVs and Monitors play back colors (usually they clip each individual channel +// to the peak brightness value, though in their native panel color space, or +// current SDR/HDR mode color space). Overall, this seems to handle bright +// gradients more smoothly, even if it shifts hues more (and generally +// desaturating). +#define DICE_TYPE_BY_CHANNEL_PQ 3 + +struct DICESettings { + uint Type; + // Determines where the highlights curve (shoulder) starts. + // Values between 0.25 and 0.5 are good with DICE by PQ (any type). + // With linear/rgb DICE this barely makes a difference, zero is a good default + // but (e.g.) 0.5 would also work. This should always be between 0 and 1. + float ShoulderStart; + + // For "Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE" + // only: The sum of these needs to be <= 1, both within 0 and 1. The closer + // the sum is to 1, the more each color channel will be containted within its + // peak range. + float DesaturationAmount; + float DarkeningAmount; +}; + +DICESettings DefaultDICESettings() { + DICESettings Settings; + Settings.Type = DICE_TYPE_BY_CHANNEL_PQ; + Settings.ShoulderStart = + (Settings.Type > DICE_TYPE_BY_LUMINANCE_RGB) + ? (1.f / 3.f) + : 0.f; // TODOFT3: increase value!!! (did I already?) + Settings.DesaturationAmount = 1.0 / 3.0; + Settings.DarkeningAmount = 1.0 / 3.0; + return Settings; +} + +// Tonemapper inspired from DICE. Can work by luminance to maintain hue. +// Takes scRGB colors with a white level (the value of 1 1 1) of 80 nits (sRGB) +// (to not be confused with paper white). Paper white is expected to have +// already been multiplied in. +float3 DICETonemap(float3 Color, float PeakWhite, + const DICESettings Settings /*= DefaultDICESettings()*/) { + const float sourceLuminance = renodx::color::y::from::BT709(Color); + + if (Settings.Type != DICE_TYPE_BY_LUMINANCE_RGB) { + static const float HDR10_MaxWhite = + HDR10_MaxWhiteNits / renodx::color::srgb::REFERENCE_WHITE; + + // We could first convert the peak white to PQ and then apply the "shoulder + // start" alpha to it (in PQ), but tests showed scaling it in linear + // actually produces a better curve and more consistently follows the peak + // across different values + const float shoulderStartPQ = + Linear_to_PQ((Settings.ShoulderStart * PeakWhite) / HDR10_MaxWhite).x; + if (Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ || Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE) { + const float sourceLuminanceNormalized = sourceLuminance / HDR10_MaxWhite; + const float sourceLuminancePQ = + Linear_to_PQ(sourceLuminanceNormalized, 1).x; + + if (sourceLuminancePQ > shoulderStartPQ) // Luminance below the shoulder (or below zero) don't + // need to be adjusted + { + const float peakWhitePQ = Linear_to_PQ(PeakWhite / HDR10_MaxWhite).x; + + const float compressedLuminancePQ = + luminanceCompress(sourceLuminancePQ, peakWhitePQ, shoulderStartPQ); + const float compressedLuminanceNormalized = + PQ_to_Linear(compressedLuminancePQ).x; + Color *= compressedLuminanceNormalized / sourceLuminanceNormalized; + + if (Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE) { + float3 Color_BT2020 = renodx::color::bt2020::from::BT709(Color); + if (any(Color_BT2020 > PeakWhite)) // Optional "optimization" branch + { + float colorLuminance = renodx::color::y::from::BT2020(Color_BT2020); + float colorLuminanceInExcess = colorLuminance - PeakWhite; + float maxColorInExcess = + max3(Color_BT2020) - PeakWhite; // This is guaranteed to be >= + // "colorLuminanceInExcess" + float brightnessReduction = saturate(renodx::math::SafeDivision( + PeakWhite, max3(Color_BT2020), + 1)); // Fall back to one in case of division by zero + float desaturateAlpha = saturate(renodx::math::SafeDivision( + maxColorInExcess, maxColorInExcess - colorLuminanceInExcess, + 0)); // Fall back to zero in case of division by zero + Color_BT2020 = lerp(Color_BT2020, colorLuminance, + desaturateAlpha * Settings.DesaturationAmount); + Color_BT2020 = + lerp(Color_BT2020, Color_BT2020 * brightnessReduction, + Settings.DarkeningAmount); // Also reduce the brightness to + // partially maintain the hue, + // at the cost of brightness + Color = renodx::color::bt709::from::BT2020(Color_BT2020); + } + } + } + } else // DICE_TYPE_BY_CHANNEL_PQ + { + const float peakWhitePQ = Linear_to_PQ(PeakWhite / HDR10_MaxWhite).x; + + // Tonemap in BT.2020 to more closely match the primaries of modern + // displays + const float3 sourceColorNormalized = + renodx::color::bt2020::from::BT709(Color) / HDR10_MaxWhite; + const float3 sourceColorPQ = Linear_to_PQ(sourceColorNormalized, 1); + + [unroll] + for (uint i = 0; i < 3; + i++) // TODO LUMA: optimize? will the shader compile already convert + // this to float3? Or should we already make a version with no + // branches that works in float3? + { + if (sourceColorPQ[i] > shoulderStartPQ) // Colors below the shoulder (or below zero) don't + // need to be adjusted + { + const float compressedColorPQ = + luminanceCompress(sourceColorPQ[i], peakWhitePQ, shoulderStartPQ); + const float compressedColorNormalized = + PQ_to_Linear(compressedColorPQ).x; + Color[i] = renodx::color::bt709::from::BT2020( + Color[i] * (compressedColorNormalized / sourceColorNormalized[i])) + .x; + } + } + } + } else // DICE_TYPE_BY_LUMINANCE_RGB + { + const float shoulderStart = + PeakWhite * Settings.ShoulderStart; // From alpha to linear range + if (sourceLuminance > shoulderStart) // Luminances below the shoulder (or below zero) don't + // need to be adjusted + { + const float compressedLuminance = + luminanceCompress(sourceLuminance, PeakWhite, shoulderStart); + Color *= compressedLuminance / sourceLuminance; + } + } + + return Color; +} diff --git a/src/games/tacticalbreachwizards/LUT3DBakerNoTonemap_0x995B320A.cs_5_0.hlsl b/src/games/tacticalbreachwizards/LUT3DBakerNoTonemap_0x995B320A.cs_5_0.hlsl new file mode 100644 index 00000000..5d22f31f --- /dev/null +++ b/src/games/tacticalbreachwizards/LUT3DBakerNoTonemap_0x995B320A.cs_5_0.hlsl @@ -0,0 +1,139 @@ +#include "./common.hlsl" + +// https://github.com/Unity-Technologies/Graphics/blob/e42df452b62857a60944aed34f02efa1bda50018/com.unity.postprocessing/PostProcessing/Shaders/Builtins/Lut3DBaker.compute +// KGenLUT3D_NoTonemap + +Texture2D t0 : register(t0); + +SamplerState s0_s : register(s0); + +RWTexture3D u0 : register(u0); + +cbuffer cb0 : register(b0) { + float4 cb0[10]; +} + +#define cmp - + +[numthreads(4, 4, 4)] +void main(uint3 vThreadID: SV_DispatchThreadID) { + float4 r0, r1, r2, r3; + uint4 bitmask, uiDest; + float4 fDest; + + r0.rgb = (uint3)vThreadID.rgb; + r1.rgb = cmp(r0.rgb < cb0[0].rrr); + r0.a = r1.g ? r1.r : 0; + r0.a = r1.b ? r0.a : 0; + if (r0.a != 0) { + // (start) ColorGrade + // (start) LogGrade + // Contrast(r0.rgb, ACEScc_MIDGRAY, cb0[3].b) + r0.rgb = r0.rgb * cb0[0].ggg; + + float3 preContrast = r0.rgb; + + r0.rgb = r0.rgb + float3(-0.413588405, -0.413588405, -0.413588405); // ACEScc_MIDGRAY = 0.4135884 + r0.rgb = r0.rgb * cb0[3].bbb + float3(0.413588405, 0.413588405, 0.413588405); + + r0.rgb = lerp(preContrast, r0.rgb, injectedData.colorGradeLUTStrength); + + r0.rgb = lutShaper(r0.rgb, true); + + float3 preCG = r0.rgb; + + // (start) LinearGrade + // WhiteBalance(r0.rgb, cb0[1].rgb) + r1.r = dot(float3(0.390405, 0.549941, 0.00892631989), r0.rgb); + r1.g = dot(float3(0.0708416030, 0.963172, 0.00135775004), r0.rgb); + r1.b = dot(float3(0.0231081992, 0.128021, 0.936245), r0.rgb); + r0.rgb = r1.rgb * cb0[1].rgb; + r1.r = dot(float3(2.858470, -1.628790, -0.024891), r0.rgb); + r1.g = dot(float3(-0.210182, 1.158200, 0.000324280991), r0.rgb); + r1.b = dot(float3(-0.041812, -0.118169, 1.068670), r0.rgb); + // ColorFilter + r0.rgb = r1.rgb * cb0[2].rgb; + // ChannelMixer(r0.rgb, cb0[4].rgb, cb0[5].rgb, cb0[6].rgb) + r1.r = dot(r0.rgb, cb0[4].rgb); + r1.g = dot(r0.rgb, cb0[5].rgb); + r1.b = dot(r0.rgb, cb0[6].rgb); + // LiftGammaGainHDR(r1.rgb, cb0[7].rgb, cb0[8].rgb, cb0[9].rgb) + r0.rgb = r1.rgb * cb0[9].rgb + cb0[7].rgb; + r1.rgb = saturate(r1.rgb * renodx::math::FLT_MAX + 0.5) * 2.0 - 1.0; + r0.rgb = pow(abs(r0.rgb), cb0[8].rgb); + r0.rgb = r0.rgb * r1.rgb; + // Do NOT feed negative values to RgbToHsv or they'll wrap around + r0.rgb = max(0, r0.rgb); + // RgbToHsv + r0.a = cmp(r0.g >= r0.b); + r0.a = r0.a ? 1.00000 : 0; + r1.rg = r0.bg; + r1.ba = float2(-1, 0.666666687); + r2.rg = r0.gb + -r1.rg; + r2.ba = float2(1, -1); + r1.rgba = r0.aaaa * r2.rgba + r1.rgba; + r0.a = cmp(r0.r >= r1.r); + r0.a = r0.a ? 1.00000 : 0; + r2.rgb = r1.rga; + r2.a = r0.r; + r1.rga = r2.agr; + r1.rgba = -r2.rgba + r1.rgba; + r1.rgba = r0.aaaa * r1.rgba + r2.rgba; + r0.a = min(r1.g, r1.a); + r0.a = -r0.a + r1.r; + r1.g = -r1.g + r1.a; + r1.a = r0.a * 6 + 0.0001; + r1.g = r1.g / r1.a; + r1.g = r1.g + r1.b; + r2.r = abs(r1.g); + r1.g = r1.r + 0.0001; + r2.b = r0.a / r1.g; + // Hue Vs Sat + r2.ga = float2(0.25, 0.25); + r0.a = t0.SampleLevel(s0_s, r2.rg, 0).g; + r0.a = saturate(r0.a); + r0.a = r0.a + r0.a; + // Sat Vs Sat + r1.g = t0.SampleLevel(s0_s, r2.ba, 0).b; + r1.g = saturate(r1.g); + r0.a = dot(r1.gg, r0.aa); + // Lum Vs Sat + r3.r = dot(r0.rgb, float3(0.212672904, 0.715152204, 0.072175)); + r3.ga = float2(0.25, 0.25); + r0.r = t0.SampleLevel(s0_s, r3.rg, 0).a; + r0.r = saturate(r0.r); + r0.r = r0.a * r0.r; + // Hue Vs Hue + r3.b = r2.r + cb0[3].r; + r0.g = t0.SampleLevel(s0_s, r3.ba, 0).r; + r0.g = saturate(r0.g); + r0.g = r3.b + r0.g; + r0.gba = r0.ggg + float3(-0.5, 0.5, -1.5); + r1.g = cmp(r0.g < 0); + r1.b = cmp(1 < r0.g); + r0.g = r1.b ? r0.a : r0.g; + r0.g = r1.g ? r0.b : r0.g; + // HsvToRgb(r0.gba) + r0.gba = r0.ggg + float3(1, 0.666666687, 0.333333343); + r0.gba = frac(r0.gba); + r0.gba = r0.gba * float3(6, 6, 6) + float3(-3, -3, -3); + r0.gba = saturate(abs(r0.gba) + float3(-1, -1, -1)); + r0.gba = r0.gba + float3(-1, -1, -1); + r0.gba = r2.bbb * r0.gba + float3(1, 1, 1); + + // Saturation(r0.gba, cb0[3].g * r0.r) + r1.gba = r0.gba * r1.rrr; + r0.r = dot(cb0[3].gg, r0.rr); + r1.g = dot(r1.gba, float3(0.212672904, 0.715152204, 0.072175)); + r0.gba = r1.rrr * r0.gba + -r1.ggg; + r0.rgb = r0.rrr * r0.gba + r1.ggg; + + r0.rgb = lerp(preCG, r0.rgb, injectedData.colorGradeLUTStrength); + + r0.rgb = applyUserTonemap(r0.rgb); + + r0.a = 1; + u0[vThreadID.xyz] = r0.rgba; + } + return; +} diff --git a/src/games/tacticalbreachwizards/addon.cpp b/src/games/tacticalbreachwizards/addon.cpp new file mode 100644 index 00000000..bbdb7d4a --- /dev/null +++ b/src/games/tacticalbreachwizards/addon.cpp @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2023 Carlos Lopez + * SPDX-License-Identifier: MIT + */ + +#define ImTextureID ImU64 + +#define DEBUG_LEVEL_0 + +#include + +#include +#include + +#include "../../mods/shader.hpp" +#include "../../mods/swapchain.hpp" +#include "../../utils/date.hpp" +#include "../../utils/settings.hpp" +#include "./shared.h" + +namespace { + +renodx::mods::shader::CustomShaders custom_shaders = { + CustomShaderEntry(0xC8C2F1A0), + CustomShaderEntry(0x995B320A), + CustomShaderEntry(0xD863ED6A), +}; + +ShaderInjectData shader_injection; +const std::string build_date = __DATE__; +const std::string build_time = __TIME__; + +renodx::utils::settings::Settings settings = { + new renodx::utils::settings::Setting{ + .key = "toneMapType", + .binding = &shader_injection.toneMapType, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 3.f, + .can_reset = true, + .label = "Tone Mapper", + .section = "Tone Mapping", + .tooltip = "Sets the tone mapper type", + .labels = {"Vanilla", "None", "ACES", "RenoDRT", "Reinhard+"}, + .tint = 0x3FD9B9, + }, + new renodx::utils::settings::Setting{ + .key = "toneMapPeakNits", + .binding = &shader_injection.toneMapPeakNits, + .default_value = 1000.f, + .can_reset = false, + .label = "Peak Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the value of peak white in nits", + .tint = 0x927A13, + .min = 48.f, + .max = 4000.f, + }, + new renodx::utils::settings::Setting{ + .key = "toneMapGameNits", + .binding = &shader_injection.toneMapGameNits, + .default_value = 203.f, + .label = "Game Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the value of 100% white in nits", + .tint = 0x927A13, + .min = 48.f, + .max = 500.f, + }, + new renodx::utils::settings::Setting{ + .key = "toneMapUINits", + .binding = &shader_injection.toneMapUINits, + .default_value = 203.f, + .label = "UI Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the brightness of UI and HUD elements in nits", + .tint = 0x927A13, + .min = 48.f, + .max = 500.f, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeExposure", + .binding = &shader_injection.colorGradeExposure, + .default_value = 1.f, + .label = "Exposure", + .section = "Color Grading", + .tint = 0x610512, + .max = 10.f, + .format = "%.2f", + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeHighlights", + .binding = &shader_injection.colorGradeHighlights, + .default_value = 50.f, + .label = "Highlights", + .section = "Color Grading", + .tint = 0x610512, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeShadows", + .binding = &shader_injection.colorGradeShadows, + .default_value = 50.f, + .label = "Shadows", + .section = "Color Grading", + .tint = 0x610512, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeContrast", + .binding = &shader_injection.colorGradeContrast, + .default_value = 50.f, + .label = "Contrast", + .section = "Color Grading", + .tint = 0x610512, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeSaturation", + .binding = &shader_injection.colorGradeSaturation, + .default_value = 50.f, + .label = "Saturation", + .section = "Color Grading", + .tint = 0x610512, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeBlowout", + .binding = &shader_injection.colorGradeBlowout, + .default_value = 50.f, + .label = "Blowout", + .section = "Color Grading", + .tooltip = "Controls highlight desaturation due to overexposure.", + .tint = 0x610512, + .max = 100.f, + .is_enabled = []() { return shader_injection.toneMapType >= 3.f; }, + .parse = [](float value) { return (value * 0.02f) - 1.f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeFlare", + .binding = &shader_injection.colorGradeFlare, + .default_value = 0.f, + .label = "Flare", + .section = "Color Grading", + .tooltip = "Embrace the darkness... (Gently.)", + .tint = 0x896895, + .max = 100.f, + .is_enabled = []() { return shader_injection.toneMapType == 3.f; }, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "colorGradeLUTStrength", + .binding = &shader_injection.colorGradeLUTStrength, + .default_value = 100.f, + .label = "LUT Strength", + .section = "Color Grading", + .tint = 0x610512, + .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", + .tint = 0xEC4E1B, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "fxVignette", + .binding = &shader_injection.fxVignette, + .default_value = 50.f, + .label = "Vignette", + .section = "Effects", + .tint = 0xEC4E1B, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "fxFilmGrain", + .binding = &shader_injection.fxFilmGrain, + .default_value = 0.f, + .label = "Film Grain", + .section = "Effects", + .tint = 0xEC4E1B, + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::TEXT, + .label = "RenoDX by ShortFuse, game mod by Ritsu. Shout-out to HDR Den & Not Voosh for (lending) their code!", + .section = "About", + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "HDR Den Discord", + .section = "About", + .group = "button-line-1", + .tint = 0x5865F2, + .on_change = []() { + static const std::string obfuscated_link = std::string("start https://discord.gg/XUhv") + std::string("tR54yc"); + system(obfuscated_link.c_str()); + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "Github", + .section = "About", + .group = "button-line-1", + .on_change = []() { + ShellExecute(0, "open", "https://github.com/clshortfuse/renodx", 0, 0, SW_SHOW); + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "ShortFuse's Ko-Fi", + .section = "About", + .group = "button-line-1", + .tint = 0xFF5F5F, + .on_change = []() { + ShellExecute(0, "open", "https://ko-fi.com/shortfuse", 0, 0, SW_SHOW); + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "HDR Den's Ko-Fi", + .section = "About", + .group = "button-line-1", + .tint = 0xFF5F5F, + .on_change = []() { + ShellExecute(0, "open", "https://ko-fi.com/hdrden", 0, 0, SW_SHOW); + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::TEXT, + .label = "This build was compiled on " + build_date + " at " + build_time + ".", + .section = "About", + }, +}; + +void OnPresetOff() { + renodx::utils::settings::UpdateSetting("toneMapType", 0.f); + renodx::utils::settings::UpdateSetting("toneMapPeakNits", 203.f); + renodx::utils::settings::UpdateSetting("toneMapGameNits", 203.f); + renodx::utils::settings::UpdateSetting("toneMapUINits", 203.f); + renodx::utils::settings::UpdateSetting("colorGradeExposure", 1.f); + renodx::utils::settings::UpdateSetting("colorGradeHighlights", 50.f); + renodx::utils::settings::UpdateSetting("colorGradeShadows", 50.f); + renodx::utils::settings::UpdateSetting("colorGradeContrast", 50.f); + renodx::utils::settings::UpdateSetting("colorGradeSaturation", 50.f); + renodx::utils::settings::UpdateSetting("colorGradeBlowout", 0.f); + renodx::utils::settings::UpdateSetting("colorGradeLUTStrength", 100.f); + renodx::utils::settings::UpdateSetting("fxVignette", 50.f); +} + +bool fired_on_init_swapchain = false; + +void OnInitSwapchain(reshade::api::swapchain* swapchain) { + if (fired_on_init_swapchain) return; + fired_on_init_swapchain = true; + auto peak = renodx::utils::swapchain::GetPeakNits(swapchain); + if (peak.has_value()) { + settings[1]->default_value = peak.value(); + settings[1]->can_reset = true; + } +} + +auto start = std::chrono::steady_clock::now(); + +void OnPresent( + reshade::api::command_queue* queue, + reshade::api::swapchain* swapchain, + const reshade::api::rect* source_rect, + const reshade::api::rect* dest_rect, + uint32_t dirty_rect_count, + const reshade::api::rect* dirty_rects) { + auto end = std::chrono::steady_clock::now(); + shader_injection.elapsedTime = std::chrono::duration_cast(end - start).count(); +} + +} // namespace + +// NOLINTBEGIN(readability-identifier-naming) + +extern "C" __declspec(dllexport) constexpr const char* NAME = "RenoDX"; +extern "C" __declspec(dllexport) constexpr const char* DESCRIPTION = "RenoDX for Tactical Breach Wizards"; + +// NOLINTEND(readability-identifier-naming) + +BOOL APIENTRY DllMain(HMODULE h_module, DWORD fdw_reason, LPVOID lpv_reserved) { + switch (fdw_reason) { + case DLL_PROCESS_ATTACH: + if (!reshade::register_addon(h_module)) return FALSE; + renodx::mods::shader::force_pipeline_cloning = true; + renodx::mods::swapchain::force_borderless = false; + renodx::mods::swapchain::prevent_full_screen = false; + renodx::mods::shader::allow_multiple_push_constants = true; + renodx::mods::swapchain::use_resource_cloning = true; + renodx::mods::swapchain::swap_chain_proxy_vertex_shader = __swap_chain_proxy_vertex_shader; + renodx::mods::swapchain::swap_chain_proxy_pixel_shader = __swap_chain_proxy_pixel_shader; + + // RG11B10_float (UAV stuff) + renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({.old_format = reshade::api::format::r11g11b10_float, + .new_format = reshade::api::format::r16g16b16a16_float, + .ignore_size = true, + .view_upgrades = { + {{reshade::api::resource_usage::shader_resource, + reshade::api::format::r11g11b10_float}, + reshade::api::format::r16g16b16a16_float}, + {{reshade::api::resource_usage::unordered_access, + reshade::api::format::r11g11b10_float}, + reshade::api::format::r16g16b16a16_float}, + {{reshade::api::resource_usage::render_target, + reshade::api::format::r11g11b10_float}, + reshade::api::format::r16g16b16a16_float}, + }}); + + // RGBA8_typeless + renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({ + .old_format = reshade::api::format::r8g8b8a8_typeless, + .new_format = reshade::api::format::r16g16b16a16_typeless, + .ignore_size = true, + }); + + /* renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({ + .old_format = reshade::api::format::r8g8b8a8_typeless, + .new_format = reshade::api::format::r16g16b16a16_float, + .index = 0, + .aspect_ratio = 16.f / 9.f, + }); + renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({ + .old_format = reshade::api::format::r11g11b10_float, + .new_format = reshade::api::format::r16g16b16a16_float, + .dimensions = {.width = 640, .height = 360}, + }); */ + + reshade::register_event(OnInitSwapchain); + reshade::register_event(OnPresent); + + break; + case DLL_PROCESS_DETACH: + reshade::unregister_addon(h_module); + reshade::unregister_event(OnInitSwapchain); + break; + } + + renodx::utils::settings::Use(fdw_reason, &settings, &OnPresetOff); + + renodx::mods::swapchain::Use(fdw_reason, &shader_injection); + + renodx::mods::shader::Use(fdw_reason, custom_shaders, &shader_injection); + + return TRUE; +} \ No newline at end of file diff --git a/src/games/tacticalbreachwizards/common.hlsl b/src/games/tacticalbreachwizards/common.hlsl new file mode 100644 index 00000000..f99527e3 --- /dev/null +++ b/src/games/tacticalbreachwizards/common.hlsl @@ -0,0 +1,162 @@ +#include "./DICE.hlsl" +#include "./shared.h" + +//-----EFFECTS-----// +float3 applyFilmGrain(float3 outputColor, float2 screen) { + float3 grainedColor = renodx::effects::ApplyFilmGrain( + outputColor, + screen, + frac(injectedData.elapsedTime / 1000.f), + injectedData.fxFilmGrain * 0.03f, + 1.f); + return grainedColor; +} + +float UpgradeToneMapRatio(float ap1_color_hdr, float ap1_color_sdr, float ap1_post_process_color) { + if (ap1_color_hdr < ap1_color_sdr) { + // If substracting (user contrast or paperwhite) scale down instead + // Should only apply on mismatched HDR + return ap1_color_hdr / ap1_color_sdr; + } else { + float ap1_delta = ap1_color_hdr - ap1_color_sdr; + ap1_delta = max(0, ap1_delta); // Cleans up NaN + const float ap1_new = ap1_post_process_color + ap1_delta; + + const bool ap1_valid = (ap1_post_process_color > 0); // Cleans up NaN and ignore black + return ap1_valid ? (ap1_new / ap1_post_process_color) : 0; + } +} +float3 UpgradeToneMapPerChannel(float3 color_hdr, float3 color_sdr, float3 post_process_color, float post_process_strength) { + // float ratio = 1.f; + + float3 bt2020_hdr = max(0, renodx::color::bt2020::from::BT709(color_hdr)); + float3 bt2020_sdr = max(0, renodx::color::bt2020::from::BT709(color_sdr)); + float3 bt2020_post_process = max(0, renodx::color::bt2020::from::BT709(post_process_color)); + + float3 ratio = float3( + UpgradeToneMapRatio(bt2020_hdr.r, bt2020_sdr.r, bt2020_post_process.r), + UpgradeToneMapRatio(bt2020_hdr.g, bt2020_sdr.g, bt2020_post_process.g), + UpgradeToneMapRatio(bt2020_hdr.b, bt2020_sdr.b, bt2020_post_process.b)); + + float3 color_scaled = max(0, bt2020_post_process * ratio); + color_scaled = renodx::color::bt709::from::BT2020(color_scaled); + float peak_correction = saturate(1.f - renodx::color::y::from::BT2020(bt2020_post_process)); + color_scaled = renodx::color::correct::Hue(color_scaled, post_process_color, peak_correction); + return lerp(color_hdr, color_scaled, post_process_strength); +} + +//-----SCALING-----// +float3 PostToneMapScale(float3 color) { + color = renodx::color::srgb::EncodeSafe(color); + color = renodx::color::gamma::DecodeSafe(color); + color *= injectedData.toneMapGameNits / injectedData.toneMapUINits; + color = renodx::color::gamma::EncodeSafe(color); + return color; +} + +float3 FinalizeOutput(float3 color) { + color = renodx::color::gamma::DecodeSafe(color); + color *= injectedData.toneMapUINits; + color = min(color, injectedData.toneMapPeakNits); // Clamp UI or Videos + + color = renodx::color::bt709::clamp::BT2020(color); + color = color / 80.f; + + return color; +} + +float3 lutShaper(float3 color, bool builder = false) { + color = builder ? renodx::color::pq::Decode(color, 100.f) + : renodx::color::pq::Encode(color, 100.f); + + return color; +} + +float3 UIScale(float3 color) { + color = renodx::color::correct::GammaSafe(color); + color *= injectedData.toneMapUINits / 80.f; + color = renodx::color::correct::GammaSafe(color, true); + + return color; +} + +//-----TONEMAP-----// +float3 applyReinhardPlus(float3 color, renodx::tonemap::Config RhConfig) { + float RhPeak = RhConfig.peak_nits / RhConfig.game_nits; + if (RhConfig.gamma_correction == 1.f) { + RhPeak = renodx::color::correct::Gamma(RhPeak, true); + } + + color = renodx::color::ap1::from::BT709(color); + float y = renodx::color::y::from::AP1(color * RhConfig.exposure); + color = renodx::color::grade::UserColorGrading(color, RhConfig.exposure, RhConfig.highlights, RhConfig.shadows, RhConfig.contrast); + color = renodx::tonemap::ReinhardScalable(color, RhPeak, 0.f, 0.18f, RhConfig.mid_gray_value); + color = renodx::color::bt709::from::AP1(color); + if (RhConfig.reno_drt_blowout != 0.f || RhConfig.saturation != 1.f) { + float3 perceptual_new; + + if (RhConfig.reno_drt_hue_correction_method == 0u) { + perceptual_new = renodx::color::oklab::from::BT709(color); + } else if (RhConfig.reno_drt_hue_correction_method == 1u) { + perceptual_new = renodx::color::ictcp::from::BT709(color); + } else if (RhConfig.reno_drt_hue_correction_method == 2u) { + perceptual_new = renodx::color::dtucs::uvY::from::BT709(color).zxy; + } + + if (RhConfig.reno_drt_blowout != 0.f) { + perceptual_new.yz *= lerp(1.f, 0.f, saturate(pow(y / (10000.f / 100.f), (1.f - RhConfig.reno_drt_blowout)))); + } + + perceptual_new.yz *= RhConfig.saturation; + + if (RhConfig.reno_drt_hue_correction_method == 0u) { + color = renodx::color::bt709::from::OkLab(perceptual_new); + } else if (RhConfig.reno_drt_hue_correction_method == 1u) { + color = renodx::color::bt709::from::ICtCp(perceptual_new); + } else if (RhConfig.reno_drt_hue_correction_method == 2u) { + color = renodx::color::bt709::from::dtucs::uvY(perceptual_new.yzx); + } + } + color = renodx::color::bt709::clamp::AP1(color); + return color; +} + +float3 applyUserTonemap(float3 untonemapped) { + float3 outputColor = untonemapped; + float midGray = renodx::color::y::from::BT709(renodx::tonemap::unity::BT709(float3(0.18f, 0.18f, 0.18f))); + float3 hueCorrectionColor = renodx::tonemap::unity::BT709(outputColor); + 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 = 1.f; + config.exposure = injectedData.colorGradeExposure; + config.highlights = injectedData.colorGradeHighlights; + config.shadows = injectedData.colorGradeShadows; + config.contrast = injectedData.colorGradeContrast; + config.saturation = injectedData.colorGradeSaturation; + config.mid_gray_value = midGray; + config.mid_gray_nits = midGray * 100; + config.reno_drt_blowout = injectedData.colorGradeBlowout; + config.reno_drt_flare = 0.010 * injectedData.colorGradeFlare; + config.reno_drt_tone_map_method = renodx::tonemap::renodrt::config::tone_map_method::DANIELE; + + if (injectedData.toneMapType >= 3.f) { + outputColor = renodx::color::correct::Hue(outputColor, hueCorrectionColor, 1.f); + } + if (injectedData.toneMapType == 2.f) { // ACES + config.contrast *= 0.75f; + config.saturation *= 0.8f; + } + if (injectedData.toneMapType == 4.f) { + // Reinhard+ + // We trust in Voosh defaults + config.saturation *= 1.1f; + outputColor = applyReinhardPlus(outputColor, config); + } else { + outputColor = renodx::tonemap::config::Apply(outputColor, config); + } + + return outputColor; +} diff --git a/src/games/tacticalbreachwizards/glow_composite_0xD863ED6A.ps_4_0.hlsl b/src/games/tacticalbreachwizards/glow_composite_0xD863ED6A.ps_4_0.hlsl new file mode 100644 index 00000000..805d9c78 --- /dev/null +++ b/src/games/tacticalbreachwizards/glow_composite_0xD863ED6A.ps_4_0.hlsl @@ -0,0 +1,40 @@ +#include "./common.hlsl" + +// ---- Created with 3Dmigoto v1.3.16 on Fri Jan 3 12:33:59 2025 +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb0 : register(b0) { + float4 cb0[7]; +} + +// 3Dmigoto declarations +#define cmp - + +void main( + float4 v0: SV_POSITION0, + float2 v1: TEXCOORD0, + float2 w1: TEXCOORD1, + out float4 o0: SV_TARGET0) { + float4 r0, r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = w1.xy * cb0[5].xy + cb0[5].zw; + r0.xyzw = t1.Sample(s1_s, r0.xy).xyzw; + r0.xyz = cb0[6].xxx * r0.xyz * injectedData.fxBloom; + r1.xy = v1.xy * cb0[3].xy + cb0[3].zw; + r1.xyzw = t0.Sample(s0_s, r1.xy).xyzw; + o0.xyz = r0.xyz * cb0[6].yzw + r1.xyz; + if (injectedData.fxFilmGrain > 0.f) { + o0.rgb = applyFilmGrain(o0.rgb, w1); + } + o0.rgb = PostToneMapScale(o0.rgb); + o0.w = 1; + return; +} diff --git a/src/games/tacticalbreachwizards/output_0xC8C2F1A0.ps_4_0.hlsl b/src/games/tacticalbreachwizards/output_0xC8C2F1A0.ps_4_0.hlsl new file mode 100644 index 00000000..0fa02153 --- /dev/null +++ b/src/games/tacticalbreachwizards/output_0xC8C2F1A0.ps_4_0.hlsl @@ -0,0 +1,117 @@ +#include "./common.hlsl" + +// ---- Created with 3Dmigoto v1.3.16 on Thu Jan 2 22:18:43 2025 +Texture2D t3 : register(t3); + +Texture3D t2 : register(t2); + +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s3_s : register(s3); + +SamplerState s2_s : register(s2); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb0 : register(b0) { + float4 cb0[43]; +} + +// 3Dmigoto declarations +#define cmp - + +void main( + float4 v0: SV_POSITION0, + float2 v1: TEXCOORD0, + float2 w1: TEXCOORD1, + out float4 o0: SV_Target0) { + float4 r0, r1, r2, r3; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xyzw = t1.Sample(s1_s, v1.xy).xyzw; + r1.xyzw = t0.Sample(s0_s, w1.xy).xyzw; + r0.yzw = float3(0.0773993805, 0.0773993805, 0.0773993805) * r1.xyz; + r2.xyz = float3(0.0549999997, 0.0549999997, 0.0549999997) + r1.xyz; + r2.xyz = float3(0.947867334, 0.947867334, 0.947867334) * r2.xyz; + r2.xyz = max(float3(1.1920929e-07, 1.1920929e-07, 1.1920929e-07), abs(r2.xyz)); + r2.xyz = log2(r2.xyz); + r2.xyz = float3(2.4000001, 2.4000001, 2.4000001) * r2.xyz; + r2.xyz = exp2(r2.xyz); + r1.xyz = cmp(float3(0.0404499993, 0.0404499993, 0.0404499993) >= r1.xyz); + r0.yzw = r1.xyz ? r0.yzw : r2.xyz; + r0.xyz = r0.yzw * r0.xxx; + r0.w = cmp(cb0[40].y < 0.5); + if (r0.w != 0) { + r1.xy = -cb0[38].xy + v1.xy; + r1.yz = cb0[39].xx * abs(r1.yx) * min(1, injectedData.fxVignette); + r0.w = cb0[22].x / cb0[22].y; + r0.w = -1 + r0.w; + r0.w = cb0[39].w * r0.w + 1; + r1.x = r1.z * r0.w; + r1.xy = saturate(r1.xy); + r1.xy = log2(r1.xy); + r1.xy = cb0[39].zz * r1.xy; + r1.xy = exp2(r1.xy); + r0.w = dot(r1.xy, r1.xy); + r0.w = 1 + -r0.w; + r0.w = max(0, r0.w); + r0.w = log2(r0.w); + r0.w = cb0[39].y * r0.w * max(1, injectedData.fxVignette); + r0.w = exp2(r0.w); + r1.xyz = float3(1, 1, 1) + -cb0[37].xyz; + r1.xyz = r0.www * r1.xyz + cb0[37].xyz; + r2.xyz = r1.xyz * r0.xyz; + r1.x = -1 + r1.w; + r2.w = r0.w * r1.x + 1; + } else { + r3.xyzw = t3.Sample(s3_s, v1.xy).xyzw; + r1.xyz = float3(1, 1, 1) + -cb0[37].xyz; + r1.xyz = r3.www * r1.xyz + cb0[37].xyz; + r1.xyz = r0.xyz * r1.xyz + -r0.xyz; + r2.xyz = cb0[40].xxx * r1.xyz + r0.xyz; + r0.x = -1 + r1.w; + r2.w = r3.w * r0.x + 1; + } + r0.xyzw = cb0[36].zzzz * r2.xyzw; + + float3 lutInput = lutShaper(r0.rgb); + float3 lutColor = renodx::lut::Sample(t2, s2_s, lutInput); + o0.rgb = lutColor; + + if (false) { + r0.xyz = r0.xyz * float3(5.55555582, 5.55555582, 5.55555582) + float3(0.0479959995, 0.0479959995, 0.0479959995); + r0.xyz = log2(r0.xyz); + r0.xyz = saturate(r0.xyz * float3(0.0734997839, 0.0734997839, 0.0734997839) + float3(0.386036009, 0.386036009, 0.386036009)); + r0.xyz = cb0[36].yyy * r0.xyz; + r1.x = 0.5 * cb0[36].x; + r0.xyz = r0.xyz * cb0[36].xxx + r1.xxx; + r1.xyzw = t2.Sample(s2_s, r0.xyz).xyzw; + r0.x = cmp(0.5 < cb0[42].x); + if (r0.x != 0) { + r0.xyz = saturate(r1.xyz); + o0.w = dot(r0.xyz, float3(0.212672904, 0.715152204, 0.0721750036)); + } else { + o0.w = r0.w; + } + r0.xyz = float3(12.9200001, 12.9200001, 12.9200001) * r1.xyz; + r2.xyz = max(float3(1.1920929e-07, 1.1920929e-07, 1.1920929e-07), abs(r1.xyz)); + r2.xyz = log2(r2.xyz); + r2.xyz = float3(0.416666657, 0.416666657, 0.416666657) * r2.xyz; + r2.xyz = exp2(r2.xyz); + r2.xyz = r2.xyz * float3(1.05499995, 1.05499995, 1.05499995) + float3(-0.0549999997, -0.0549999997, -0.0549999997); + r1.xyz = cmp(float3(0.00313080009, 0.00313080009, 0.00313080009) >= r1.xyz); + o0.xyz = r1.xyz ? r0.xyz : r2.xyz; + } + + if (injectedData.toneMapType == 0.f) { + o0.rgb = saturate(o0.rgb); + } + o0.w = r0.w; + + return; +} diff --git a/src/games/tacticalbreachwizards/output_0xEB23B0ED.ps_5_0.hlsl b/src/games/tacticalbreachwizards/output_0xEB23B0ED.ps_5_0.hlsl new file mode 100644 index 00000000..9b247907 --- /dev/null +++ b/src/games/tacticalbreachwizards/output_0xEB23B0ED.ps_5_0.hlsl @@ -0,0 +1,39 @@ +// ---- Created with 3Dmigoto v1.3.16 on Fri Jan 3 12:27:45 2025 +Texture2D t1 : register(t1); + +Texture2D t0 : register(t0); + +SamplerState s1_s : register(s1); + +SamplerState s0_s : register(s0); + +cbuffer cb0 : register(b0) { + float4 cb0[29]; +} + +// 3Dmigoto declarations +#define cmp - + +void main( + float4 v0: SV_POSITION0, + float2 v1: TEXCOORD0, + float2 w1: TEXCOORD1, + out float4 o0: SV_Target0) { + float4 r0, r1; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xy = v1.xy * cb0[28].xy + cb0[28].zw; + r0.x = t0.Sample(s0_s, r0.xy).w; + r0.x = r0.x * 2 + -1; + r0.y = 1 + -abs(r0.x); + r0.x = saturate(r0.x * 3.40282347e+38 + 0.5); + r0.x = r0.x * 2 + -1; + r0.y = sqrt(r0.y); + r0.y = 1 + -r0.y; + r0.x = r0.x * r0.y; + r1.xyzw = t1.Sample(s1_s, w1.xy).xyzw; + o0.xyz = r0.xxx * float3(0.00392156886, 0.00392156886, 0.00392156886) + r1.xyz; + o0.w = r1.w; + return; +} diff --git a/src/games/tacticalbreachwizards/shared.h b/src/games/tacticalbreachwizards/shared.h new file mode 100644 index 00000000..ef632a39 --- /dev/null +++ b/src/games/tacticalbreachwizards/shared.h @@ -0,0 +1,35 @@ +#ifndef SRC_TACTICAL_BREACH_WIZARDS_SHARED_H_ +#define SRC_TACTICAL_BREACH_WIZARDS_SHARED_H_ + +#ifndef __cplusplus +#include "../../shaders/renodx.hlsl" +#endif + +// Must be 32bit aligned +// Should be 4x32 +struct ShaderInjectData { + float toneMapType; + float toneMapPeakNits; + float toneMapGameNits; + float toneMapUINits; + float colorGradeExposure; + float colorGradeHighlights; + float colorGradeShadows; + float colorGradeContrast; + float colorGradeSaturation; + float colorGradeBlowout; + float colorGradeFlare; + float colorGradeLUTStrength; + float fxBloom; + float fxVignette; + float fxFilmGrain; + float elapsedTime; +}; + +#ifndef __cplusplus +cbuffer cb13 : register(b13) { + ShaderInjectData injectedData : packoffset(c0); +} +#endif + +#endif // SRC_TACTICAL_BREACH_WIZARDS_SHARED_H_ \ No newline at end of file diff --git a/src/games/tacticalbreachwizards/swap_chain_proxy_pixel_shader.ps_4_0.hlsl b/src/games/tacticalbreachwizards/swap_chain_proxy_pixel_shader.ps_4_0.hlsl new file mode 100644 index 00000000..1743d2d2 --- /dev/null +++ b/src/games/tacticalbreachwizards/swap_chain_proxy_pixel_shader.ps_4_0.hlsl @@ -0,0 +1,12 @@ +#include "./common.hlsl" +#include "./shared.h" + +Texture2D t0 : register(t0); +SamplerState s0 : register(s0); +float4 main(float4 vpos: SV_POSITION, float2 uv: TEXCOORD0) + : SV_TARGET { + float4 color = t0.Sample(s0, uv); + color.rgb = FinalizeOutput(color.rgb); + color.a = 1.f; + return color; +} diff --git a/src/games/tacticalbreachwizards/swap_chain_proxy_vertex_shader.vs_4_0.hlsl b/src/games/tacticalbreachwizards/swap_chain_proxy_vertex_shader.vs_4_0.hlsl new file mode 100644 index 00000000..aaee1e17 --- /dev/null +++ b/src/games/tacticalbreachwizards/swap_chain_proxy_vertex_shader.vs_4_0.hlsl @@ -0,0 +1,6 @@ +void main(uint id : SV_VERTEXID, out float4 pos : SV_POSITION, + out float2 uv : TEXCOORD0) { + uv.x = (id == 1) ? 2.0 : 0.0; + uv.y = (id == 2) ? 2.0 : 0.0; + pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); +} \ No newline at end of file From 553994f8f1d62ede6372ac34aee3afe5989c51a5 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sat, 11 Jan 2025 15:08:42 -0500 Subject: [PATCH 08/12] feat(shaders): add color_convert --- src/shaders/color_convert.hlsl | 84 ++++++++++++++++++++++++++++++++++ src/shaders/renodx.hlsl | 1 + 2 files changed, 85 insertions(+) create mode 100644 src/shaders/color_convert.hlsl diff --git a/src/shaders/color_convert.hlsl b/src/shaders/color_convert.hlsl new file mode 100644 index 00000000..c758b78b --- /dev/null +++ b/src/shaders/color_convert.hlsl @@ -0,0 +1,84 @@ +#ifndef SRC_SHADERS_COLOR_CONVERT_HLSL_ +#define SRC_SHADERS_COLOR_CONVERT_HLSL_ + +#include "./color.hlsl" + +namespace renodx { +namespace color { +namespace convert { +static const float COLOR_SPACE_UNKNOWN = -1; +static const float COLOR_SPACE_NONE = -1; +static const float COLOR_SPACE_BT709 = 0; +static const float COLOR_SPACE_BT2020 = 1.f; +static const float COLOR_SPACE_AP1 = 2.f; + +float3 ColorSpaceFromBT709(float3 color, float color_space) { + [branch] + if (color_space == COLOR_SPACE_BT2020) { + color = renodx::color::bt2020::from::BT709(color); + } else { + [branch] + if (color_space == COLOR_SPACE_AP1) { + color = renodx::color::ap1::from::BT709(color); + } else { + color = color; + } + } + return color; +} + +float3 ColorSpaceFromBT2020(float3 color, float color_space) { + [branch] + if (color_space == COLOR_SPACE_BT709) { + color = renodx::color::bt709::from::BT2020(color); + } else { + [branch] + if (color_space == COLOR_SPACE_AP1) { + color = renodx::color::ap1::from::BT2020(color); + } else { + color = color; + } + } + return color; +} + +float3 ColorSpaceFromAP1(float3 color, float color_space) { + [branch] + if (color_space == COLOR_SPACE_BT709) { + color = renodx::color::bt709::from::AP1(color); + } else { + [branch] + if (color_space == COLOR_SPACE_BT2020) { + color = renodx::color::bt2020::from::AP1(color); + } else { + color = color; + } + } + return color; +} + +float3 ColorSpaces(float3 color, float input_color_space, float output_color_space) { + [branch] + if (input_color_space == COLOR_SPACE_BT709) { + color = ColorSpaceFromBT709(color, output_color_space); + } else { + [branch] + if (input_color_space == COLOR_SPACE_BT2020) { + color = ColorSpaceFromBT2020(color, output_color_space); + } else { + [branch] + if (input_color_space == COLOR_SPACE_AP1) { + color = ColorSpaceFromAP1(color, output_color_space); + } else { + color = color; + } + } + } + return color; +} + +} // namespace convert +} // namespace color +} // namespace renodx + +#endif // SRC_SHADERS_COLOR_CONVERT_HLSL_ diff --git a/src/shaders/renodx.hlsl b/src/shaders/renodx.hlsl index adb233c9..06de5c1f 100644 --- a/src/shaders/renodx.hlsl +++ b/src/shaders/renodx.hlsl @@ -5,6 +5,7 @@ #include "./aces.hlsl" #include "./color.hlsl" +#include "./color_convert.hlsl" #include "./colorcorrect.hlsl" #include "./colorgrade.hlsl" #include "./debug.hlsl" From c2e9c4dce9a98f0ba0f65ae2d4348ee7b6575fe4 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sat, 11 Jan 2025 15:09:25 -0500 Subject: [PATCH 09/12] feat(renodrt): add per_channel option for neutralsdr --- src/shaders/reno_drt.hlsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shaders/reno_drt.hlsl b/src/shaders/reno_drt.hlsl index e42153c0..dca4c590 100644 --- a/src/shaders/reno_drt.hlsl +++ b/src/shaders/reno_drt.hlsl @@ -364,7 +364,7 @@ float3 BT709( bt709); } -float3 NeutralSDR(float3 bt709) { +float3 NeutralSDR(float3 bt709, bool per_channel = false) { Config renodrt_config = config::Create(); renodrt_config.nits_peak = 100.f; renodrt_config.mid_gray_value = 0.18f; @@ -376,6 +376,7 @@ float3 NeutralSDR(float3 bt709) { renodrt_config.saturation = 1.f; renodrt_config.dechroma = 0.f; renodrt_config.flare = 0.f; + renodrt_config.per_channel = per_channel; renodrt_config.hue_correction_strength = 0.f; renodrt_config.working_color_space = 0u; renodrt_config.clamp_color_space = 0u; From 7a1d2fc0a6976a685598b4e47e02e1f79a7b06d4 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sat, 11 Jan 2025 15:10:04 -0500 Subject: [PATCH 10/12] feat(renodrt): add clamp_peak option --- src/shaders/reno_drt.hlsl | 90 +++++++++++++++++++++++++++++---------- src/shaders/tonemap.hlsl | 8 +++- 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/shaders/reno_drt.hlsl b/src/shaders/reno_drt.hlsl index dca4c590..4b3d0490 100644 --- a/src/shaders/reno_drt.hlsl +++ b/src/shaders/reno_drt.hlsl @@ -2,6 +2,7 @@ #define SRC_SHADERS_RENO_DRT_HLSL_ #include "./color.hlsl" +#include "./color_convert.hlsl" #include "./math.hlsl" namespace renodx { @@ -28,6 +29,7 @@ struct Config { bool per_channel; float blowout; float clamp_color_space; + float clamp_peak; }; namespace config { @@ -67,7 +69,8 @@ Config Create( uint working_color_space = 0u, bool per_channel = false, float blowout = 0, - float clamp_color_space = 2.f) { + float clamp_color_space = 2.f, + float clamp_peak = 0.f) { const Config renodrt_config = { nits_peak, mid_gray_value, @@ -87,7 +90,8 @@ Config Create( working_color_space, per_channel, blowout, - clamp_color_space + clamp_color_space, + clamp_peak }; return renodrt_config; } @@ -136,24 +140,44 @@ float3 BT709(float3 bt709, Config current_config) { float y = y_original * current_config.exposure; - float y_normalized = y / 0.18f; + float y_normalized; + [branch] + if (current_config.tone_map_method == config::tone_map_method::REINHARD + && current_config.contrast != 1.f) { + y_normalized = pow(y / 0.18f, current_config.contrast); + } else { + y_normalized = y / 0.18f; + } - if (current_config.tone_map_method == config::tone_map_method::REINHARD) { - y_normalized = pow(y_normalized, current_config.contrast); + float y_highlighted; + [branch] + if (current_config.highlights != 1.f) { + y_highlighted = pow(y_normalized, current_config.highlights); + y_highlighted = lerp(y_normalized, y_highlighted, saturate(y_normalized)); + } else { + y_highlighted = y_normalized; } - float y_highlighted = pow(y_normalized, current_config.highlights); - y_highlighted = lerp(y_normalized, y_highlighted, saturate(y_normalized)); + float y_shadowed; + [branch] + if (current_config.shadows != 1.f) { + y_shadowed = pow(y_highlighted, 2.f - current_config.shadows); + y_shadowed = lerp(y_shadowed, y_highlighted, saturate(y_highlighted)); + } else { + y_shadowed = y_highlighted; + } - float y_shadowed = pow(y_highlighted, 2.f - current_config.shadows); - y_shadowed = lerp(y_shadowed, y_highlighted, saturate(y_highlighted)); y_shadowed *= 0.18f; y = y_shadowed; float3 per_channel_color; + [branch] if (current_config.per_channel) { per_channel_color = input_color * (y_original > 0 ? (y / y_original) : 0); + } else { + per_channel_color = input_color; } + float m_0 = (n / n_r); float ts; float3 ts3; @@ -195,6 +219,7 @@ float3 BT709(float3 bt709, Config current_config) { } float3 color_output; + [branch] if (current_config.per_channel) { float3 flared3 = max(0, (ts3 * ts3) / (ts3 + t_1)); @@ -208,16 +233,19 @@ float3 BT709(float3 bt709, Config current_config) { color_output = input_color * (y_original > 0 ? (y_new / y_original) : 0); } - if (current_config.working_color_space == 2u) { - color_output = renodx::color::bt709::from::AP1(color_output); - } else if (current_config.working_color_space == 1u) { - color_output = renodx::color::bt709::from::BT2020(color_output); - } - + float current_color_space; + [branch] if (current_config.dechroma != 0.f || current_config.saturation != 1.f || current_config.hue_correction_strength != 0.f || current_config.blowout != 0.f) { + [branch] + if (current_config.working_color_space == 2u) { + color_output = renodx::color::bt709::from::AP1(color_output); + } else if (current_config.working_color_space == 1u) { + color_output = renodx::color::bt709::from::BT2020(color_output); + } + float3 perceptual_new; if (current_config.hue_correction_strength != 0.f) { @@ -225,6 +253,8 @@ float3 BT709(float3 bt709, Config current_config) { float3 source = (current_config.hue_correction_type == config::hue_correction_type::INPUT) ? bt709 : current_config.hue_correction_source; + + [branch] switch (current_config.hue_correction_method) { case config::hue_correction_method::OKLAB: default: @@ -241,7 +271,7 @@ float3 BT709(float3 bt709, Config current_config) { break; } - // Save chrominance to apply black + // Save chrominance to apply back float chrominance_pre_adjust = length(perceptual_new.yz); perceptual_new.yz = lerp(perceptual_new.yz, perceptual_old.yz, current_config.hue_correction_strength); @@ -252,6 +282,7 @@ float3 BT709(float3 bt709, Config current_config) { perceptual_new.yz *= renodx::math::DivideSafe(chrominance_pre_adjust, chrominance_post_adjust, 1.f); } else { + [branch] switch (current_config.hue_correction_method) { default: case config::hue_correction_method::OKLAB: @@ -284,6 +315,7 @@ float3 BT709(float3 bt709, Config current_config) { perceptual_new.yz *= current_config.saturation; + [branch] if (current_config.hue_correction_method == config::hue_correction_method::OKLAB) { color_output = renodx::color::bt709::from::OkLab(perceptual_new); } else if (current_config.hue_correction_method == config::hue_correction_method::ICTCP) { @@ -291,16 +323,28 @@ float3 BT709(float3 bt709, Config current_config) { } else if (current_config.hue_correction_method == config::hue_correction_method::DARKTABLE_UCS) { color_output = renodx::color::bt709::from::dtucs::uvY(perceptual_new.yzx); } + + current_color_space = renodx::color::convert::COLOR_SPACE_BT709; + } else { + color_output = color_output; + current_color_space = current_config.working_color_space; } - if (current_config.clamp_color_space == 0) { - color_output = renodx::color::bt709::clamp::BT709(color_output); - } else if (current_config.clamp_color_space == 1.f) { - color_output = renodx::color::bt709::clamp::BT2020(color_output); - } else if (current_config.clamp_color_space == 2.f) { - color_output = renodx::color::bt709::clamp::AP1(color_output); + [branch] + if (current_config.clamp_color_space != -1.f) { + color_output = renodx::color::convert::ColorSpaces(color_output, current_color_space, current_config.clamp_color_space); + color_output = max(0, color_output); + current_color_space = current_config.clamp_color_space; } - color_output = min(m_0, color_output); // Clamp to Peak + + [branch] + if (current_config.clamp_peak != -1.f) { + color_output = renodx::color::convert::ColorSpaces(color_output, current_color_space, current_config.clamp_peak); + color_output = min(color_output, m_0); + current_color_space = current_config.clamp_peak; + } + + color_output = renodx::color::convert::ColorSpaces(color_output, current_color_space, renodx::color::convert::COLOR_SPACE_BT709); return color_output; } diff --git a/src/shaders/tonemap.hlsl b/src/shaders/tonemap.hlsl index 9f117dbf..f9be6e32 100644 --- a/src/shaders/tonemap.hlsl +++ b/src/shaders/tonemap.hlsl @@ -223,6 +223,7 @@ struct Config { bool reno_drt_per_channel; float reno_drt_blowout; float reno_drt_clamp_color_space; + float reno_drt_clamp_peak; }; float3 UpgradeToneMap(float3 color_hdr, float3 color_sdr, float3 post_process_color, float post_process_strength) { @@ -290,7 +291,8 @@ Config Create( uint reno_drt_working_color_space = 0u, bool reno_drt_per_channel = false, float reno_drt_blowout = 0, - float reno_drt_clamp_color_space = 2.f) { + float reno_drt_clamp_color_space = 2.f, + float reno_drt_clamp_peak = 1.f) { const Config tm_config = { type, peak_nits, @@ -317,7 +319,8 @@ Config Create( reno_drt_working_color_space, reno_drt_per_channel, reno_drt_blowout, - reno_drt_clamp_color_space + reno_drt_clamp_color_space, + reno_drt_clamp_peak }; return tm_config; } @@ -360,6 +363,7 @@ float3 ApplyRenoDRT(float3 color, Config tm_config) { reno_drt_config.per_channel = tm_config.reno_drt_per_channel; reno_drt_config.blowout = tm_config.reno_drt_blowout; reno_drt_config.clamp_color_space = tm_config.reno_drt_clamp_color_space; + reno_drt_config.clamp_peak = tm_config.reno_drt_clamp_peak; return renodrt::BT709(color, reno_drt_config); } From 197907910ebd4ad26b9f37400a03468c7c8bf97b Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sat, 11 Jan 2025 15:12:23 -0500 Subject: [PATCH 11/12] feat(draw): add clamp_peak and use per-channel for hue shift --- src/shaders/draw.hlsl | 135 ++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 72 deletions(-) diff --git a/src/shaders/draw.hlsl b/src/shaders/draw.hlsl index b18f0c59..16da7e34 100644 --- a/src/shaders/draw.hlsl +++ b/src/shaders/draw.hlsl @@ -2,6 +2,7 @@ #define SRC_SHADERS_DRAW_HLSL_ #include "./color.hlsl" +#include "./color_convert.hlsl" #include "./colorcorrect.hlsl" #include "./math.hlsl" #include "./tonemap.hlsl" @@ -26,6 +27,8 @@ struct Config { float tone_map_hue_correction; // 1.f float tone_map_hue_shift; // 0.f float tone_map_working_color_space; // 0.f + float tone_map_clamp_color_space; // -1 = none, bt709, bt2020, ap1 + float tone_map_clamp_peak; // -1 = none, bt709, bt2020, ap1 float tone_map_hue_processor; // 0.f float tone_map_per_channel; // 0.f float gamma_correction; // 0 = srgb/none, 1 = 2.2, 2 = 2.4 @@ -54,16 +57,12 @@ static const float ENCODING_GAMMA_2_4 = 3.f; static const float ENCODING_PQ = 4.f; static const float ENCODING_SCRGB = 5.f; -static const float COLOR_SPACE_UNKNOWN = -1; -static const float COLOR_SPACE_BT709 = 0; -static const float COLOR_SPACE_BT2020 = 1.f; -static const float COLOR_SPACE_AP1 = 2.f; - static const float COLOR_SPACE_CUSTOM_BT709D65 = 0; static const float COLOR_SPACE_CUSTOM_BT709D93 = 1.f; static const float COLOR_SPACE_CUSTOM_NTSCU = 2.f; static const float COLOR_SPACE_CUSTOM_NTSCJ = 3.f; +static const float HUE_PROCESSOR_NONE = -1.f; static const float HUE_PROCESSOR_OKLAB = 0; static const float HUE_PROCESSOR_ICTCP = 1.f; static const float HUE_PROCESSOR_DTUCS = 2.f; @@ -158,10 +157,20 @@ Config BuildConfig() { config.tone_map_hue_shift = RENODX_TONE_MAP_HUE_SHIFT; #if !defined(RENODX_TONE_MAP_WORKING_COLOR_SPACE) -#define RENODX_TONE_MAP_WORKING_COLOR_SPACE COLOR_SPACE_BT709 +#define RENODX_TONE_MAP_WORKING_COLOR_SPACE color::convert::COLOR_SPACE_BT709 #endif config.tone_map_working_color_space = RENODX_TONE_MAP_WORKING_COLOR_SPACE; +#if !defined(RENODX_TONE_MAP_CLAMP_COLOR_SPACE) +#define RENODX_TONE_MAP_CLAMP_COLOR_SPACE color::convert::COLOR_SPACE_NONE +#endif + config.tone_map_clamp_color_space = RENODX_TONE_MAP_CLAMP_COLOR_SPACE; + +#if !defined(RENODX_TONE_MAP_CLAMP_PEAK) +#define RENODX_TONE_MAP_CLAMP_PEAK color::convert::COLOR_SPACE_BT709 +#endif + config.tone_map_clamp_peak = RENODX_TONE_MAP_CLAMP_PEAK; + #if !defined(RENODX_TONE_MAP_HUE_PROCESSOR) #define RENODX_TONE_MAP_HUE_PROCESSOR HUE_PROCESSOR_OKLAB #endif @@ -188,7 +197,7 @@ Config BuildConfig() { config.intermediate_encoding = RENODX_INTERMEDIATE_ENCODING; #if !defined(RENODX_INTERMEDIATE_COLOR_SPACE) -#define RENODX_INTERMEDIATE_COLOR_SPACE COLOR_SPACE_BT709 +#define RENODX_INTERMEDIATE_COLOR_SPACE color::convert::COLOR_SPACE_BT709 #endif config.intermediate_color_space = RENODX_INTERMEDIATE_COLOR_SPACE; @@ -218,7 +227,7 @@ Config BuildConfig() { config.swap_chain_clamp_nits = RENODX_SWAP_CHAIN_CLAMP_NITS; #if !defined(RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE) -#define RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE COLOR_SPACE_UNKNOWN +#define RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE color::convert::COLOR_SPACE_UNKNOWN #endif config.swap_chain_clamp_color_space = RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE; @@ -228,63 +237,13 @@ Config BuildConfig() { config.swap_chain_encoding = RENODX_SWAP_CHAIN_ENCODING; #if !defined(RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE) -#define RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE COLOR_SPACE_BT709 +#define RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE color::convert::COLOR_SPACE_BT709 #endif config.swap_chain_encoding_color_space = RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE; return config; }; -float3 ConvertColorSpaceFromBT709(float3 color, float color_space) { - [branch] - if (color_space == COLOR_SPACE_BT2020) { - color = renodx::color::bt2020::from::BT709(color); - } else if (color_space == COLOR_SPACE_AP1) { - color = renodx::color::ap1::from::BT709(color); - } else { - color = color; - } - return color; -} - -float3 ConvertColorSpaceFromBT2020(float3 color, float color_space) { - [branch] - if (color_space == COLOR_SPACE_BT709) { - color = renodx::color::bt709::from::BT2020(color); - } else if (color_space == COLOR_SPACE_AP1) { - color = renodx::color::ap1::from::BT2020(color); - } else { - color = color; - } - return color; -} - -float3 ConvertColorSpaceFromAP1(float3 color, float color_space) { - [branch] - if (color_space == COLOR_SPACE_BT709) { - color = renodx::color::bt709::from::AP1(color); - } else if (color_space == COLOR_SPACE_BT2020) { - color = renodx::color::bt2020::from::AP1(color); - } else { - color = color; - } - return color; -} - -float3 ConvertColorSpaces(float3 color, float input_color_space, float output_color_space) { - [branch] - if (input_color_space == COLOR_SPACE_BT709) { - color = ConvertColorSpaceFromBT709(color, output_color_space); - } else if (input_color_space == COLOR_SPACE_BT2020) { - color = ConvertColorSpaceFromBT2020(color, output_color_space); - } else if (input_color_space == COLOR_SPACE_AP1) { - color = ConvertColorSpaceFromAP1(color, output_color_space); - } else { - color = color; - } - return color; -} - float3 DecodeColor(float3 color, float encoding) { [branch] if (encoding == ENCODING_SRGB) { @@ -364,29 +323,52 @@ float3 RenderIntermediatePass(float3 color, Config config) { color *= config.intermediate_scaling; - color = ConvertColorSpaceFromBT709(color, config.intermediate_color_space); + color = renodx::color::convert::ColorSpaces( + color, + renodx::color::convert::COLOR_SPACE_BT709, + config.intermediate_color_space); color = EncodeColor(color, config.intermediate_encoding); return color; } +float3 InvertIntermediatePass(float3 color, Config config) { + color = DecodeColor(color, config.intermediate_encoding); + + color = renodx::color::convert::ColorSpaces( + color, + config.intermediate_color_space, + renodx::color::convert::COLOR_SPACE_BT709); + + color /= config.intermediate_scaling; + + [branch] + if (config.gamma_correction == GAMMA_CORRECTION_GAMMA_2_2) { + color = renodx::color::correct::GammaSafe(color, true, 2.2f); + } else if (config.gamma_correction == GAMMA_CORRECTION_GAMMA_2_4) { + color = renodx::color::correct::GammaSafe(color, true, 2.4f); + } + + return color; +} + float3 SwapChainPass(float3 color, Config config) { color = DecodeColor(color, config.swap_chain_decoding); [branch] if (config.swap_chain_custom_color_space == COLOR_SPACE_CUSTOM_BT709D93) { - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, COLOR_SPACE_BT709); + color = color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, color::convert::COLOR_SPACE_BT709); color = renodx::color::bt709::from::BT709D93(color); - config.swap_chain_decoding_color_space = COLOR_SPACE_BT709; + config.swap_chain_decoding_color_space = renodx::color::convert::COLOR_SPACE_BT709; } else if (config.swap_chain_custom_color_space == COLOR_SPACE_CUSTOM_NTSCU) { - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, COLOR_SPACE_BT709); + color = color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, color::convert::COLOR_SPACE_BT709); color = renodx::color::bt709::from::BT601NTSCU(color); - config.swap_chain_decoding_color_space = COLOR_SPACE_BT709; + config.swap_chain_decoding_color_space = renodx::color::convert::COLOR_SPACE_BT709; } else if (config.swap_chain_custom_color_space == COLOR_SPACE_CUSTOM_NTSCJ) { - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, COLOR_SPACE_BT709); + color = color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, color::convert::COLOR_SPACE_BT709); color = renodx::color::bt709::from::ARIBTRB9(color); - config.swap_chain_decoding_color_space = COLOR_SPACE_BT709; + config.swap_chain_decoding_color_space = renodx::color::convert::COLOR_SPACE_BT709; } color *= config.swap_chain_scaling_nits; @@ -394,19 +376,19 @@ float3 SwapChainPass(float3 color, Config config) { color = min(color, config.swap_chain_clamp_nits); // Clamp UI or Videos [branch] - if (config.swap_chain_clamp_color_space != COLOR_SPACE_UNKNOWN) { + if (config.swap_chain_clamp_color_space != renodx::color::convert::COLOR_SPACE_UNKNOWN) { [branch] if (config.swap_chain_clamp_color_space == config.swap_chain_encoding_color_space) { - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); + color = renodx::color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); color = max(0, color); } else { if (config.swap_chain_clamp_color_space == config.swap_chain_decoding_color_space) { color = max(0, color); } - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); + color = renodx::color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); } } else { - color = ConvertColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); + color = renodx::color::convert::ColorSpaces(color, config.swap_chain_decoding_color_space, config.swap_chain_encoding_color_space); } color = EncodeColor(color, config.swap_chain_encoding); @@ -436,7 +418,8 @@ float3 ToneMapPass(float3 color, Config draw_config) { tone_map_config.reno_drt_working_color_space = (uint)draw_config.tone_map_working_color_space; tone_map_config.reno_drt_per_channel = draw_config.tone_map_per_channel == 1.f; tone_map_config.reno_drt_hue_correction_method = (uint)draw_config.tone_map_hue_processor; - tone_map_config.reno_drt_clamp_color_space = -1.f; // None + tone_map_config.reno_drt_clamp_color_space = draw_config.tone_map_clamp_color_space; + tone_map_config.reno_drt_clamp_peak = draw_config.tone_map_clamp_peak; tone_map_config.hue_correction_strength = draw_config.tone_map_hue_correction; @@ -445,7 +428,7 @@ float3 ToneMapPass(float3 color, Config draw_config) { if (draw_config.tone_map_hue_shift != 0) { output_color = renodx::color::correct::Hue( output_color, - renodx::tonemap::renodrt::NeutralSDR(output_color), + renodx::tonemap::renodrt::NeutralSDR(output_color, true), draw_config.tone_map_hue_shift); } @@ -474,6 +457,14 @@ float4 RenderIntermediatePass(float4 color) { return float4(RenderIntermediatePass(color.rgb, BuildConfig()).rgb, 1.f); } +float3 InvertIntermediatePass(float3 color) { + return InvertIntermediatePass(color, BuildConfig()); +} + +float4 InvertIntermediatePass(float4 color) { + return float4(InvertIntermediatePass(color.rgb, BuildConfig()).rgb, 1.f); +} + float3 SwapChainPass(float3 color) { return SwapChainPass(color, BuildConfig()); } From f83b1aef5accbc3fa864f1ad4036fd22297e8768 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sat, 11 Jan 2025 15:12:58 -0500 Subject: [PATCH 12/12] feat(tunic): rewrite with renodx::draw --- src/games/tunic/addon.cpp | 285 +++++++++++++----- .../tunic/booklet_0xB274BE4D.ps_4_0.hlsl | 101 ------- .../tunic/final00_0x49E25D6C.ps_4_0.hlsl | 26 -- .../tunic/final01_0x55B0DCB7.ps_4_0.hlsl | 85 ------ .../tunic/final02_0x5439FB55.ps_4_0.hlsl | 39 --- .../tunic/final03_0x54E583C8.ps_4_0.hlsl | 31 -- ...s_4_0.hlsl => glow_0x4AC5CC39.ps_4_0.hlsl} | 41 ++- src/games/tunic/intro_0x1CCE11A3.ps_4_0.hlsl | 37 --- .../tunic/lutsample2_0xAA66A0B6.ps_4_0.hlsl | 52 ++-- .../tunic/lutsample_0xEEFE9737.ps_4_0.hlsl | 52 ++-- src/games/tunic/shared.h | 69 +++-- .../swap_chain_proxy_pixel_shader.ps_4_0.hlsl | 8 + ...swap_chain_proxy_vertex_shader.vs_4_0.hlsl | 6 + 13 files changed, 334 insertions(+), 498 deletions(-) delete mode 100644 src/games/tunic/booklet_0xB274BE4D.ps_4_0.hlsl delete mode 100644 src/games/tunic/final00_0x49E25D6C.ps_4_0.hlsl delete mode 100644 src/games/tunic/final01_0x55B0DCB7.ps_4_0.hlsl delete mode 100644 src/games/tunic/final02_0x5439FB55.ps_4_0.hlsl delete mode 100644 src/games/tunic/final03_0x54E583C8.ps_4_0.hlsl rename src/games/tunic/{final04_0x4AC5CC39.ps_4_0.hlsl => glow_0x4AC5CC39.ps_4_0.hlsl} (71%) delete mode 100644 src/games/tunic/intro_0x1CCE11A3.ps_4_0.hlsl create mode 100644 src/games/tunic/swap_chain_proxy_pixel_shader.ps_4_0.hlsl create mode 100644 src/games/tunic/swap_chain_proxy_vertex_shader.vs_4_0.hlsl diff --git a/src/games/tunic/addon.cpp b/src/games/tunic/addon.cpp index ac019bc6..baa3c4fb 100644 --- a/src/games/tunic/addon.cpp +++ b/src/games/tunic/addon.cpp @@ -7,19 +7,11 @@ #define DEBUG_LEVEL_0 -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include +#include + #include "../../mods/shader.hpp" #include "../../mods/swapchain.hpp" #include "../../utils/settings.hpp" @@ -28,34 +20,38 @@ namespace { renodx::mods::shader::CustomShaders custom_shaders = { - CustomShaderEntry(0x49E25D6C), // final - CustomShaderEntry(0x1CCE11A3), // UI/video - CustomShaderEntry(0xB274BE4D), // booklet - CustomShaderEntry(0x55B0DCB7), CustomShaderEntry(0xEEFE9737), // LUT CustomShaderEntry(0xAA66A0B6), // LUT + Noise - CustomShaderEntry(0x5439FB55), - CustomShaderEntry(0x54E583C8), // glow effect - CustomShaderEntry(0x4AC5CC39) // tonemapper + CustomShaderEntry(0x4AC5CC39) // glow }; ShaderInjectData shader_injection; renodx::utils::settings::Settings settings = { new renodx::utils::settings::Setting{ - .key = "toneMapType", - .binding = &shader_injection.toneMapType, + .key = "SettingsMode", .value_type = renodx::utils::settings::SettingValueType::INTEGER, - .default_value = 3.f, + .default_value = 0.f, .can_reset = false, + .label = "Settings Mode", + .labels = {"Simple", "Intermediate", "Advanced"}, + .is_global = true, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapType", + .binding = &RENODX_TONE_MAP_TYPE, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 3.f, + .can_reset = true, .label = "Tone Mapper", .section = "Tone Mapping", .tooltip = "Sets the tone mapper type", .labels = {"Vanilla", "None", "ACES", "RenoDRT"}, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, }, new renodx::utils::settings::Setting{ - .key = "toneMapPeakNits", - .binding = &shader_injection.toneMapPeakNits, + .key = "ToneMapPeakNits", + .binding = &RENODX_PEAK_WHITE_NITS, .default_value = 1000.f, .can_reset = false, .label = "Peak Brightness", @@ -65,8 +61,8 @@ renodx::utils::settings::Settings settings = { .max = 4000.f, }, new renodx::utils::settings::Setting{ - .key = "toneMapGameNits", - .binding = &shader_injection.toneMapGameNits, + .key = "ToneMapGameNits", + .binding = &RENODX_DIFFUSE_WHITE_NITS, .default_value = 203.f, .label = "Game Brightness", .section = "Tone Mapping", @@ -75,8 +71,8 @@ renodx::utils::settings::Settings settings = { .max = 500.f, }, new renodx::utils::settings::Setting{ - .key = "toneMapUINits", - .binding = &shader_injection.toneMapUINits, + .key = "ToneMapUINits", + .binding = &RENODX_GRAPHICS_WHITE_NITS, .default_value = 203.f, .label = "UI Brightness", .section = "Tone Mapping", @@ -85,46 +81,110 @@ renodx::utils::settings::Settings settings = { .max = 500.f, }, new renodx::utils::settings::Setting{ - .key = "toneMapHueCorrection", - .binding = &shader_injection.toneMapHueCorrection, + .key = "ToneMapHueProcessor", + .binding = &RENODX_TONE_MAP_HUE_PROCESSOR, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Hue Processor", + .section = "Tone Mapping", + .tooltip = "Selects hue processor", + .labels = {"OKLab", "ICtCp", "darkTable UCS"}, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, + .is_visible = []() { return settings[0]->GetValue() >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapHueShift", + .binding = &RENODX_TONE_MAP_HUE_SHIFT, + .default_value = 100.f, + .label = "Hue Shift", + .section = "Tone Mapping", + .tooltip = "Hue-shift emulation strength.", + .min = 0.f, + .max = 100.f, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, + .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapWorkingColorSpace", + .binding = &RENODX_TONE_MAP_WORKING_COLOR_SPACE, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Working Color Space", + .section = "Tone Mapping", + .labels = {"BT709", "BT2020", "AP1"}, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, + .is_visible = []() { return settings[0]->GetValue() >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapHueCorrection", + .binding = &RENODX_TONE_MAP_HUE_CORRECTION, .default_value = 100.f, .label = "Hue Correction", .section = "Tone Mapping", - .tooltip = "Emulates Vanilla hue shifts.", + .tooltip = "Hue retention strength.", .min = 0.f, .max = 100.f, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return settings[0]->GetValue() >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "GammaCorrection", + .binding = &RENODX_GAMMA_CORRECTION, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 1.f, + .label = "Gamma Correction", + .section = "Tone Mapping", + .tooltip = "Emulates a display EOTF.", + .labels = {"Off", "2.2", "BT.1886"}, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapScaling", + .binding = &RENODX_TONE_MAP_PER_CHANNEL, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Scaling", + .section = "Tone Mapping", + .tooltip = "Luminance scales colors consistently while per-channel saturates and blows out sooner", + .labels = {"Luminance", "Per Channel"}, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, + .is_visible = []() { return settings[0]->GetValue() >= 2; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeExposure", - .binding = &shader_injection.colorGradeExposure, + .key = "ColorGradeExposure", + .binding = &RENODX_TONE_MAP_EXPOSURE, .default_value = 1.f, .label = "Exposure", .section = "Color Grading", - .max = 10.f, + .max = 2.f, .format = "%.2f", + .is_visible = []() { return settings[0]->GetValue() >= 1; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeHighlights", - .binding = &shader_injection.colorGradeHighlights, + .key = "ColorGradeHighlights", + .binding = &RENODX_TONE_MAP_HIGHLIGHTS, .default_value = 50.f, .label = "Highlights", .section = "Color Grading", .max = 100.f, .parse = [](float value) { return value * 0.02f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeShadows", - .binding = &shader_injection.colorGradeShadows, + .key = "ColorGradeShadows", + .binding = &RENODX_TONE_MAP_SHADOWS, .default_value = 50.f, .label = "Shadows", .section = "Color Grading", .max = 100.f, .parse = [](float value) { return value * 0.02f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeContrast", - .binding = &shader_injection.colorGradeContrast, + .key = "ColorGradeContrast", + .binding = &RENODX_TONE_MAP_CONTRAST, .default_value = 50.f, .label = "Contrast", .section = "Color Grading", @@ -132,8 +192,8 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.02f; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeSaturation", - .binding = &shader_injection.colorGradeSaturation, + .key = "ColorGradeSaturation", + .binding = &RENODX_TONE_MAP_SATURATION, .default_value = 50.f, .label = "Saturation", .section = "Color Grading", @@ -141,9 +201,21 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.02f; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeBlowout", - .binding = &shader_injection.colorGradeBlowout, + .key = "ColorGradeHighlightSaturation", + .binding = &RENODX_TONE_MAP_HIGHLIGHT_SATURATION, .default_value = 50.f, + .label = "Highlight Saturation", + .section = "Color Grading", + .tooltip = "Adds or removes highlight color.", + .max = 100.f, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE >= 1; }, + .parse = [](float value) { return value * 0.02f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeBlowout", + .binding = &RENODX_TONE_MAP_BLOWOUT, + .default_value = 0.f, .label = "Blowout", .section = "Color Grading", .tooltip = "Controls highlight desaturation due to overexposure.", @@ -151,17 +223,29 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.01f; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeLUTStrength", - .binding = &shader_injection.colorGradeLUTStrength, + .key = "ColorGradeFlare", + .binding = &RENODX_TONE_MAP_FLARE, + .default_value = 0.f, + .label = "Flare", + .section = "Color Grading", + .tooltip = "Flare/Glare Compensation", + .max = 100.f, + .is_enabled = []() { return RENODX_TONE_MAP_TYPE == 3; }, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeLUTStrength", + .binding = &CUSTOM_LUT_STRENGTH, .default_value = 100.f, .label = "LUT Strength", .section = "Color Grading", .max = 100.f, .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, }, new renodx::utils::settings::Setting{ - .key = "colorGradeLUTScaling", - .binding = &shader_injection.colorGradeLUTScaling, + .key = "ColorGradeLUTScaling", + .binding = &CUSTOM_LUT_SCALING, .default_value = 100.f, .label = "LUT Scaling", .section = "Color Grading", @@ -170,8 +254,8 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.01f; }, }, new renodx::utils::settings::Setting{ - .key = "fxNoise", - .binding = &shader_injection.fxNoise, + .key = "FxNoise", + .binding = &CUSTOM_NOISE, .default_value = 50.f, .label = "Noise", .section = "Effects", @@ -180,50 +264,101 @@ renodx::utils::settings::Settings settings = { .parse = [](float value) { return value * 0.02f; }, }, new renodx::utils::settings::Setting{ - .key = "fxScreenGlow", - .binding = &shader_injection.fxScreenGlow, + .key = "FxScreenGlow", + .binding = &CUSTOM_SCREEN_GLOW, .default_value = 100.f, .label = "Screen Glow", .section = "Effects", .max = 100.f, .parse = [](float value) { return value * 0.01f; }, }, + new renodx::utils::settings::Setting{ + .key = "FxMotionBlur", + .binding = &CUSTOM_MOTION_BLUR, + .default_value = 100.f, + .label = "Motion Blur", + .section = "Effects", + .max = 100.f, + .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, + }, new renodx::utils::settings::Setting{ .value_type = renodx::utils::settings::SettingValueType::BUTTON, - .label = "Discord", - .section = "Links", + .label = "Reset All", + .section = "Options", + .group = "button-line-1", + .on_change = []() { + for (auto setting : settings) { + if (setting->key.empty()) continue; + if (!setting->can_reset) continue; + renodx::utils::settings::UpdateSetting(setting->key, setting->default_value); + } + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "HDR Look", + .section = "Options", .group = "button-line-1", + .on_change = []() { + for (auto setting : settings) { + if (setting->key.empty()) continue; + if (!setting->can_reset) continue; + if (setting->key == "ColorGradeSaturation" || setting->key == "ColorGradeContrast" || setting->key == "ColorGradeBlowout") { + renodx::utils::settings::UpdateSetting(setting->key, 80.f); + } else { + renodx::utils::settings::UpdateSetting(setting->key, setting->default_value); + } + } + }, + }, + new renodx::utils::settings::Setting{ + .value_type = renodx::utils::settings::SettingValueType::BUTTON, + .label = "Discord", + .section = "Options", + .group = "button-line-2", .tint = 0x5865F2, .on_change = []() { - system("start https://discord.gg/5WZXDpmbpP"); + renodx::utils::platform::Launch( + "https://discord.gg/" + "5WZXDpmbpP"); }, }, new renodx::utils::settings::Setting{ .value_type = renodx::utils::settings::SettingValueType::BUTTON, .label = "Github", - .section = "Links", - .group = "button-line-1", + .section = "Options", + .group = "button-line-2", .on_change = []() { - system("start https://github.com/clshortfuse/renodx"); + renodx::utils::platform::Launch("https://github.com/clshortfuse/renodx"); }, }, }; void OnPresetOff() { - renodx::utils::settings::UpdateSetting("toneMapType", 0.f); - renodx::utils::settings::UpdateSetting("toneMapPeakNits", 203.f); - renodx::utils::settings::UpdateSetting("toneMapGameNits", 203.f); - renodx::utils::settings::UpdateSetting("toneMapUINits", 203.f); - renodx::utils::settings::UpdateSetting("colorGradeExposure", 1.f); - renodx::utils::settings::UpdateSetting("colorGradeHighlights", 50.f); - renodx::utils::settings::UpdateSetting("colorGradeShadows", 50.f); - renodx::utils::settings::UpdateSetting("colorGradeContrast", 50.f); - renodx::utils::settings::UpdateSetting("colorGradeSaturation", 50.f); - renodx::utils::settings::UpdateSetting("colorGradeBlowout", 0.f); - renodx::utils::settings::UpdateSetting("colorGradeLUTStrength", 100.f); - renodx::utils::settings::UpdateSetting("colorGradeLUTScaling", 0.f); - renodx::utils::settings::UpdateSetting("fxNoise", 50.f); - renodx::utils::settings::UpdateSetting("fxScreenGlow", 100.f); + renodx::utils::settings::UpdateSetting("ToneMapType", 0.f); + renodx::utils::settings::UpdateSetting("ToneMapPeakNits", 203.f); + renodx::utils::settings::UpdateSetting("ToneMapGameNits", 203.f); + renodx::utils::settings::UpdateSetting("ToneMapUINits", 203.f); + // renodx::utils::settings::UpdateSetting("ToneMapHueProcessor", 1.f); + // renodx::utils::settings::UpdateSetting("ToneMapHueShift", 1.f); + // renodx::utils::settings::UpdateSetting("ToneMapWorkingColorSpace", 1.f); + // renodx::utils::settings::UpdateSetting("ToneMapHueCorrection", 1.f); + renodx::utils::settings::UpdateSetting("GammaCorrection", 0.f); + // renodx::utils::settings::UpdateSetting("ToneMapScaling", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeExposure", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeHighlights", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeShadows", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeContrast", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeSaturation", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeHighlightSaturation", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeBlowout", 1.f); + // renodx::utils::settings::UpdateSetting("ColorGradeFlare", 1.f); + renodx::utils::settings::UpdateSetting("ColorGradeLUTStrength", 100.f); + renodx::utils::settings::UpdateSetting("ColorGradeLUTScaling", 0.f); + renodx::utils::settings::UpdateSetting("FxNoise", 50.f); + renodx::utils::settings::UpdateSetting("FxScreenGlow", 100.f); + renodx::utils::settings::UpdateSetting("FxMotionBlur", 100.f); } bool fired_on_init_swapchain = false; @@ -233,8 +368,8 @@ void OnInitSwapchain(reshade::api::swapchain* swapchain) { fired_on_init_swapchain = true; auto peak = renodx::utils::swapchain::GetPeakNits(swapchain); if (peak.has_value()) { - settings[1]->default_value = peak.value(); - settings[1]->can_reset = true; + settings[2]->default_value = peak.value(); + settings[2]->can_reset = true; } } @@ -248,6 +383,10 @@ BOOL APIENTRY DllMain(HMODULE h_module, DWORD fdw_reason, LPVOID lpv_reserved) { case DLL_PROCESS_ATTACH: if (!reshade::register_addon(h_module)) return FALSE; + renodx::mods::swapchain::use_resource_cloning = true; + renodx::mods::swapchain::swap_chain_proxy_vertex_shader = __swap_chain_proxy_vertex_shader; + renodx::mods::swapchain::swap_chain_proxy_pixel_shader = __swap_chain_proxy_pixel_shader; + // Always upgrade first of format renodx::mods::swapchain::swap_chain_upgrade_targets.push_back({ .old_format = reshade::api::format::r8g8b8a8_typeless, @@ -271,7 +410,7 @@ BOOL APIENTRY DllMain(HMODULE h_module, DWORD fdw_reason, LPVOID lpv_reserved) { renodx::utils::settings::Use(fdw_reason, &settings, &OnPresetOff); - renodx::mods::swapchain::Use(fdw_reason); + renodx::mods::swapchain::Use(fdw_reason, &shader_injection); renodx::mods::shader::Use(fdw_reason, custom_shaders, &shader_injection); diff --git a/src/games/tunic/booklet_0xB274BE4D.ps_4_0.hlsl b/src/games/tunic/booklet_0xB274BE4D.ps_4_0.hlsl deleted file mode 100644 index c6fe0802..00000000 --- a/src/games/tunic/booklet_0xB274BE4D.ps_4_0.hlsl +++ /dev/null @@ -1,101 +0,0 @@ -// booklet - -#include "./shared.h" - -Texture2D t1 : register(t1); - -Texture2D t0 : register(t0); - -SamplerState s1_s : register(s1); - -SamplerState s0_s : register(s0); - -cbuffer cb0 : register(b0) { - float4 cb0[5]; -} - -// 3Dmigoto declarations -#define cmp - - -void main( - float4 v0 : SV_POSITION0, - float2 v1 : TEXCOORD0, - float2 w1 : TEXCOORD1, - out float4 o0 : SV_Target0 -) { - const float4 icb[] = { - { 0.624630, 0.543370, 0.827900, 0}, - {-0.134140, -0.944880, 0.954350, 0}, - { 0.387720, -0.434750, 0.582530, 0}, - { 0.121260, -0.192820, 0.227780, 0}, - {-0.203880, 0.111330, 0.232300, 0}, - { 0.831140, -0.292180, 0.881000, 0}, - { 0.107590, -0.578390, 0.588310, 0}, - { 0.282850, 0.790360, 0.839450, 0}, - {-0.366220, 0.395160, 0.538760, 0}, - { 0.755910, 0.219160, 0.787040, 0}, - {-0.526100, 0.023860, 0.526640, 0}, - {-0.882160, -0.244710, 0.915470, 0}, - {-0.488880, -0.293300, 0.570110, 0}, - { 0.440140, -0.085580, 0.448380, 0}, - { 0.211790, 0.513730, 0.555670, 0}, - { 0.054830, 0.957010, 0.958580, 0}, - {-0.590010, -0.705090, 0.919380, 0}, - {-0.800650, 0.246310, 0.837680, 0}, - {-0.194240, -0.184020, 0.267570, 0}, - {-0.436670, 0.767510, 0.883040, 0}, - { 0.216660, 0.116020, 0.245770, 0}, - { 0.156960, -0.856000, 0.870270, 0}, - {-0.758210, 0.583630, 0.956820, 0}, - { 0.992840, -0.029040, 0.993270, 0}, - {-0.222340, -0.579070, 0.620290, 0}, - { 0.550520, -0.669840, 0.867040, 0}, - { 0.464310, 0.281150, 0.542800, 0}, - {-0.072140, 0.605540, 0.609820, 0} - }; - float4 r0, r1, r2, r3, r4, r5; - uint4 bitmask, uiDest; - float4 fDest; - - r0.xyzw = t0.Sample(s1_s, w1.xy).xyzw; - r1.xyzw = t1.Sample(s0_s, w1.xy).xyzw; - r2.xy = cb0[3].xy * r1.ww; - r2.xy = cb0[4].ww * r2.xy; - r0.w = 0.25 * r1.w; - r0.w = max(0.100000001, r0.w); - r3.xyz = r1.xyz * r0.www; - r4.xyz = r3.xyz; - r2.z = r0.w; - r2.w = 0; - while (true) { - r3.w = cmp((int)r2.w >= 28); - if (r3.w != 0) break; - r5.xy = icb[r2.w + 0].xy * r2.xy + w1.xy; - r5.xyzw = t1.Sample(s0_s, r5.xy).xyzw; - r3.w = -r1.w * icb[r2.w + 0].z + r5.w; - r3.w = 0.264999986 + r3.w; - r3.w = saturate(3.77358508 * r3.w); - r4.w = r3.w * -2 + 3; - r3.w = r3.w * r3.w; - r5.w = r4.w * r3.w; - r4.xyz = r5.xyz * r5.www + r4.xyz; - r2.z = r4.w * r3.w + r2.z; - r2.w = (int)r2.w + 1; - } - r0.w = 9.99999975e-06 + r2.z; - r2.xyz = r4.xyz / r0.www; - r0.w = -0.649999976 + r1.w; - r0.w = saturate(4.99999905 * r0.w); - r2.w = r0.w * -2 + 3; - r0.w = r0.w * r0.w; - r0.w = r2.w * r0.w; - r0.xyz = -r2.xyz + r0.xyz; - r0.xyz = r0.www * r0.xyz + r2.xyz; - r2.x = cmp(r1.w < 0.00999999978); - r0.w = r1.w; - o0.xyzw = r2.xxxx ? r1.xyzw : r0.xyzw; - - o0.rgb = pow(saturate(o0.rgb), 2.2f); - o0.rgb *= injectedData.toneMapUINits / 80.f; - return; -} diff --git a/src/games/tunic/final00_0x49E25D6C.ps_4_0.hlsl b/src/games/tunic/final00_0x49E25D6C.ps_4_0.hlsl deleted file mode 100644 index 49e5ed76..00000000 --- a/src/games/tunic/final00_0x49E25D6C.ps_4_0.hlsl +++ /dev/null @@ -1,26 +0,0 @@ -// Final render (everything) - -#include "./shared.h" - -Texture2D t0 : register(t0); - -SamplerState s0_s : register(s0); - -cbuffer cb0 : register(b0) { - float4 cb0[4]; -} - -// 3Dmigoto declarations -#define cmp - - -float4 main(float4 v0 : SV_POSITION0, float2 v1 : TEXCOORD0) : SV_Target0 { - float4 r0; - - const float4 inputColor = t0.Sample(s0_s, v1.xy).xyzw; - - r0.xyzw = inputColor; - - float4 outputColor = cb0[3].xyzw * r0.xyzw; - - return outputColor; -} diff --git a/src/games/tunic/final01_0x55B0DCB7.ps_4_0.hlsl b/src/games/tunic/final01_0x55B0DCB7.ps_4_0.hlsl deleted file mode 100644 index ad8eeb5c..00000000 --- a/src/games/tunic/final01_0x55B0DCB7.ps_4_0.hlsl +++ /dev/null @@ -1,85 +0,0 @@ -#include "./shared.h" - -Texture2D t2 : register(t2); - -Texture2D t1 : register(t1); - -Texture2D t0 : register(t0); - -SamplerState s2_s : register(s2); - -SamplerState s1_s : register(s1); - -SamplerState s0_s : register(s0); - -cbuffer cb1 : register(b1) -{ - float4 cb1[1]; -} - -cbuffer cb0 : register(b0) -{ - float4 cb0[23]; -} - - - - -// 3Dmigoto declarations -#define cmp - - - -void main( - float4 v0 : SV_POSITION0, - float4 v1 : COLOR0, - float4 v2 : TEXCOORD0, - float4 v3 : TEXCOORD1, - float4 v4 : TEXCOORD2, - float4 v5 : TEXCOORD3, - float4 v6 : TEXCOORD5, - out float4 o0 : SV_Target0) -{ - float4 r0,r1,r2,r3; - uint4 bitmask, uiDest; - float4 fDest; - - r0.xyzw = t0.Sample(s2_s, v2.xy).xyzw; - r0.x = -v3.x + r0.w; - r0.y = v3.z + -r0.w; - r0.x = cmp(r0.x < 0); - if (r0.x != 0) discard; - r0.x = cb0[22].w * cb0[6].x; - r0.x = v3.y * r0.x; - r0.z = min(1, r0.x); - r0.x = 0.5 * r0.x; - r0.z = sqrt(r0.z); - r0.w = saturate(r0.y * v3.y + r0.x); - r0.x = r0.y * v3.y + -r0.x; - r0.y = r0.w * r0.z; - r0.zw = cb0[4].zw * cb1[0].yy + v6.zw; - r1.xyzw = t2.Sample(s1_s, r0.zw).xyzw; - r1.xyzw = cb0[5].xyzw * r1.xyzw; - r1.xyz = r1.xyz * r1.www; - r2.xyz = cb0[3].xyz * v1.xyz; - r0.zw = cb0[2].xy * cb1[0].yy + v6.xy; - r3.xyzw = t1.Sample(s0_s, r0.zw).xyzw; - r2.xyz = r3.xyz * r2.xyz; - r3.w = cb0[3].w * r3.w; - r3.xyz = r3.www * r2.xyz; - r1.xyzw = -r3.xyzw + r1.xyzw; - r1.xyzw = r0.yyyy * r1.xyzw + r3.xyzw; - r0.y = cb0[22].w * cb0[4].y; - r0.z = v3.y * r0.y; - r0.y = r0.y * v3.y + 1; - r0.x = r0.z * 0.5 + r0.x; - r0.x = saturate(r0.x / r0.y); - r0.x = 1 + -r0.x; - r0.xyzw = r1.xyzw * r0.xxxx; - o0.xyzw = v1.wwww * r0.xyzw; - - - o0.rgb = pow(saturate(o0.rgb), 2.2f); - o0.rgb *= injectedData.toneMapUINits / 80.f; - - return; -} \ No newline at end of file diff --git a/src/games/tunic/final02_0x5439FB55.ps_4_0.hlsl b/src/games/tunic/final02_0x5439FB55.ps_4_0.hlsl deleted file mode 100644 index fc1a6285..00000000 --- a/src/games/tunic/final02_0x5439FB55.ps_4_0.hlsl +++ /dev/null @@ -1,39 +0,0 @@ -// UI Component - -#include "./shared.h" - -Texture2D t0 : register(t0); - -SamplerState s0_s : register(s0); - -cbuffer cb0 : register(b0) -{ - float4 cb0[4]; -} - -// 3Dmigoto declarations -#define cmp - - -void main( - float4 v0 : SV_POSITION0, - float4 v1 : COLOR0, - float4 v2 : TEXCOORD0, - float4 v3 : TEXCOORD1, - float4 v4 : TEXCOORD2, - out float4 o0 : SV_Target0) -{ - float4 r0; - uint4 bitmask, uiDest; - float4 fDest; - - const float4 inputColor = t0.Sample(s0_s, v2.xy).xyzw; - r0.xyzw = inputColor; - r0.xyzw = cb0[3].xyzw + r0.xyzw; - r0.xyzw = v1.xyzw * r0.xyzw; - o0.xyz = r0.xyz * r0.www; - o0.w = r0.w; - - o0.rgb = pow(saturate(o0.rgb), 2.2f); - o0.rgb *= injectedData.toneMapUINits / 80.f; - return; -} \ No newline at end of file diff --git a/src/games/tunic/final03_0x54E583C8.ps_4_0.hlsl b/src/games/tunic/final03_0x54E583C8.ps_4_0.hlsl deleted file mode 100644 index ac364bbe..00000000 --- a/src/games/tunic/final03_0x54E583C8.ps_4_0.hlsl +++ /dev/null @@ -1,31 +0,0 @@ -#include "./shared.h" - -Texture2D t0 : register(t0); - -SamplerState s0_s : register(s0); - -// 3Dmigoto declarations -#define cmp - - - -void main( - float4 v0 : SV_POSITION0, - float2 v1 : TEXCOORD0, - float4 v2 : COLOR0, - out float4 o0 : SV_Target0) -{ - float4 r0,r1; - uint4 bitmask, uiDest; - float4 fDest; - - r0.xyzw = t0.Sample(s0_s, v1.xy).xyzw; - r1.x = r0.w * v2.w + -0.00999999978; - r0.xyzw = v2.xyzw * r0.xyzw; - o0.xyzw = r0.xyzw; - r0.x = cmp(r1.x < 0); - if (r0.x != 0) discard; - - o0.rgb = pow(saturate(o0.rgb), 2.2f); - o0.rgb *= injectedData.toneMapUINits / 80.f; - return; -} \ No newline at end of file diff --git a/src/games/tunic/final04_0x4AC5CC39.ps_4_0.hlsl b/src/games/tunic/glow_0x4AC5CC39.ps_4_0.hlsl similarity index 71% rename from src/games/tunic/final04_0x4AC5CC39.ps_4_0.hlsl rename to src/games/tunic/glow_0x4AC5CC39.ps_4_0.hlsl index d492095a..c6dc922f 100644 --- a/src/games/tunic/final04_0x4AC5CC39.ps_4_0.hlsl +++ b/src/games/tunic/glow_0x4AC5CC39.ps_4_0.hlsl @@ -25,7 +25,7 @@ cbuffer cb0 : register(b0) { // 3Dmigoto declarations #define cmp - -void main(float4 v0 : SV_POSITION0, float2 v1 : TEXCOORD0, out float4 o0 : SV_Target0) { +void main(float4 v0: SV_POSITION0, float2 v1: TEXCOORD0, out float4 o0: SV_Target0) { float4 r0, r1, r2; uint4 bitmask, uiDest; float4 fDest; @@ -67,22 +67,20 @@ void main(float4 v0 : SV_POSITION0, float2 v1 : TEXCOORD0, out float4 o0 : SV_Ta r0.y = -r0.y * r1.z + 1; r1.y = v1.y; r1.xy = r1.xy * cb0[4].xy + cb0[4].zw; + r1.xyzw = t0.Sample(s0_s, r1.xy).xyzw; - const float4 inputColor = t0.Sample(s0_s, r1.xy).xyzw; + const float3 inputColor = r1.rgb; // Expects the frame buffer to be in gamma - r1.xyzw = inputColor; + r0.xyz = r0.yyy * r1.xyz + r0.xzw; r1.xy = float2(-0.5, -0.5) + v1.xy; r1.xy = r1.xy * r1.xy; r0.w = r1.x + r1.y; r0.w = log2(r0.w); - r0.w = cb2[2].y * r0.w; // cb2[2].y + r0.w = cb2[2].y * r0.w; r0.w = exp2(r0.w); r1.x = saturate(cb2[2].x); - - const float3 colorFilter = cb2[1].xyz; - - r1.xyz = colorFilter * r1.xxx; + r1.xyz = cb2[1].xyz * r1.xxx; r2.xyz = r1.xyz * r0.www + -r0.xyz; r1.w = r1.x * r0.w; r0.xyz = r1.www * r2.xyz + r0.xyz; @@ -91,6 +89,7 @@ void main(float4 v0 : SV_POSITION0, float2 v1 : TEXCOORD0, out float4 o0 : SV_Ta // r1.xyz = saturate(r0.xyz); r1.xyz = r0.xyz; + // r0.w = dot(r1.xyz, float3(0.300000012, 0.589999974, 0.109999999)); r0.w = renodx::color::y::from::BT709(abs(r1.xyz)); r2.xyz = r0.www + -r1.xyz; @@ -105,25 +104,19 @@ void main(float4 v0 : SV_POSITION0, float2 v1 : TEXCOORD0, out float4 o0 : SV_Ta r0.xyz = cb2[8].yyy * r0.xyz + r1.xyz; r0.xyz = cb2[3].yyy + r0.xyz; r0.xyz = -cb2[3].zzz + r0.xyz; - r1.xy = v1.xy * cb0[5].xy + cb0[5].zw; - - float4 t1Color = t1.Sample(s1_s, r1.xy).xyzw; // last frame - r1.xyzw = t1Color; - t1Color *= 80.f / injectedData.toneMapGameNits; // reduce paperwhite sclaing - r1.xyzw = sign(t1Color) * pow(abs(t1Color), 1.f / 2.2f); // Convert raw framebuffer to gamma - r1.xyz = r1.xyz - r0.xyz; // delta - float scaleStrength = saturate(cb2[6].y); // scaler? + // Custom + r0.xyz = lerp(inputColor.rgb, r0.xyz, CUSTOM_SCREEN_GLOW); - o0.xyz = scaleStrength * r1.xyz + r0.xyz; - o0.w = 1; + r1.xy = v1.xy * cb0[5].xy + cb0[5].zw; + r1.xyzw = t1.Sample(s1_s, r1.xy).xyzw; - o0.rgb = lerp(inputColor.rgb, o0.rgb, injectedData.fxScreenGlow); + // r1.xyz = r1.xyz + -r0.xyz; + // r0.w = saturate(cb2[6].y); + // o0.xyz = r0.www * r1.xyz + r0.xyz; - o0.rgb = sign(o0.rgb) * pow(abs(o0.rgb), 2.2f); // linear - o0.rgb *= injectedData.toneMapGameNits / 80.f; + o0.xyz = lerp(r0.xyz, r1.xyz, saturate(cb2[6].y) * CUSTOM_MOTION_BLUR); - // Clamp needed before effects happen after tone mapping... - o0.rgb = min(o0.rgb, injectedData.toneMapPeakNits / 80.f); + o0.w = 1; return; -} \ No newline at end of file +} diff --git a/src/games/tunic/intro_0x1CCE11A3.ps_4_0.hlsl b/src/games/tunic/intro_0x1CCE11A3.ps_4_0.hlsl deleted file mode 100644 index 8d1a4256..00000000 --- a/src/games/tunic/intro_0x1CCE11A3.ps_4_0.hlsl +++ /dev/null @@ -1,37 +0,0 @@ -#include "./shared.h" - -Texture2D t0 : register(t0); - -SamplerState s0_s : register(s0); - -cbuffer cb0 : register(b0) -{ - float4 cb0[4]; -} - -// 3Dmigoto declarations -#define cmp - - - -void main( - float4 v0 : SV_POSITION0, - float2 v1 : TEXCOORD0, - float4 v2 : COLOR0, - uint v3 : SV_IsFrontFace0, - out float4 o0 : SV_Target0) -{ - float4 r0; - uint4 bitmask, uiDest; - float4 fDest; - - r0.xy = v1.xy * cb0[2].xy + cb0[2].zw; - r0.xyzw = t0.Sample(s0_s, r0.xy).xyzw; - r0.xyzw = cb0[3].xyzw * r0.xyzw; - r0.xyzw = v2.xyzw * r0.xyzw; - o0.xyz = r0.xyz * r0.www; - o0.w = 1; - - o0.rgb = pow(saturate(o0.rgb), 2.2f); - o0.rgb *= injectedData.toneMapUINits / 80.f; - return; -} \ No newline at end of file diff --git a/src/games/tunic/lutsample2_0xAA66A0B6.ps_4_0.hlsl b/src/games/tunic/lutsample2_0xAA66A0B6.ps_4_0.hlsl index ede2d481..c2253cdd 100644 --- a/src/games/tunic/lutsample2_0xAA66A0B6.ps_4_0.hlsl +++ b/src/games/tunic/lutsample2_0xAA66A0B6.ps_4_0.hlsl @@ -17,7 +17,7 @@ cbuffer cb0 : register(b0) { // 3Dmigoto declarations #define cmp - -void main(float4 v0 : SV_POSITION0, float4 v1 : TEXCOORD0, float4 v2 : TEXCOORD1, float4 v3 : TEXCOORD2, out float4 o0 : SV_Target0) { +void main(float4 v0: SV_POSITION0, float4 v1: TEXCOORD0, float4 v2: TEXCOORD1, float4 v3: TEXCOORD2, out float4 o0: SV_Target0) { float4 r0, r1, r2; uint4 bitmask, uiDest; float4 fDest; @@ -32,48 +32,36 @@ void main(float4 v0 : SV_POSITION0, float4 v1 : TEXCOORD0, float4 v2 : TEXCOORD1 o0.w = r1.w; // r0.xyz = saturate(r1.xyz * cb0[6].yyy + r0.xyz); - r0.xyz = (r1.xyz * cb0[6].yyy + r0.xyz * injectedData.fxNoise); + r0.xyz = (r1.xyz * cb0[6].yyy + r0.xyz * CUSTOM_NOISE); - float3 untonemapped = r0.rgb; + float3 gamma_input = max(0, r0.rgb); - untonemapped = max(0, renodx::color::srgb::Decode(untonemapped)); - - renodx::tonemap::Config config = renodx::tonemap::config::Create(); - - config.type = injectedData.toneMapType; - config.peak_nits = injectedData.toneMapPeakNits; - config.game_nits = injectedData.toneMapGameNits; - config.exposure = injectedData.colorGradeExposure; - config.highlights = injectedData.colorGradeHighlights; - config.shadows = injectedData.colorGradeShadows; - config.contrast = injectedData.colorGradeContrast; - config.saturation = injectedData.colorGradeSaturation; - config.hue_correction_type = renodx::tonemap::config::hue_correction_type::CUSTOM; - config.hue_correction_color = lerp( - untonemapped, - renodx::tonemap::Reinhard(untonemapped), - injectedData.toneMapHueCorrection); - - config.reno_drt_contrast = 1.1f; - config.reno_drt_saturation = 1.05f; - config.reno_drt_dechroma = injectedData.colorGradeBlowout; + float3 untonemapped = renodx::color::srgb::Decode(gamma_input); renodx::lut::Config lut_config = renodx::lut::config::Create( s1_s, - injectedData.colorGradeLUTStrength, - injectedData.colorGradeLUTScaling, + CUSTOM_LUT_STRENGTH, + CUSTOM_LUT_SCALING, renodx::lut::config::type::SRGB, renodx::lut::config::type::SRGB, 32.f); - if (injectedData.toneMapType == 0.f) { - untonemapped = saturate(untonemapped); + float3 outputColor; + if (RENODX_TONE_MAP_TYPE == 0.f) { + outputColor = renodx::lut::Sample( + saturate(untonemapped), + lut_config, + t1); + } else { + outputColor = renodx::draw::ToneMapPass( + untonemapped, + renodx::lut::Sample( + renodx::tonemap::renodrt::NeutralSDR(untonemapped), + lut_config, + t1)); } - - float3 outputColor = renodx::tonemap::config::Apply(untonemapped, config, lut_config, t1); - - outputColor = sign(outputColor) * pow(abs(outputColor), 1.f / 2.2f); + outputColor = renodx::draw::RenderIntermediatePass(outputColor); o0.rgb = outputColor.rgb; return; diff --git a/src/games/tunic/lutsample_0xEEFE9737.ps_4_0.hlsl b/src/games/tunic/lutsample_0xEEFE9737.ps_4_0.hlsl index 63a07ccc..e7bb18b1 100644 --- a/src/games/tunic/lutsample_0xEEFE9737.ps_4_0.hlsl +++ b/src/games/tunic/lutsample_0xEEFE9737.ps_4_0.hlsl @@ -17,7 +17,7 @@ cbuffer cb0 : register(b0) { // 3Dmigoto declarations #define cmp - -void main(float4 v0 : SV_POSITION0, float4 v1 : TEXCOORD0, float4 v2 : TEXCOORD1, float4 v3 : TEXCOORD2, out float4 o0 : SV_Target0) { +void main(float4 v0: SV_POSITION0, float4 v1: TEXCOORD0, float4 v2: TEXCOORD1, float4 v3: TEXCOORD2, out float4 o0: SV_Target0) { float4 r0, r1, r2; uint4 bitmask, uiDest; float4 fDest; @@ -26,45 +26,35 @@ void main(float4 v0 : SV_POSITION0, float4 v1 : TEXCOORD0, float4 v2 : TEXCOORD1 o0.w = r0.w; r0.xyz = cb0[6].yyy * r0.xyz; // scale - float3 untonemapped = r0.rgb; - - untonemapped = max(0, renodx::color::srgb::Decode(untonemapped)); - - renodx::tonemap::Config config = renodx::tonemap::config::Create(); - - config.type = injectedData.toneMapType; - config.peak_nits = injectedData.toneMapPeakNits; - config.game_nits = injectedData.toneMapGameNits; - config.exposure = injectedData.colorGradeExposure; - config.highlights = injectedData.colorGradeHighlights; - config.shadows = injectedData.colorGradeShadows; - config.contrast = injectedData.colorGradeContrast; - config.saturation = injectedData.colorGradeSaturation; - config.hue_correction_type = renodx::tonemap::config::hue_correction_type::CUSTOM; - config.hue_correction_color = lerp( - untonemapped, - renodx::tonemap::Reinhard(untonemapped), - injectedData.toneMapHueCorrection); - - config.reno_drt_contrast = 1.1f; - config.reno_drt_saturation = 1.05f; - config.reno_drt_dechroma = injectedData.colorGradeBlowout; + + float3 gamma_input = max(0, r0.rgb); + + float3 untonemapped = renodx::color::srgb::Decode(gamma_input); renodx::lut::Config lut_config = renodx::lut::config::Create( s1_s, - injectedData.colorGradeLUTStrength, - injectedData.colorGradeLUTScaling, + CUSTOM_LUT_STRENGTH, + CUSTOM_LUT_SCALING, renodx::lut::config::type::SRGB, renodx::lut::config::type::SRGB, 32.f); - if (injectedData.toneMapType == 0.f) { - untonemapped = saturate(untonemapped); + float3 outputColor; + if (RENODX_TONE_MAP_TYPE == 0.f) { + outputColor = renodx::lut::Sample( + saturate(untonemapped), + lut_config, + t1); + } else { + outputColor = renodx::draw::ToneMapPass( + untonemapped, + renodx::lut::Sample( + renodx::tonemap::renodrt::NeutralSDR(untonemapped), + lut_config, + t1)); } - float3 outputColor = renodx::tonemap::config::Apply(untonemapped, config, lut_config, t1); - - outputColor = sign(outputColor) * pow(abs(outputColor), 1.f / 2.2f); + outputColor = renodx::draw::RenderIntermediatePass(outputColor); o0.rgb = outputColor.rgb; return; diff --git a/src/games/tunic/shared.h b/src/games/tunic/shared.h index c0219394..f17cb7d9 100644 --- a/src/games/tunic/shared.h +++ b/src/games/tunic/shared.h @@ -1,34 +1,65 @@ #ifndef SRC_TUNIC_SHARED_H_ #define SRC_TUNIC_SHARED_H_ -#ifndef __cplusplus -#include "../../shaders/renodx.hlsl" -#endif +#define RENODX_PEAK_WHITE_NITS shader_injection.peak_white_nits +#define RENODX_DIFFUSE_WHITE_NITS shader_injection.diffuse_white_nits +#define RENODX_GRAPHICS_WHITE_NITS shader_injection.graphics_white_nits +#define RENODX_TONE_MAP_TYPE shader_injection.tone_map_type +#define RENODX_TONE_MAP_EXPOSURE shader_injection.tone_map_exposure +#define RENODX_TONE_MAP_HIGHLIGHTS shader_injection.tone_map_highlights +#define RENODX_TONE_MAP_SHADOWS shader_injection.tone_map_shadows +#define RENODX_TONE_MAP_CONTRAST shader_injection.tone_map_contrast +#define RENODX_TONE_MAP_SATURATION shader_injection.tone_map_saturation +#define RENODX_TONE_MAP_HIGHLIGHT_SATURATION shader_injection.tone_map_highlight_saturation +#define RENODX_TONE_MAP_BLOWOUT shader_injection.tone_map_blowout +#define RENODX_TONE_MAP_FLARE shader_injection.tone_map_flare +#define RENODX_TONE_MAP_HUE_CORRECTION shader_injection.tone_map_hue_correction +#define RENODX_TONE_MAP_HUE_SHIFT shader_injection.tone_map_hue_shift +#define RENODX_TONE_MAP_WORKING_COLOR_SPACE shader_injection.tone_map_working_color_space +#define RENODX_TONE_MAP_HUE_PROCESSOR shader_injection.tone_map_hue_processor +#define RENODX_TONE_MAP_PER_CHANNEL shader_injection.tone_map_per_channel +#define RENODX_GAMMA_CORRECTION shader_injection.gamma_correction +#define CUSTOM_LUT_STRENGTH shader_injection.custom_lut_strength +#define CUSTOM_LUT_SCALING shader_injection.custom_lut_scaling +#define CUSTOM_NOISE shader_injection.custom_noise +#define CUSTOM_SCREEN_GLOW shader_injection.custom_screen_glow +#define CUSTOM_MOTION_BLUR shader_injection.custom_motion_blur // Must be 32bit aligned // Should be 4x32 struct ShaderInjectData { - float toneMapType; - float toneMapPeakNits; - float toneMapGameNits; - float toneMapUINits; - float toneMapHueCorrection; - float colorGradeExposure; - float colorGradeHighlights; - float colorGradeShadows; - float colorGradeContrast; - float colorGradeSaturation; - float colorGradeBlowout; - float colorGradeLUTStrength; - float colorGradeLUTScaling; - float fxNoise; - float fxScreenGlow; + float peak_white_nits; + float diffuse_white_nits; + float graphics_white_nits; + float tone_map_type; + float tone_map_exposure; + float tone_map_highlights; + float tone_map_shadows; + float tone_map_contrast; + float tone_map_saturation; + float tone_map_highlight_saturation; + float tone_map_blowout; + float tone_map_flare; + float tone_map_hue_correction; + float tone_map_hue_shift; + float tone_map_working_color_space; + float tone_map_hue_processor; + float tone_map_per_channel; + float gamma_correction; + float custom_lut_scaling; + float custom_lut_strength; + float custom_noise; + float custom_screen_glow; + float custom_motion_blur; }; #ifndef __cplusplus cbuffer cb13 : register(b13) { - ShaderInjectData injectedData : packoffset(c0); + ShaderInjectData shader_injection : packoffset(c0); } + +#include "../../shaders/renodx.hlsl" + #endif #endif // SRC_TUNIC_SHARED_H_ diff --git a/src/games/tunic/swap_chain_proxy_pixel_shader.ps_4_0.hlsl b/src/games/tunic/swap_chain_proxy_pixel_shader.ps_4_0.hlsl new file mode 100644 index 00000000..93e3b603 --- /dev/null +++ b/src/games/tunic/swap_chain_proxy_pixel_shader.ps_4_0.hlsl @@ -0,0 +1,8 @@ +#include "./shared.h" + +Texture2D t0 : register(t0); +SamplerState s0 : register(s0); +float4 main(float4 vpos: SV_POSITION, float2 uv: TEXCOORD0) + : SV_TARGET { + return renodx::draw::SwapChainPass(t0.Sample(s0, uv)); +} diff --git a/src/games/tunic/swap_chain_proxy_vertex_shader.vs_4_0.hlsl b/src/games/tunic/swap_chain_proxy_vertex_shader.vs_4_0.hlsl new file mode 100644 index 00000000..aaee1e17 --- /dev/null +++ b/src/games/tunic/swap_chain_proxy_vertex_shader.vs_4_0.hlsl @@ -0,0 +1,6 @@ +void main(uint id : SV_VERTEXID, out float4 pos : SV_POSITION, + out float2 uv : TEXCOORD0) { + uv.x = (id == 1) ? 2.0 : 0.0; + uv.y = (id == 2) ? 2.0 : 0.0; + pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); +} \ No newline at end of file