From 15d9c944b6ceeac0a45d1b477dc0f05e7f3687fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Thu, 7 Nov 2024 09:26:13 +0100 Subject: [PATCH] added HDR calibration --- .../ScriptingAPI-Documentation.md | 1 + Editor/GraphicsWindow.cpp | 15 ++++++++ Editor/GraphicsWindow.h | 1 + .../shaders/ShaderInterop_Postprocess.h | 2 +- WickedEngine/shaders/tonemapCS.hlsl | 34 +++++++++++-------- WickedEngine/wiRenderPath3D.cpp | 3 +- WickedEngine/wiRenderPath3D.h | 3 ++ WickedEngine/wiRenderPath3D_BindLua.cpp | 16 +++++++++ WickedEngine/wiRenderPath3D_BindLua.h | 1 + WickedEngine/wiRenderPath3D_PathTracing.cpp | 3 +- WickedEngine/wiRenderer.cpp | 14 ++++---- WickedEngine/wiRenderer.h | 3 +- WickedEngine/wiVersion.cpp | 2 +- 13 files changed, 73 insertions(+), 25 deletions(-) diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index cfcda4bfd..9a4ddd5f1 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -1728,6 +1728,7 @@ It inherits functions from RenderPath2D, so it can render a 2D overlay. - SetSharpenFilterEnabled(bool value) - SetSharpenFilterAmount(float value) - SetExposure(float value) +- SetHDRCalibration(float value) - SetOutlineEnabled(bool value) - SetOutlineThreshold(float value) - SetOutlineThickness(float value) diff --git a/Editor/GraphicsWindow.cpp b/Editor/GraphicsWindow.cpp index a445fa0a2..0f0d3d58a 100644 --- a/Editor/GraphicsWindow.cpp +++ b/Editor/GraphicsWindow.cpp @@ -696,6 +696,19 @@ void GraphicsWindow::Create(EditorComponent* _editor) wid = 140; float mod_wid = 60; + hdrcalibrationSlider.Create(0, 8, 1, 100, "HDR calibration: "); + hdrcalibrationSlider.SetTooltip("Set multiplier for HDR output, this only takes effect when swapchain output format is non-SRGB"); + hdrcalibrationSlider.OnSlide([=](wi::gui::EventArgs args) { + editor->renderPath->setHDRCalibration(args.fValue); + editor->main->config.GetSection("graphics").Set("hdr_calibration", args.fValue); + editor->main->config.Commit(); + }); + if (editor->main->config.GetSection("graphics").Has("hdr_calibration")) + { + editor->renderPath->setHDRCalibration(editor->main->config.GetSection("graphics").GetFloat("hdr_calibration")); + } + AddWidget(&hdrcalibrationSlider); + tonemapCombo.Create("Tonemap: "); tonemapCombo.SetTooltip("Choose tone mapping type"); tonemapCombo.SetScriptTip("RenderPath3D::SetTonemap(Tonemap value)"); @@ -1528,6 +1541,7 @@ void GraphicsWindow::Update() ddgiY.SetValue(std::to_string(scene.ddgi.grid_dimensions.y)); ddgiZ.SetValue(std::to_string(scene.ddgi.grid_dimensions.z)); + hdrcalibrationSlider.SetValue(editor->renderPath->getHDRCalibration()); occlusionCullingCheckBox.SetCheck(wi::renderer::GetOcclusionCullingEnabled()); GIBoostSlider.SetValue(wi::renderer::GetGIBoost()); visibilityComputeShadingCheckBox.SetCheck(editor->renderPath->getVisibilityComputeShadingEnabled()); @@ -1674,6 +1688,7 @@ void GraphicsWindow::ResizeLayout() add_right(vsyncCheckBox); add(swapchainComboBox); + add(hdrcalibrationSlider); add(renderPathComboBox); add(resolutionScaleSlider); add(streamingSlider); diff --git a/Editor/GraphicsWindow.h b/Editor/GraphicsWindow.h index b64a90fd9..9cc3ec9b9 100644 --- a/Editor/GraphicsWindow.h +++ b/Editor/GraphicsWindow.h @@ -10,6 +10,7 @@ public: wi::gui::CheckBox vsyncCheckBox; wi::gui::ComboBox swapchainComboBox; + wi::gui::Slider hdrcalibrationSlider; wi::gui::ComboBox renderPathComboBox; wi::gui::Slider pathTraceTargetSlider; wi::gui::Label pathTraceStatisticsLabel; diff --git a/WickedEngine/shaders/ShaderInterop_Postprocess.h b/WickedEngine/shaders/ShaderInterop_Postprocess.h index e1aaefb00..778fcbb83 100644 --- a/WickedEngine/shaders/ShaderInterop_Postprocess.h +++ b/WickedEngine/shaders/ShaderInterop_Postprocess.h @@ -139,7 +139,7 @@ struct PushConstantsTonemap int texture_bloom; int texture_output; int texture_input_distortion_overlay; - uint flags; + uint flags_hdrcalibration; }; struct PostprocessTileStatistics diff --git a/WickedEngine/shaders/tonemapCS.hlsl b/WickedEngine/shaders/tonemapCS.hlsl index 732598794..59021965b 100644 --- a/WickedEngine/shaders/tonemapCS.hlsl +++ b/WickedEngine/shaders/tonemapCS.hlsl @@ -50,11 +50,13 @@ void main(uint3 DTid : SV_DispatchThreadID) if(!GetCamera().is_uv_inside_scissor(uv)) // Note: uv scissoring is used because this supports upscaled resolution (FSR 2) return; - float4 exposure_brightness_contrast_saturation = unpack_half4(tonemap_push.exposure_brightness_contrast_saturation); - float exposure = exposure_brightness_contrast_saturation.x; - float brightness = exposure_brightness_contrast_saturation.y; - float contrast = exposure_brightness_contrast_saturation.z; - float saturation = exposure_brightness_contrast_saturation.w; + half4 exposure_brightness_contrast_saturation = unpack_half4(tonemap_push.exposure_brightness_contrast_saturation); + half exposure = exposure_brightness_contrast_saturation.x; + half brightness = exposure_brightness_contrast_saturation.y; + half contrast = exposure_brightness_contrast_saturation.z; + half saturation = exposure_brightness_contrast_saturation.w; + min16uint flags = tonemap_push.flags_hdrcalibration & 0xFFFF; + half hdr_calibration = f16tof32(tonemap_push.flags_hdrcalibration >> 16u); [branch] if (tonemap_push.texture_input_distortion >= 0) @@ -83,19 +85,19 @@ void main(uint3 DTid : SV_DispatchThreadID) if (tonemap_push.texture_bloom >= 0) { Texture2D texture_bloom = bindless_textures[tonemap_push.texture_bloom]; - float3 bloom = texture_bloom.SampleLevel(sampler_linear_clamp, uv, 1.5f).rgb; - bloom += texture_bloom.SampleLevel(sampler_linear_clamp, uv, 3.5f).rgb; - bloom += texture_bloom.SampleLevel(sampler_linear_clamp, uv, 4.5f).rgb; - bloom /= 3.0f; + half3 bloom = texture_bloom.SampleLevel(sampler_linear_clamp, uv, 1.5).rgb; + bloom += texture_bloom.SampleLevel(sampler_linear_clamp, uv, 3.5).rgb; + bloom += texture_bloom.SampleLevel(sampler_linear_clamp, uv, 4.5).rgb; + bloom /= 3.0; hdr.rgb += bloom; } float4 result = hdr; [branch] - if (tonemap_push.flags & TONEMAP_FLAG_SRGB) + if (flags & TONEMAP_FLAG_SRGB) { - if (tonemap_push.flags & TONEMAP_FLAG_ACES) + if (flags & TONEMAP_FLAG_ACES) { result.rgb = ACESFitted(hdr.rgb); } @@ -105,6 +107,10 @@ void main(uint3 DTid : SV_DispatchThreadID) } result.rgb = ApplySRGBCurve_Fast(result.rgb); } + else + { + result *= hdr_calibration; + } [branch] if (tonemap_push.texture_colorgrade_lookuptable >= 0) @@ -113,13 +119,13 @@ void main(uint3 DTid : SV_DispatchThreadID) } [branch] - if (tonemap_push.flags & TONEMAP_FLAG_DITHER) + if (flags & TONEMAP_FLAG_DITHER) { // dithering before outputting to SDR will reduce color banding: - result.rgb += (dither((float2)DTid.xy) - 0.5f) / 64.0f; + result.rgb += (dither((float2)DTid.xy) - 0.5) / 64.0; } - result.rgb = (result.rgb - 0.5f) * contrast + 0.5f + brightness; + result.rgb = (result.rgb - 0.5) * contrast + 0.5 + brightness; result.rgb = mul(saturationMatrix(saturation), result.rgb); [branch] diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index b13ca6c0c..fdfe9b893 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -2414,7 +2414,8 @@ namespace wi getBloomEnabled() ? &bloomResources.texture_bloom : nullptr, colorspace, getTonemap(), - &distortion_overlay + &distortion_overlay, + getHDRCalibration() ); rt_first = nullptr; diff --git a/WickedEngine/wiRenderPath3D.h b/WickedEngine/wiRenderPath3D.h index f0aabbd1d..f8b892d3b 100644 --- a/WickedEngine/wiRenderPath3D.h +++ b/WickedEngine/wiRenderPath3D.h @@ -57,6 +57,7 @@ namespace wi float reflectionRoughnessCutoff = 0.6f; float ssgiDepthRejection = 8; wi::renderer::Tonemap tonemap = wi::renderer::Tonemap::ACES; + float hdr_calibration = 1; AO ao = AO_DISABLED; bool fxaaEnabled = false; @@ -215,6 +216,7 @@ namespace wi const wi::graphics::Texture* GetGUIBlurredBackground() const override { return &rtGUIBlurredBackground[2]; } constexpr float getExposure() const { return exposure; } + constexpr float getHDRCalibration() const { return hdr_calibration; } constexpr float getBrightness() const { return brightness; } constexpr float getContrast() const { return contrast; } constexpr float getSaturation() const { return saturation; } @@ -270,6 +272,7 @@ namespace wi constexpr bool getVisibilityComputeShadingEnabled() const { return visibility_shading_in_compute; } constexpr void setExposure(float value) { exposure = value; } + constexpr void setHDRCalibration(float value) { hdr_calibration = value; } constexpr void setBrightness(float value) { brightness = value; } constexpr void setContrast(float value) { contrast = value; } constexpr void setSaturation(float value) { saturation = value; } diff --git a/WickedEngine/wiRenderPath3D_BindLua.cpp b/WickedEngine/wiRenderPath3D_BindLua.cpp index 18d71be19..cf1a4ea3f 100644 --- a/WickedEngine/wiRenderPath3D_BindLua.cpp +++ b/WickedEngine/wiRenderPath3D_BindLua.cpp @@ -48,6 +48,7 @@ namespace wi::lua lunamethod(RenderPath3D_BindLua, SetSharpenFilterEnabled), lunamethod(RenderPath3D_BindLua, SetSharpenFilterAmount), lunamethod(RenderPath3D_BindLua, SetExposure), + lunamethod(RenderPath3D_BindLua, SetHDRCalibration), lunamethod(RenderPath3D_BindLua, SetMotionBlurStrength), lunamethod(RenderPath3D_BindLua, SetDepthOfFieldStrength), lunamethod(RenderPath3D_BindLua, SetLightShaftsStrength), @@ -432,6 +433,21 @@ namespace wi::lua wi::lua::SError(L, "SetExposure(float value) not enough arguments!"); return 0; } + int RenderPath3D_BindLua::SetHDRCalibration(lua_State* L) + { + if (component == nullptr) + { + wi::lua::SError(L, "SetHDRCalibration(float value) component is null!"); + return 0; + } + if (wi::lua::SGetArgCount(L) > 0) + { + ((RenderPath3D*)component)->setHDRCalibration(wi::lua::SGetFloat(L, 1)); + } + else + wi::lua::SError(L, "SetHDRCalibration(float value) not enough arguments!"); + return 0; + } int RenderPath3D_BindLua::SetMotionBlurStrength(lua_State* L) { if (component == nullptr) diff --git a/WickedEngine/wiRenderPath3D_BindLua.h b/WickedEngine/wiRenderPath3D_BindLua.h index 84b0d85b1..74100d288 100644 --- a/WickedEngine/wiRenderPath3D_BindLua.h +++ b/WickedEngine/wiRenderPath3D_BindLua.h @@ -54,6 +54,7 @@ namespace wi::lua int SetSharpenFilterEnabled(lua_State* L); int SetSharpenFilterAmount(lua_State* L); int SetExposure(lua_State* L); + int SetHDRCalibration(lua_State* L); int SetMotionBlurStrength(lua_State* L); int SetDepthOfFieldStrength(lua_State* L); int SetLightShaftsStrength(lua_State* L); diff --git a/WickedEngine/wiRenderPath3D_PathTracing.cpp b/WickedEngine/wiRenderPath3D_PathTracing.cpp index 1b397fccf..f61c4b48d 100644 --- a/WickedEngine/wiRenderPath3D_PathTracing.cpp +++ b/WickedEngine/wiRenderPath3D_PathTracing.cpp @@ -603,7 +603,8 @@ namespace wi getBloomEnabled() ? &bloomResources.texture_bloom : nullptr, colorspace, getTonemap(), - &distortion_overlay + &distortion_overlay, + getHDRCalibration() ); lastPostprocessRT = &rtPostprocess; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index d8c241f63..0c794c34c 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -120,7 +120,7 @@ bool variableRateShadingClassification = false; bool variableRateShadingClassificationDebug = false; float GameSpeed = 1; bool debugLightCulling = false; -bool occlusionCulling = false; +bool occlusionCulling = true; bool temporalAA = false; bool temporalAADEBUG = false; uint32_t raytraceBounceCount = 3; @@ -16348,7 +16348,8 @@ void Postprocess_Tonemap( const Texture* texture_bloom, ColorSpace display_colorspace, Tonemap tonemap, - const Texture* texture_distortion_overlay + const Texture* texture_distortion_overlay, + float hdr_calibration ) { if (!input.IsValid() || !output.IsValid()) @@ -16388,19 +16389,20 @@ void Postprocess_Tonemap( tonemap_push.resolution_rcp.y = 1.0f / desc.height; tonemap_push.exposure_brightness_contrast_saturation.x = uint(exposure_brightness_contrast_saturation.v); tonemap_push.exposure_brightness_contrast_saturation.y = uint(exposure_brightness_contrast_saturation.v >> 32ull); - tonemap_push.flags = 0; + tonemap_push.flags_hdrcalibration = 0; if (dither) { - tonemap_push.flags |= TONEMAP_FLAG_DITHER; + tonemap_push.flags_hdrcalibration |= TONEMAP_FLAG_DITHER; } if (tonemap == Tonemap::ACES) { - tonemap_push.flags |= TONEMAP_FLAG_ACES; + tonemap_push.flags_hdrcalibration |= TONEMAP_FLAG_ACES; } if (display_colorspace == ColorSpace::SRGB) { - tonemap_push.flags |= TONEMAP_FLAG_SRGB; + tonemap_push.flags_hdrcalibration |= TONEMAP_FLAG_SRGB; } + tonemap_push.flags_hdrcalibration |= XMConvertFloatToHalf(hdr_calibration) << 16u; tonemap_push.texture_input = device->GetDescriptorIndex(&input, SubresourceType::SRV); tonemap_push.buffer_input_luminance = device->GetDescriptorIndex((buffer_luminance == nullptr) ? &luminance_dummy : buffer_luminance, SubresourceType::SRV); tonemap_push.texture_input_distortion = device->GetDescriptorIndex(texture_distortion, SubresourceType::SRV); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 790b7cb56..ea07ee921 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -829,7 +829,8 @@ namespace wi::renderer const wi::graphics::Texture* texture_bloom = nullptr, wi::graphics::ColorSpace display_colorspace = wi::graphics::ColorSpace::SRGB, Tonemap tonemap = Tonemap::Reinhard, - const wi::graphics::Texture* texture_distortion_overlay = nullptr + const wi::graphics::Texture* texture_distortion_overlay = nullptr, + float hdr_calibration = 1 ); void Postprocess_FSR( const wi::graphics::Texture& input, diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index c707dc3c2..a21e15c3e 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 619; + const int revision = 620; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);