diff --git a/src/games/hoi4/addon.cpp b/src/games/hoi4/addon.cpp new file mode 100644 index 000000000..64a871b4f --- /dev/null +++ b/src/games/hoi4/addon.cpp @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2024 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/settings.hpp" +#include "./shared.h" + +namespace { + +renodx::mods::shader::CustomShaders custom_shaders = { + CustomShaderEntry(0xB99B4F78), + // CustomSwapchainShader(0x00000000), + // BypassShaderEntry(0x00000000) +}; + +ShaderInjectData shader_injection; + +float current_settings_mode = 0; + +renodx::utils::settings::Settings settings = { + new renodx::utils::settings::Setting{ + .key = "SettingsMode", + .binding = ¤t_settings_mode, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .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 = &shader_injection.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 current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapPeakNits", + .binding = &shader_injection.peak_white_nits, + .default_value = 1000.f, + .can_reset = false, + .label = "Peak Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the value of peak white in nits", + .min = 48.f, + .max = 4000.f, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapGameNits", + .binding = &shader_injection.diffuse_white_nits, + .default_value = 203.f, + .label = "Game Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the value of 100% white in nits", + .min = 48.f, + .max = 500.f, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapUINits", + .binding = &shader_injection.graphics_white_nits, + .default_value = 203.f, + .label = "UI Brightness", + .section = "Tone Mapping", + .tooltip = "Sets the brightness of UI and HUD elements in nits", + .min = 48.f, + .max = 500.f, + }, + new renodx::utils::settings::Setting{ + .key = "GammaCorrection", + .binding = &shader_injection.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 current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapScaling", + .binding = &shader_injection.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 shader_injection.tone_map_type >= 1; }, + .is_visible = []() { return current_settings_mode >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapWorkingColorSpace", + .binding = &shader_injection.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 false; }, + .is_visible = []() { return false; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapHueProcessor", + .binding = &shader_injection.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 shader_injection.tone_map_type >= 1; }, + .is_visible = []() { return current_settings_mode >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapHueCorrection", + .binding = &shader_injection.tone_map_hue_correction, + .default_value = 100.f, + .label = "Hue Correction", + .section = "Tone Mapping", + .tooltip = "Hue retention strength.", + .min = 0.f, + .max = 100.f, + .is_enabled = []() { return shader_injection.tone_map_type >= 1; }, + .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return current_settings_mode >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapHueShift", + .binding = &shader_injection.tone_map_hue_shift, + .default_value = 50.f, + .label = "Hue Shift", + .section = "Tone Mapping", + .tooltip = "Hue-shift emulation strength.", + .min = 0.f, + .max = 100.f, + .is_enabled = []() { return shader_injection.tone_map_type >= 1; }, + .parse = [](float value) { return value * 0.01f; }, + .is_visible = []() { return current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapClampColorSpace", + .binding = &shader_injection.tone_map_clamp_color_space, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Clamp Color Space", + .section = "Tone Mapping", + .tooltip = "Hue-shift emulation strength.", + .labels = {"None", "BT709", "BT2020", "AP1"}, + .is_enabled = []() { return shader_injection.tone_map_type >= 1; }, + .parse = [](float value) { return value - 1.f; }, + .is_visible = []() { return current_settings_mode >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ToneMapClampPeak", + .binding = &shader_injection.tone_map_clamp_peak, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Clamp Peak", + .section = "Tone Mapping", + .tooltip = "Hue-shift emulation strength.", + .labels = {"None", "BT709", "BT2020", "AP1"}, + .is_enabled = []() { return shader_injection.tone_map_type >= 1; }, + .parse = [](float value) { return value - 1.f; }, + .is_visible = []() { return current_settings_mode >= 2; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeExposure", + .binding = &shader_injection.tone_map_exposure, + .default_value = 1.f, + .label = "Exposure", + .section = "Color Grading", + .max = 2.f, + .format = "%.2f", + .is_visible = []() { return current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeHighlights", + .binding = &shader_injection.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 current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeShadows", + .binding = &shader_injection.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 current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeContrast", + .binding = &shader_injection.tone_map_contrast, + .default_value = 50.f, + .label = "Contrast", + .section = "Color Grading", + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeSaturation", + .binding = &shader_injection.tone_map_saturation, + .default_value = 50.f, + .label = "Saturation", + .section = "Color Grading", + .max = 100.f, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeHighlightSaturation", + .binding = &shader_injection.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 shader_injection.tone_map_type >= 1; }, + .parse = [](float value) { return value * 0.02f; }, + .is_visible = []() { return current_settings_mode >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeBlowout", + .binding = &shader_injection.tone_map_blowout, + .default_value = 0.f, + .label = "Blowout", + .section = "Color Grading", + .tooltip = "Controls highlight desaturation due to overexposure.", + .max = 100.f, + .parse = [](float value) { return value * 0.01f; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeFlare", + .binding = &shader_injection.tone_map_flare, + .default_value = 0.f, + .label = "Flare", + .section = "Color Grading", + .tooltip = "Flare/Glare Compensation", + .max = 100.f, + .is_enabled = []() { return shader_injection.tone_map_type == 3; }, + .parse = [](float value) { return value * 0.02f; }, + }, + new renodx::utils::settings::Setting{ + .key = "ColorGradeScene", + .binding = &shader_injection.color_grade_strength, + .default_value = 100.f, + .label = "Scene Grading", + .section = "Color Grading", + .tooltip = "Scene grading as applied by the game", + .max = 100.f, + .is_enabled = []() { return shader_injection.tone_map_type > 0; }, + .parse = [](float value) { return value * 0.01f; }, + }, + new renodx::utils::settings::Setting{ + .key = "SwapChainCustomColorSpace", + .binding = &shader_injection.swap_chain_custom_color_space, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Custom Color Space", + .section = "Display Output", + .tooltip = "Selects output color space" + "\nUS Modern for BT.709 D65." + "\nJPN Modern for BT.709 D93." + "\nUS CRT for BT.601 (NTSC-U)." + "\nJPN CRT for BT.601 ARIB-TR-B9 D93 (NTSC-J)." + "\nDefault: US CRT", + .labels = { + "US Modern", + "JPN Modern", + "US CRT", + "JPN CRT", + }, + .is_visible = []() { return settings[0]->GetValue() >= 1; }, + }, + new renodx::utils::settings::Setting{ + .key = "IntermediateDecoding", + .binding = &shader_injection.intermediate_encoding, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Intermediate Encoding", + .section = "Display Output", + .labels = {"Auto", "None", "SRGB", "2.2", "2.4"}, + .is_enabled = []() { return false; }, + .parse = [](float value) { + if (value == 0) return shader_injection.gamma_correction + 1.f; + return value - 1.f; }, + .is_visible = []() { return false; }, + }, + new renodx::utils::settings::Setting{ + .key = "SwapChainDecoding", + .binding = &shader_injection.swap_chain_decoding, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Swapchain Decoding", + .section = "Display Output", + .labels = {"Auto", "None", "SRGB", "2.2", "2.4"}, + .is_enabled = []() { return false; }, + .parse = [](float value) { + if (value == 0) return shader_injection.intermediate_encoding; + return value - 1.f; }, + .is_visible = []() { return false; }, + }, + new renodx::utils::settings::Setting{ + .key = "SwapChainGammaCorrection", + .binding = &shader_injection.swap_chain_gamma_correction, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 0.f, + .label = "Gamma Correction", + .section = "Display Output", + .labels = {"None", "2.2", "2.4"}, + .is_enabled = []() { return false; }, + .is_visible = []() { return false; }, + }, + new renodx::utils::settings::Setting{ + .key = "SwapChainClampColorSpace", + .binding = &shader_injection.swap_chain_clamp_color_space, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 2.f, + .label = "Clamp Color Space", + .section = "Display Output", + .labels = {"None", "BT709", "BT2020", "AP1"}, + .is_enabled = []() { return false; }, + .parse = [](float value) { return value - 1.f; }, + .is_visible = []() { return false; }, + }, +}; + +const std::unordered_map UPGRADE_TARGETS = { + {"R8G8B8A8_TYPELESS", reshade::api::format::r8g8b8a8_typeless}, + {"B8G8R8A8_TYPELESS", reshade::api::format::b8g8r8a8_typeless}, + {"R8G8B8A8_UNORM", reshade::api::format::r8g8b8a8_unorm}, + {"B8G8R8A8_UNORM", reshade::api::format::b8g8r8a8_unorm}, + {"R8G8B8A8_SNORM", reshade::api::format::r8g8b8a8_snorm}, + {"R8G8B8A8_UNORM_SRGB", reshade::api::format::r8g8b8a8_unorm_srgb}, + {"B8G8R8A8_UNORM_SRGB", reshade::api::format::b8g8r8a8_unorm_srgb}, + {"R10G10B10A2_TYPELESS", reshade::api::format::r10g10b10a2_typeless}, + {"R10G10B10A2_UNORM", reshade::api::format::r10g10b10a2_unorm}, + {"B10G10R10A2_UNORM", reshade::api::format::b10g10r10a2_unorm}, + {"R11G11B10_FLOAT", reshade::api::format::r11g11b10_float}, + {"R16G16B16A16_TYPELESS", reshade::api::format::r16g16b16a16_typeless}, +}; + +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("toneMapGammaCorrection", 0); + // 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("colorGradeLUTStrength", 100.f); + // renodx::utils::settings::UpdateSetting("colorGradeLUTScaling", 0.f); +} + +const auto UPGRADE_TYPE_NONE = 0.f; +const auto UPGRADE_TYPE_OUTPUT_SIZE = 1.f; +const auto UPGRADE_TYPE_OUTPUT_RATIO = 2.f; +const auto UPGRADE_TYPE_ANY = 3.f; + +bool initialized = false; + +} // namespace + +extern "C" __declspec(dllexport) constexpr const char* NAME = "RenoDX"; +extern "C" __declspec(dllexport) constexpr const char* DESCRIPTION = "RenoDX (Generic)"; + +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; + + if (!initialized) { + renodx::mods::swapchain::force_borderless = false; + renodx::mods::swapchain::prevent_full_screen = false; + renodx::mods::shader::force_pipeline_cloning = true; + renodx::mods::shader::expected_constant_buffer_space = 50; + renodx::mods::shader::expected_constant_buffer_index = 13; + renodx::mods::shader::allow_multiple_push_constants = true; + + renodx::mods::swapchain::expected_constant_buffer_index = 13; + renodx::mods::swapchain::expected_constant_buffer_space = 50; + renodx::mods::swapchain::use_resource_cloning = true; + + { + auto* setting = new renodx::utils::settings::Setting{ + .key = "SwapChainEncoding", + .binding = &shader_injection.swap_chain_encoding, + .value_type = renodx::utils::settings::SettingValueType::INTEGER, + .default_value = 5.f, + .label = "Encoding", + .section = "Display Output", + .labels = {"None", "SRGB", "2.2", "2.4", "HDR10", "scRGB"}, + .is_enabled = []() { return false; }, + .on_change_value = [](float previous, float current) { + bool is_hdr10 = current == 4; + shader_injection.swap_chain_encoding_color_space = (is_hdr10 ? 1.f : 0.f); + // return void + }, + .is_global = true, + .is_visible = []() { return false; }, + }; + renodx::utils::settings::LoadSetting(renodx::utils::settings::global_name, setting); + bool is_hdr10 = setting->GetValue() == 4; + renodx::mods::swapchain::SetUseHDR10(is_hdr10); + renodx::mods::swapchain::use_resize_buffer = setting->GetValue() < 4; + shader_injection.swap_chain_encoding_color_space = is_hdr10 ? 1.f : 0.f; + settings.push_back(setting); + } + + renodx::utils::settings::useRenoDXHelper = true; + + initialized = true; + } + + break; + case DLL_PROCESS_DETACH: + reshade::unregister_addon(h_module); + 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; +} diff --git a/src/games/hoi4/output_0xB99B4F78.ps_5_0.hlsl b/src/games/hoi4/output_0xB99B4F78.ps_5_0.hlsl new file mode 100644 index 000000000..ca309cfa7 --- /dev/null +++ b/src/games/hoi4/output_0xB99B4F78.ps_5_0.hlsl @@ -0,0 +1,143 @@ +#include "./shared.h" + +// ---- Created with 3Dmigoto v1.4.1 on Wed Sep 24 13:51:42 2025 + +cbuffer dx11_cb1 : register(b1) +{ + float4 HSV : packoffset(c0); + float3 ColorBalance : packoffset(c1); + float EmissiveBloomStrength : packoffset(c1.w); + float2 InvDownSampleSize : packoffset(c2); + float2 InvWindowSize : packoffset(c2.z); + float2 BloomToScreenScale : packoffset(c3); + float BrightThreshold : packoffset(c3.z); + float MiddleGrey : packoffset(c3.w); + float LumWhite2 : packoffset(c4); +} + +SamplerState MainScene_Sampler_s : register(s0); +SamplerState RestoreBloom_Sampler_s : register(s1); +SamplerState ColorCube_Sampler_s : register(s2); +SamplerState AverageLuminanceTexture_Sampler_s : register(s3); +Texture2D MainScene_Texture : register(t0); +Texture2D RestoreBloom_Texture : register(t1); +Texture2D ColorCube_Texture : register(t2); +Texture2D AverageLuminanceTexture_Texture : register(t3); + + +// 3Dmigoto declarations +#define cmp - + + +void main( + float4 v0 : SV_POSITION0, + float2 v1 : TEXCOORD0, + out float4 o0 : SV_TARGET0) +{ + float4 r0,r1,r2,r3; + uint4 bitmask, uiDest; + float4 fDest; + + r0.xyz = MainScene_Texture.SampleLevel(MainScene_Sampler_s, v1.xy, 0).xyz; + r1.xy = BloomToScreenScale.xy * v1.xy; + r1.xyz = RestoreBloom_Texture.SampleLevel(RestoreBloom_Sampler_s, r1.xy, 0).xyz; + r0.xyzw = r1.xyzz + r0.xyzz; + r1.x = AverageLuminanceTexture_Texture.SampleLevel(AverageLuminanceTexture_Sampler_s, float2(0.5,0.5), 0).x; + r1.x = MiddleGrey / r1.x; + r0.xyzw = r1.xxxx * r0.xyzw; + + float3 untonemapped = r0.xyz; + + // Tonemap with Uncharted2 + r1.xyzw = r0.xyww * float4(0.219999999,0.219999999,0.219999999,0.219999999) + float4(0.0300000012,0.0300000012,0.0300000012,0.0300000012); + r1.xyzw = r0.xyww * r1.xyzw + float4(0.00200000009,0.00200000009,0.00200000009,0.00200000009); + r2.xyzw = r0.xyww * float4(0.219999999,0.219999999,0.219999999,0.219999999) + float4(0.300000012,0.300000012,0.300000012,0.300000012); + r0.xyzw = r0.xyzw * r2.xyzw + float4(0.0600000024,0.0600000024,0.0600000024,0.0600000024); + r0.xyzw = r1.xyzw / r0.xyzw; + r0.xyzw = float4(-0.0333333313,-0.0333333313,-0.0333333313,-0.0333333313) + r0.xyzw; + r0.xyzw = float4(1.1530019,1.1530019,1.1530019,1.1530019) * r0.xyzw; + + // Go to 2.2 Gamma + r0.xyzw = log2(r0.xyzw); + r0.xyzw = float4(0.454545468,0.454545468,0.454545468,0.454545468) * r0.xyzw; + r0.xyzw = exp2(r0.xyzw); + r0.xyzw = min(float4(1,1,1,1), r0.xyzw); + + // Sample 2D 16x16x16 LUT + r1.yzw = r0.yxz * float3(0.96875,0.96875,0.96875) + float3(0.015625,0.015625,0.015625); + r0.xy = float2(0.03125,32) * r1.zw; + r0.y = floor(r0.y); + r0.z = 1 + r0.y; + r0.z = min(31, r0.z); + r1.x = r0.y * 0.03125 + r0.x; + r2.xyz = ColorCube_Texture.Sample(ColorCube_Sampler_s, r1.xy).xyz; + r1.x = r0.z * 0.03125 + r0.x; + r1.xyz = ColorCube_Texture.Sample(ColorCube_Sampler_s, r1.xy).xyz; + r0.x = r0.w * 31 + -r0.y; + r0.yzw = r1.yzx + -r2.yzx; + r0.xyz = r0.xxx * r0.yzw + r2.yzx; + + + r0.w = max(r0.x, r0.y); + r1.z = max(r0.z, r0.w); + r0.w = min(r0.x, r0.y); + r0.w = min(r0.z, r0.w); + + r0.w = r1.z + -r0.w; + r1.w = cmp(r0.w != 0.000000); + r2.y = r0.w / r1.z; + r3.xyz = r0.xyz + -r0.yzx; + r3.xyz = r3.xyz / r0.www; + r0.xy = cmp(r0.zx == r1.zz); + r3.xyz = float3(6,2,4) + r3.xyz; + r0.y = r0.y ? r3.y : r3.z; + r2.x = r0.x ? r3.x : r0.y; + r1.xy = r1.ww ? r2.xy : 0; + r0.xy = HSV.zy * r1.zy; + r0.z = cmp(r0.y != 0.000000); + if (r0.z != 0) { + r0.w = HSV.x + r1.x; + r1.x = 6 * r0.w; + r1.x = cmp(r1.x >= -r1.x); + r1.xy = r1.xx ? float2(6,0.166666672) : float2(-6,-0.166666672); + r0.w = r1.y * r0.w; + r0.w = frac(r0.w); + r0.w = r1.x * r0.w; + r0.y = r0.y * r0.x; + r1.x = r0.w + r0.w; + r1.x = cmp(r1.x >= -r1.x); + r1.xy = r1.xx ? float2(2,0.5) : float2(-2,-0.5); + r1.y = r1.y * r0.w; + r1.y = frac(r1.y); + r1.x = r1.x * r1.y + -1; + r2.y = 1 + -abs(r1.x); + r3.xyzw = cmp(r0.wwww < float4(1,2,3,4)); + r0.w = cmp(r0.w < 5); + r2.xz = float2(1,0); + r1.xyw = r0.www ? r2.yzx : r2.xzy; + r1.xyw = r3.www ? r2.zyx : r1.xyw; + r1.xyw = r3.zzz ? r2.zxy : r1.xyw; + r1.xyw = r3.yyy ? r2.yxz : r1.xyw; + r1.xyw = r3.xxx ? r2.xyz : r1.xyw; + r0.w = r1.z * HSV.z + -r0.y; + r1.xyz = saturate(r1.xyw * r0.yyy + r0.www); + } + r0.x = saturate(r0.x); + r0.xyz = r0.zzz ? r1.xyz : r0.xxx; + r0.xyz = saturate(ColorBalance.xyz * r0.xyz); + r0.xyz = float3(-0.0399999991,-0.0399999991,-0.0399999991) + r0.xyz; + r0.xyz = max(float3(0,0,0), r0.xyz); + r0.xyz = float3(1.31578946,1.31578946,1.31578946) * r0.xyz; + o0.xyz = min(float3(1,1,1), r0.xyz); + + float3 graded_sdr = renodx::color::srgb::DecodeSafe(o0.xyz); + if (RENODX_TONE_MAP_TYPE == 0.f) { + o0.rgb = saturate(graded_sdr); + } else { + o0.rgb = renodx::draw::ToneMapPass(untonemapped, graded_sdr); + } + o0.rgb = renodx::draw::RenderIntermediatePass(o0.rgb); + + o0.w = 1; + return; +} \ No newline at end of file diff --git a/src/games/hoi4/shared.h b/src/games/hoi4/shared.h new file mode 100644 index 000000000..d7c1f8f6f --- /dev/null +++ b/src/games/hoi4/shared.h @@ -0,0 +1,121 @@ +#ifndef SRC_TEMPLATE_SHARED_H_ +#define SRC_TEMPLATE_SHARED_H_ + +// #define RENODX_PEAK_WHITE_NITS 1000.f +// #define RENODX_DIFFUSE_WHITE_NITS renodx::color::bt2408::REFERENCE_WHITE +// #define RENODX_GRAPHICS_WHITE_NITS renodx::color::bt2408::GRAPHICS_WHITE +// #define RENODX_COLOR_GRADE_STRENGTH 1.f +// #define RENODX_TONE_MAP_TYPE TONE_MAP_TYPE_RENO_DRT +// #define RENODX_TONE_MAP_EXPOSURE 1.f +// #define RENODX_TONE_MAP_HIGHLIGHTS 1.f +// #define RENODX_TONE_MAP_SHADOWS 1.f +// #define RENODX_TONE_MAP_CONTRAST 1.f +// #define RENODX_TONE_MAP_SATURATION 1.f +// #define RENODX_TONE_MAP_HIGHLIGHT_SATURATION 1.f +// #define RENODX_TONE_MAP_BLOWOUT 0 +// #define RENODX_TONE_MAP_FLARE 0 +// #define RENODX_TONE_MAP_HUE_CORRECTION 1.f +// #define RENODX_TONE_MAP_HUE_SHIFT 0 +// #define RENODX_TONE_MAP_WORKING_COLOR_SPACE color::convert::COLOR_SPACE_BT709 +// #define RENODX_TONE_MAP_CLAMP_COLOR_SPACE color::convert::COLOR_SPACE_NONE +// #define RENODX_TONE_MAP_CLAMP_PEAK color::convert::COLOR_SPACE_BT709 +// #define RENODX_TONE_MAP_HUE_PROCESSOR HUE_PROCESSOR_OKLAB +// #define RENODX_TONE_MAP_PER_CHANNEL 0 +// #define RENODX_GAMMA_CORRECTION GAMMA_CORRECTION_GAMMA_2_2 +// #define RENODX_INTERMEDIATE_SCALING (RENODX_DIFFUSE_WHITE_NITS / RENODX_GRAPHICS_WHITE_NITS) +// #define RENODX_INTERMEDIATE_ENCODING (RENODX_GAMMA_CORRECTION + 1.f) +// #define RENODX_INTERMEDIATE_COLOR_SPACE color::convert::COLOR_SPACE_BT709 +// #define RENODX_SWAP_CHAIN_DECODING RENODX_INTERMEDIATE_ENCODING +// #define RENODX_SWAP_CHAIN_DECODING_COLOR_SPACE RENODX_INTERMEDIATE_COLOR_SPACE +// #define RENODX_SWAP_CHAIN_CUSTOM_COLOR_SPACE COLOR_SPACE_CUSTOM_BT709D65 +// #define RENODX_SWAP_CHAIN_SCALING_NITS RENODX_GRAPHICS_WHITE_NITS +// #define RENODX_SWAP_CHAIN_CLAMP_NITS RENODX_PEAK_WHITE_NITS +// #define RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE color::convert::COLOR_SPACE_UNKNOWN +// #define RENODX_SWAP_CHAIN_ENCODING ENCODING_SCRGB +// #define RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE color::convert::COLOR_SPACE_BT709 + +// Must be 32bit aligned +// Should be 4x32 +struct ShaderInjectData { + float peak_white_nits; + float diffuse_white_nits; + float graphics_white_nits; + float color_grade_strength; + 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_clamp_color_space; + float tone_map_clamp_peak; + float tone_map_hue_processor; + float tone_map_per_channel; + float gamma_correction; + float intermediate_scaling; + float intermediate_encoding; + float intermediate_color_space; + float swap_chain_decoding; + float swap_chain_gamma_correction; + // float swap_chain_decoding_color_space; + float swap_chain_custom_color_space; + // float swap_chain_scaling_nits; + // float swap_chain_clamp_nits; + float swap_chain_clamp_color_space; + float swap_chain_encoding; + float swap_chain_encoding_color_space; +}; + +#ifndef __cplusplus +#if ((__SHADER_TARGET_MAJOR == 5 && __SHADER_TARGET_MINOR >= 1) || __SHADER_TARGET_MAJOR >= 6) +cbuffer shader_injection : register(b13, space50) { +#elif (__SHADER_TARGET_MAJOR < 5) || ((__SHADER_TARGET_MAJOR == 5) && (__SHADER_TARGET_MINOR < 1)) +cbuffer shader_injection : register(b13) { +#endif + ShaderInjectData shader_injection : packoffset(c0); +} + +#define RENODX_TONE_MAP_TYPE shader_injection.tone_map_type +#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_GAMMA_CORRECTION shader_injection.gamma_correction +#define RENODX_TONE_MAP_PER_CHANNEL shader_injection.tone_map_per_channel +#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_HUE_CORRECTION shader_injection.tone_map_hue_correction +#define RENODX_TONE_MAP_HUE_SHIFT shader_injection.tone_map_hue_shift +#define RENODX_TONE_MAP_CLAMP_COLOR_SPACE shader_injection.tone_map_clamp_color_space +#define RENODX_TONE_MAP_CLAMP_PEAK shader_injection.tone_map_clamp_peak +#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_COLOR_GRADE_STRENGTH shader_injection.color_grade_strength +#define RENODX_INTERMEDIATE_ENCODING shader_injection.intermediate_encoding +#define RENODX_SWAP_CHAIN_DECODING shader_injection.swap_chain_decoding +#define RENODX_SWAP_CHAIN_GAMMA_CORRECTION shader_injection.swap_chain_gamma_correction +// #define RENODX_SWAP_CHAIN_DECODING_COLOR_SPACE shader_injection.swap_chain_decoding_color_space +#define RENODX_SWAP_CHAIN_CUSTOM_COLOR_SPACE shader_injection.swap_chain_custom_color_space +// #define RENODX_SWAP_CHAIN_SCALING_NITS shader_injection.swap_chain_scaling_nits +// #define RENODX_SWAP_CHAIN_CLAMP_NITS shader_injection.swap_chain_clamp_nits +#define RENODX_SWAP_CHAIN_CLAMP_COLOR_SPACE shader_injection.swap_chain_clamp_color_space +#define RENODX_SWAP_CHAIN_ENCODING shader_injection.swap_chain_encoding +#define RENODX_SWAP_CHAIN_ENCODING_COLOR_SPACE shader_injection.swap_chain_encoding_color_space +#define RENODX_RENO_DRT_TONE_MAP_METHOD renodx::tonemap::renodrt::config::tone_map_method::REINHARD + +#include "../../shaders/renodx.hlsl" + +#endif + +#endif // SRC_TEMPLATE_SHARED_H_ diff --git a/src/utils/settings.hpp b/src/utils/settings.hpp index 203bb2647..86b96ce09 100644 --- a/src/utils/settings.hpp +++ b/src/utils/settings.hpp @@ -159,6 +159,8 @@ static Settings* settings = nullptr; .format = "%.2f", \ } +bool useRenoDXHelper = false; + static Setting* FindSetting(const std::string& key) { for (auto* setting : *settings) { if (setting->key == key) { @@ -338,6 +340,40 @@ static void WriteGlobalString(const std::string& key, const std::string& value) reshade::set_config_value(nullptr, global_name.c_str(), key.c_str(), value.c_str()); } +static void updateRenoDXHelper(reshade::api::effect_runtime* runtime, float ToneMapUINits = 0) { + auto technique = runtime->find_technique("RenoDXHelper.addonfx", "RenoDXHelper"); + + if (!technique.handle) return; + + if (!useRenoDXHelper) { + runtime->set_technique_state(technique, false); + return; + } + auto variable = runtime->find_uniform_variable("RenoDXHelper.addonfx", "RENODX_UI_NITS"); + if (!variable.handle) return; + runtime->set_technique_state(technique, true); + if (ToneMapUINits <= 0.f) { + auto setting = FindSetting("ToneMapUINits"); + if (setting) { + ToneMapUINits = setting->value; + } else { + return; + } + } + runtime->set_uniform_value_float(variable, ToneMapUINits); +} + +static void OnReshadeBeginEffects( + reshade::api::effect_runtime* runtime, + reshade::api::command_list* cmd_list, + reshade::api::resource_view rtv, + reshade::api::resource_view rtv_srgb +) { + // run once + updateRenoDXHelper(runtime); + reshade::unregister_event(OnReshadeBeginEffects); +} + // Runs first // https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html static void OnRegisterOverlay(reshade::api::effect_runtime* runtime) { @@ -375,6 +411,7 @@ static void OnRegisterOverlay(reshade::api::effect_runtime* runtime) { for (auto& callback : on_preset_changed_callbacks) { callback(); } + updateRenoDXHelper(runtime); } has_drawn_presets = true; }; @@ -580,6 +617,9 @@ static void OnRegisterOverlay(reshade::api::effect_runtime* runtime) { if (changed) { const std::unique_lock lock(renodx::utils::mutex::global_mutex); setting->Write(); + if (useRenoDXHelper && setting->key == "ToneMapUINits") { + updateRenoDXHelper(runtime, setting->value); + } any_change = true; setting->on_change_value(previous_value, setting->GetValue()); } @@ -628,6 +668,7 @@ static void Use(DWORD fdw_reason, Settings* new_settings, void (*new_on_preset_o LoadGlobalSettings(); LoadSettings(global_name + "-preset1"); reshade::register_overlay(overlay_title.c_str(), OnRegisterOverlay); + reshade::register_event(OnReshadeBeginEffects); break; case DLL_PROCESS_DETACH: