From 3dd1c10a99cf775bccc313337397d401e3c0bb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Fri, 18 Apr 2025 11:16:45 +0200 Subject: [PATCH] added option to disable shadow LOD override --- .../ScriptingAPI-Documentation.md | 1 + Editor/GraphicsWindow.cpp | 19 ++++++++++++ Editor/GraphicsWindow.h | 1 + WickedEngine/wiRenderer.cpp | 30 +++++++++++++++---- WickedEngine/wiRenderer.h | 2 ++ WickedEngine/wiRenderer_BindLua.cpp | 14 +++++++++ WickedEngine/wiVersion.cpp | 2 +- 7 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index c6d5e229f..741868e58 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -161,6 +161,7 @@ You can use the Renderer with the following functions, all of which are in the g - SetCapsuleShadowEnabled(bool enabled) - SetCapsuleShadowFade(float value) - SetCapsuleShadowAngle(float value) +- SetShadowLODOverrideEnabled(bool value) - SetTemporalAAEnabled(bool value) - SetRaytracedShadowsEnabled(bool value) - SetMeshShaderAllowed(bool enabled) diff --git a/Editor/GraphicsWindow.cpp b/Editor/GraphicsWindow.cpp index 0063f579b..a6f27f681 100644 --- a/Editor/GraphicsWindow.cpp +++ b/Editor/GraphicsWindow.cpp @@ -162,6 +162,21 @@ void GraphicsWindow::Create(EditorComponent* _editor) AddWidget(&meshletOcclusionCullingCheckBox); meshletOcclusionCullingCheckBox.SetEnabled(wi::graphics::GetDevice()->CheckCapability(wi::graphics::GraphicsDeviceCapability::MESH_SHADER)); + shadowLODCheckBox.Create("Shadow LOD override: "); + shadowLODCheckBox.SetTooltip("Enable custom LOD selection for shadow maps.\nThis can cause LOD mismatch between objects in the camera and shadows, but can be a performance benefit."); + shadowLODCheckBox.SetPos(XMFLOAT2(x, y += step)); + shadowLODCheckBox.SetSize(XMFLOAT2(itemheight, itemheight)); + if (editor->main->config.GetSection("graphics").Has("shadow_lod_override")) + { + wi::renderer::SetShadowLODOverrideEnabled(editor->main->config.GetSection("graphics").GetBool("shadow_lod_override")); + } + shadowLODCheckBox.OnClick([=](wi::gui::EventArgs args) { + wi::renderer::SetShadowLODOverrideEnabled(args.bValue); + editor->main->config.GetSection("graphics").Set("shadow_lod_override", args.bValue); + editor->main->config.Commit(); + }); + AddWidget(&shadowLODCheckBox); + GIBoostSlider.Create(1, 10, 1.0f, 1000.0f, "GI Boost: "); GIBoostSlider.SetTooltip("Adjust the strength of GI.\nNote that values other than 1.0 will cause mismatch with path tracing reference!"); GIBoostSlider.SetSize(XMFLOAT2(wid, itemheight)); @@ -1594,6 +1609,7 @@ void GraphicsWindow::Update() visibilityComputeShadingCheckBox.SetCheck(editor->renderPath->getVisibilityComputeShadingEnabled()); meshShaderCheckBox.SetCheck(wi::renderer::IsMeshShaderAllowed()); meshletOcclusionCullingCheckBox.SetCheck(wi::renderer::IsMeshletOcclusionCullingEnabled()); + shadowLODCheckBox.SetCheck(wi::renderer::IsShadowLODOverrideEnabled()); resolutionScaleSlider.SetValue(editor->resolutionScale); streamingSlider.SetValue(wi::resourcemanager::GetStreamingMemoryThreshold()); MSAAComboBox.SetSelectedByUserdataWithoutCallback(editor->renderPath->getMSAASampleCount()); @@ -1762,6 +1778,7 @@ void GraphicsWindow::ResizeLayout() visibilityComputeShadingCheckBox.SetVisible(false); meshShaderCheckBox.SetVisible(false); meshletOcclusionCullingCheckBox.SetVisible(false); + shadowLODCheckBox.SetVisible(false); tessellationCheckBox.SetVisible(false); } else @@ -1780,6 +1797,7 @@ void GraphicsWindow::ResizeLayout() visibilityComputeShadingCheckBox.SetVisible(true); meshShaderCheckBox.SetVisible(true); meshletOcclusionCullingCheckBox.SetVisible(true); + shadowLODCheckBox.SetVisible(true); tessellationCheckBox.SetVisible(true); add(shadowTypeComboBox); @@ -1796,6 +1814,7 @@ void GraphicsWindow::ResizeLayout() add_right(visibilityComputeShadingCheckBox); add_right(meshShaderCheckBox); add_right(meshletOcclusionCullingCheckBox); + add_right(shadowLODCheckBox); add_right(tessellationCheckBox); } diff --git a/Editor/GraphicsWindow.h b/Editor/GraphicsWindow.h index d5b8f45ec..cc5a70663 100644 --- a/Editor/GraphicsWindow.h +++ b/Editor/GraphicsWindow.h @@ -18,6 +18,7 @@ public: wi::gui::CheckBox visibilityComputeShadingCheckBox; wi::gui::CheckBox meshShaderCheckBox; wi::gui::CheckBox meshletOcclusionCullingCheckBox; + wi::gui::CheckBox shadowLODCheckBox; wi::gui::Slider resolutionScaleSlider; wi::gui::Slider streamingSlider; wi::gui::Slider GIBoostSlider; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 4030c4397..e537246ce 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -145,6 +145,7 @@ int VXGI_DEBUG_CLIPMAP = 0; bool CAPSULE_SHADOW_ENABLED = false; float CAPSULE_SHADOW_ANGLE = XM_PIDIV4; float CAPSULE_SHADOW_FADE = 0.2f; +bool SHADOW_LOD_OVERRIDE = true; Texture shadowMapAtlas; Texture shadowMapAtlas_Transparent; @@ -6303,8 +6304,11 @@ void DrawShadowmaps( if ((cascade < (cascade_count - object.cascadeMask)) && shcams[cascade].frustum.CheckBoxFast(aabb)) { camera_mask |= 1 << cascade; - uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], shcams[cascade].view_projection); - shadow_lod = std::min(shadow_lod, candidate_lod); + if (IsShadowLODOverrideEnabled()) + { + uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], shcams[cascade].view_projection); + shadow_lod = std::min(shadow_lod, candidate_lod); + } } } if (camera_mask == 0) @@ -6421,8 +6425,11 @@ void DrawShadowmaps( continue; uint8_t shadow_lod = 0xFF; - uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], shcam.view_projection); - shadow_lod = std::min(shadow_lod, candidate_lod); + if (IsShadowLODOverrideEnabled()) + { + uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], shcam.view_projection); + shadow_lod = std::min(shadow_lod, candidate_lod); + } renderQueue.add(object.mesh_index, uint32_t(i), 0, object.sort_bits, 0xFF, shadow_lod); @@ -6584,8 +6591,11 @@ void DrawShadowmaps( if (frusta[camera_index].CheckBoxFast(aabb)) { camera_mask |= 1 << camera_index; - uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], cameras[camera_index].view_projection); - shadow_lod = std::min(shadow_lod, candidate_lod); + if (IsShadowLODOverrideEnabled()) + { + uint8_t candidate_lod = (uint8_t)vis.scene->ComputeObjectLODForView(object, aabb, vis.scene->meshes[object.mesh_index], cameras[camera_index].view_projection); + shadow_lod = std::min(shadow_lod, candidate_lod); + } } } if (camera_mask == 0) @@ -18521,6 +18531,14 @@ float GetCapsuleShadowFade() { return CAPSULE_SHADOW_FADE; } +void SetShadowLODOverrideEnabled(bool value) +{ + SHADOW_LOD_OVERRIDE = value; +} +bool IsShadowLODOverrideEnabled() +{ + return SHADOW_LOD_OVERRIDE; +} wi::Resource CreatePaintableTexture(uint32_t width, uint32_t height, uint32_t mips, wi::Color initialColor) { diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index a506b8459..59b6494cd 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -1154,6 +1154,8 @@ namespace wi::renderer float GetCapsuleShadowAngle(); void SetCapsuleShadowFade(float value); float GetCapsuleShadowFade(); + void SetShadowLODOverrideEnabled(bool value); // Allow shadowmap rendering to request custom LOD for objects (can result in shadow mismatch, but increased GPU performance) + bool IsShadowLODOverrideEnabled(); // Gets pick ray according to the current screen resolution and pointer coordinates. Can be used as input into RayIntersectWorld() wi::primitive::Ray GetPickRay(long cursorX, long cursorY, const wi::Canvas& canvas, const wi::scene::CameraComponent& camera = wi::scene::GetCamera()); diff --git a/WickedEngine/wiRenderer_BindLua.cpp b/WickedEngine/wiRenderer_BindLua.cpp index 1b25688ac..d27d6ec83 100644 --- a/WickedEngine/wiRenderer_BindLua.cpp +++ b/WickedEngine/wiRenderer_BindLua.cpp @@ -334,6 +334,19 @@ namespace wi::lua::renderer } return 0; } + int SetShadowLODOverrideEnabled(lua_State* L) + { + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + wi::renderer::SetShadowLODOverrideEnabled(wi::lua::SGetBool(L, 1)); + } + else + { + wi::lua::SError(L, "SetShadowLODOverrideEnabled(bool value) not enough arguments!"); + } + return 0; + } int DrawLine(lua_State* L) { @@ -1048,6 +1061,7 @@ namespace wi::lua::renderer wi::lua::RegisterFunc("SetCapsuleShadowEnabled", SetCapsuleShadowEnabled); wi::lua::RegisterFunc("SetCapsuleShadowFade", SetCapsuleShadowFade); wi::lua::RegisterFunc("SetCapsuleShadowAngle", SetCapsuleShadowAngle); + wi::lua::RegisterFunc("SetShadowLODOverrideEnabled", SetShadowLODOverrideEnabled); wi::lua::RegisterFunc("DrawLine", DrawLine); wi::lua::RegisterFunc("DrawPoint", DrawPoint); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 67f0cd80d..c0e21503c 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 = 742; + const int revision = 743; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);