From 8dbfb9f5543a96bce8afd085644c7529c7ee0a1c Mon Sep 17 00:00:00 2001 From: atdunbg Date: Fri, 25 Sep 2026 16:39:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20LOD=20=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E5=BC=80=E5=85=B3=EF=BC=88ImGui=20Features=20=E6=A8=AA?= =?UTF-8?q?=E6=8E=92=EF=BC=8C=E5=85=B3=20=3D=20=E5=AE=9E=E4=BE=8B=E6=94=B6?= =?UTF-8?q?=E9=9B=86=E6=81=92=E9=80=89=20LOD0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/main.cpp | 6 ++++++ Engine/include/Engine/Renderer/Renderer.h | 3 ++- Engine/include/Engine/Renderer/SceneRenderer.h | 2 ++ Engine/include/Engine/Renderer/SceneTypes.h | 1 + Engine/src/Renderer/Renderer.cpp | 2 ++ Engine/src/Renderer/SceneRenderer.cpp | 17 ++++++++++------- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/App/main.cpp b/App/main.cpp index e88e314..7ddad89 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -332,6 +332,12 @@ namespace { renderer.SetTAAEnabled(taa); } + ImGui::SameLine(); + bool lod = renderer.GetLodEnabled(); + if (ImGui::Checkbox("LOD", &lod)) + { + renderer.SetLodEnabled(lod); // 关 = 恒绘原网格 + } } // ---- Environment:IBL 环境 + 调试视图(决定"看什么") ---- diff --git a/Engine/include/Engine/Renderer/Renderer.h b/Engine/include/Engine/Renderer/Renderer.h index ec9ce7d..e887173 100644 --- a/Engine/include/Engine/Renderer/Renderer.h +++ b/Engine/include/Engine/Renderer/Renderer.h @@ -92,6 +92,8 @@ namespace Engine { void SetTAAEnabled(bool b); bool GetBloomEnabled() const; void SetBloomEnabled(bool b); + bool GetLodEnabled() const; + void SetLodEnabled(bool b); // 关 = 全部强制 LOD0 int GetDebugView() const; void SetDebugView(int v); // Passes::DebugView 枚举值 // 调试视图名表(下标 = DebugView 枚举值,ImGui combo 直接枚举) @@ -116,7 +118,6 @@ namespace Engine { // 垂直同步开关(present mode 切换会重建 swapchain), // 只应在帧 UI 构建段调用(Render 之前) void SetVSync(bool vsync); - private: void BuildGraph(); // 声明 RG 资源 + 注册 pass 对象 void HandleResize(); diff --git a/Engine/include/Engine/Renderer/SceneRenderer.h b/Engine/include/Engine/Renderer/SceneRenderer.h index 8b38d75..4aafc73 100644 --- a/Engine/include/Engine/Renderer/SceneRenderer.h +++ b/Engine/include/Engine/Renderer/SceneRenderer.h @@ -57,6 +57,7 @@ namespace Engine { void SetShadowsEnabled(bool b) { m_ShadowsEnabled = b; } void SetTAAEnabled(bool b) { m_TAAEnabled = b; } void SetBloomEnabled(bool b) { m_BloomEnabled = b; } + void SetLodEnabled(bool b) { m_LodEnabled = b; } void SetDebugView(int v) { m_DebugView = v; } private: @@ -109,6 +110,7 @@ namespace Engine { bool m_ShadowsEnabled = true; bool m_TAAEnabled = true; bool m_BloomEnabled = true; + bool m_LodEnabled = true; // 关 = 全部强制 LOD0(选级跳过) int m_DebugView = 0; }; diff --git a/Engine/include/Engine/Renderer/SceneTypes.h b/Engine/include/Engine/Renderer/SceneTypes.h index 834f515..4217a62 100644 --- a/Engine/include/Engine/Renderer/SceneTypes.h +++ b/Engine/include/Engine/Renderer/SceneTypes.h @@ -97,6 +97,7 @@ namespace Engine { bool shadowsEnabled = true; // ShadowPass 空转 + frag ShadowFactor 短路 bool taaEnabled = true; // TAAPass 直通(alpha=0) + 停投影抖动 bool bloomEnabled = true; // BloomPass 子 pass 空转 + tonemap 强度归零 + bool lodEnabled = true; // 关 = 实例收集恒选 LOD0(绘制原网格) int debugView = 0; // Passes::DebugView 枚举(tonemap 路由上屏) // 实例预算溢出(kMaxInstances):本轮收集有实例被静默丢弃—— diff --git a/Engine/src/Renderer/Renderer.cpp b/Engine/src/Renderer/Renderer.cpp index d358862..0d80798 100644 --- a/Engine/src/Renderer/Renderer.cpp +++ b/Engine/src/Renderer/Renderer.cpp @@ -186,6 +186,8 @@ namespace Engine return m_SceneRenderer->Frame().bloomEnabled; } void Renderer::SetBloomEnabled(bool b) { m_SceneRenderer->SetBloomEnabled(b); } + bool Renderer::GetLodEnabled() const { return m_SceneRenderer->Frame().lodEnabled; } + void Renderer::SetLodEnabled(bool b) { m_SceneRenderer->SetLodEnabled(b); } int Renderer::GetDebugView() const { return m_SceneRenderer->Frame().debugView; } void Renderer::SetDebugView(int v) { m_SceneRenderer->SetDebugView(v); } diff --git a/Engine/src/Renderer/SceneRenderer.cpp b/Engine/src/Renderer/SceneRenderer.cpp index 00c54df..83c8758 100644 --- a/Engine/src/Renderer/SceneRenderer.cpp +++ b/Engine/src/Renderer/SceneRenderer.cpp @@ -174,6 +174,7 @@ namespace Engine m_Frame.shadowsEnabled = m_ShadowsEnabled; m_Frame.taaEnabled = m_TAAEnabled; m_Frame.bloomEnabled = m_BloomEnabled; + m_Frame.lodEnabled = m_LodEnabled; m_Frame.debugView = m_DebugView; ubo.cascadeSplits.w = m_ShadowsEnabled ? 1.0f : 0.0f; @@ -315,14 +316,16 @@ namespace Engine const f32 worldRadius = bounds.radius * worldScale; // LOD 选级:屏占比近似 = radius/距离(主视图按实例距离; - // 阈值 10/20 倍半径,可调) + // 阈值 10/20 倍半径,可调)。开关关闭 = 恒 LOD0 const f32 dist = glm::length(worldCenter - camTransform->GetPosition()); u32 mainLod = 0; - if (dist >= worldRadius * 20.0f) { - mainLod = 2; - } else if (dist >= worldRadius * 10.0f) { - mainLod = 1; + if (m_LodEnabled) { + if (dist >= worldRadius * 20.0f) { + mainLod = 2; + } else if (dist >= worldRadius * 10.0f) { + mainLod = 1; + } } auto tryAppend = [&](ViewScratch& s, const Frustum& frustum, @@ -361,9 +364,9 @@ namespace Engine for (u32 c = 0; c < kMaxCascades; ++c) { if (!cascVis[c]) continue; // 粗剔除已判不可见 // 级联降级:越远的级联覆盖范围越大,用越低的 LOD - //(阴影本来就是低频信息,误差可接受) + //(阴影本来就是低频信息,误差可接受);开关关闭 = 恒 LOD0 tryAppend(m_CascScratch[c], cascFrustum[c], - std::min(c, kMeshLodCount - 1)); + m_LodEnabled ? std::min(c, kMeshLodCount - 1) : 0u); } } });