From b65856b8a5455e37be96bceebe68892dc437939b Mon Sep 17 00:00:00 2001 From: atdunbg Date: Thu, 24 Sep 2026 13:44:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20ImGui=20=E8=B0=83=E8=AF=95=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=88=86=E7=BB=84=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scene/Rendering/Environment/GPU Timings/Frame 五个 CollapsingHeader; 功能开关用 checkbox 条件显隐联动参数(Bloom 勾选才出现 threshold/ strength),无参数开关横排平铺。 --- App/main.cpp | 230 +++++++++++++++++++++++++++------------------------ 1 file changed, 122 insertions(+), 108 deletions(-) diff --git a/App/main.cpp b/App/main.cpp index 95703f7..27b86b6 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -162,130 +162,144 @@ namespace void OnRenderOverlay() override { ImGui::Begin("Scene Debug"); - - // 阴影光源方向:拖动滑条实时看影子变化 - if (auto* light = m_KeyLight.TryGetComponent()) - { - ImGui::Text("Key Light (shadow caster)"); - ImGui::SliderFloat3("direction", - &light->direction.x, -1.0f, 1.0f); - ImGui::SliderFloat("intensity", &light->color.a, 0.0f, 20.0f); - if (ImGui::Button("reset")) - { - light->direction = glm::vec3(-0.5f, -0.6f, -0.35f); - light->color.a = 2.0f; - } - } - - // Tonemap + Bloom 参数(HDR 后处理输出端) auto& renderer = GetRenderer(); - ImGui::Separator(); - ImGui::Text("Tonemap"); - f32 exposure = renderer.GetExposure(); - if (ImGui::SliderFloat("exposure", &exposure, 0.1f, 4.0f)) - { - renderer.SetExposure(exposure); - } - bool aces = renderer.GetUseACES(); - if (ImGui::Checkbox("ACES", &aces)) - { - renderer.SetUseACES(aces); - } - ImGui::Text("Bloom"); - f32 threshold = renderer.GetBloomThreshold(); - if (ImGui::SliderFloat("threshold", &threshold, 0.0f, 2.0f)) + // ---- Scene:场景内容(灯/动画) ---- + if (ImGui::CollapsingHeader("Scene", ImGuiTreeNodeFlags_DefaultOpen)) { - renderer.SetBloomThreshold(threshold); - } - f32 strength = renderer.GetBloomStrength(); - if (ImGui::SliderFloat("strength", &strength, 0.0f, 2.0f)) - { - renderer.SetBloomStrength(strength); - } - - ImGui::Text("Features"); - bool shadows = renderer.GetShadowsEnabled(); - if (ImGui::Checkbox("Shadows", &shadows)) - { - renderer.SetShadowsEnabled(shadows); - } - bool taa = renderer.GetTAAEnabled(); - if (ImGui::Checkbox("TAA", &taa)) - { - renderer.SetTAAEnabled(taa); - } - bool bloom = renderer.GetBloomEnabled(); - if (ImGui::Checkbox("Bloom", &bloom)) - { - renderer.SetBloomEnabled(bloom); - } - - // 动态环境切换(Assets 层加载 → Renderer 换绑;缓存去重) - ImGui::Separator(); - ImGui::Text("Environment (IBL)"); - int envIdx = m_EnvIndex; - if (ImGui::Combo("env", &envIdx, kEnvNames, kEnvCount)) - { - const auto ref = GetAssets().LoadEnvironment(kEnvPaths[envIdx]); - if (ref.Valid()) + // 阴影光源(无开关,控件平铺聚拢) + if (auto* light = m_KeyLight.TryGetComponent()) { - renderer.SetEnvironment(GetAssets().GetEnvironment(ref)); - m_EnvIndex = envIdx; + ImGui::Text("Key Light (shadow caster)"); + ImGui::SliderFloat3("direction", + &light->direction.x, -1.0f, 1.0f); + ImGui::SliderFloat("intensity", &light->color.a, 0.0f, 20.0f); + if (ImGui::Button("reset")) + { + light->direction = glm::vec3(-0.5f, -0.6f, -0.35f); + light->color.a = 2.0f; + } + } + ImGui::Checkbox("Pause Animation", &m_PauseAnim); + } + + // ---- Rendering:渲染管线参数与开关 ---- + if (ImGui::CollapsingHeader("Rendering", ImGuiTreeNodeFlags_DefaultOpen)) + { + // Tonemap(无开关,平铺) + f32 exposure = renderer.GetExposure(); + if (ImGui::SliderFloat("exposure", &exposure, 0.1f, 4.0f)) + { + renderer.SetExposure(exposure); + } + bool aces = renderer.GetUseACES(); + if (ImGui::Checkbox("ACES", &aces)) + { + renderer.SetUseACES(aces); + } + + // Bloom:开关即显隐——勾上才显示参数 + bool bloom = renderer.GetBloomEnabled(); + if (ImGui::Checkbox("Bloom", &bloom)) + { + renderer.SetBloomEnabled(bloom); + } + if (bloom) + { + f32 threshold = renderer.GetBloomThreshold(); + if (ImGui::SliderFloat("threshold", &threshold, 0.0f, 2.0f)) + { + renderer.SetBloomThreshold(threshold); + } + f32 strength = renderer.GetBloomStrength(); + if (ImGui::SliderFloat("strength", &strength, 0.0f, 2.0f)) + { + renderer.SetBloomStrength(strength); + } + } + + // 无参数的纯开关:横排平铺 + bool shadows = renderer.GetShadowsEnabled(); + if (ImGui::Checkbox("Shadows", &shadows)) + { + renderer.SetShadowsEnabled(shadows); + } + ImGui::SameLine(); + bool taa = renderer.GetTAAEnabled(); + if (ImGui::Checkbox("TAA", &taa)) + { + renderer.SetTAAEnabled(taa); } } - ImGui::Text("(switch = compute pre-integrate, ms-level)"); - // 调试视图:单看某个 pass 的中间输出(类 UE pass debug) - const auto& viewNames = renderer.GetDebugViewNames(); - int view = renderer.GetDebugView(); - if (ImGui::Combo("Debug View", &view, viewNames.data(), - static_cast(viewNames.size()))) + // ---- Environment:IBL 环境 + 调试视图(决定"看什么") ---- + if (ImGui::CollapsingHeader("Environment", ImGuiTreeNodeFlags_DefaultOpen)) { - renderer.SetDebugView(view); - } - ImGui::Checkbox("Pause Animation", &m_PauseAnim); + // 动态环境切换(Assets 层加载 → Renderer 换绑;缓存去重) + ImGui::Text("Environment (IBL)"); + int envIdx = m_EnvIndex; + if (ImGui::Combo("env", &envIdx, kEnvNames, kEnvCount)) + { + const auto ref = GetAssets().LoadEnvironment(kEnvPaths[envIdx]); + if (ref.Valid()) + { + renderer.SetEnvironment(GetAssets().GetEnvironment(ref)); + m_EnvIndex = envIdx; + } + } + ImGui::Text("(switch = compute pre-integrate, ms-level)"); - // Pass 级 GPU 耗时(RG timestamp) - ImGui::Separator(); - ImGui::Text("GPU Timings"); - ImGui::Text("instances: %u main / %u shadow", - renderer.GetMainInstanceCount(), - renderer.GetShadowInstanceCount()); - const auto& names = renderer.GetPassNames(); - const auto& times = renderer.GetPassGpuMs(); - for (size_t i = 0; i < names.size() && i < times.size(); ++i) - { - ImGui::Text(" %-12s %.3f ms", names[i].c_str(), times[i]); + // 调试视图:单看某个 pass 的中间输出(类 UE pass debug) + const auto& viewNames = renderer.GetDebugViewNames(); + int view = renderer.GetDebugView(); + if (ImGui::Combo("Debug View", &view, viewNames.data(), + static_cast(viewNames.size()))) + { + renderer.SetDebugView(view); + } } - // 帧率控制 - auto& app = *this; - ImGui::Separator(); - ImGui::Text("Frame"); - bool vsync = app.GetVSync(); - if (ImGui::Checkbox("VSync", &vsync)) + // ---- GPU Timings:只读遥测(默认折叠,不占面板高度) ---- + if (ImGui::CollapsingHeader("GPU Timings")) { - app.SetVSync(vsync); + // Pass 级 GPU 耗时(RG timestamp) + ImGui::Text("instances: %u main / %u shadow", + renderer.GetMainInstanceCount(), + renderer.GetShadowInstanceCount()); + const auto& names = renderer.GetPassNames(); + const auto& times = renderer.GetPassGpuMs(); + for (size_t i = 0; i < names.size() && i < times.size(); ++i) + { + ImGui::Text(" %-12s %.3f ms", names[i].c_str(), times[i]); + } + } + + // ---- Frame:帧率控制与显示 ---- + if (ImGui::CollapsingHeader("Frame", ImGuiTreeNodeFlags_DefaultOpen)) + { + auto& app = *this; + bool vsync = app.GetVSync(); + if (ImGui::Checkbox("VSync", &vsync)) + { + app.SetVSync(vsync); + if (!vsync) + { + const f32 target = app.GetTargetFps(); + app.SetTargetFps(target); + } + } if (!vsync) { - const f32 target = app.GetTargetFps(); - app.SetTargetFps(target); + f32 target = app.GetTargetFps(); + if (ImGui::SliderFloat("target fps", &target, 24.0f, 360.0f, "%.0f")) + { + app.SetTargetFps(target); + } } + ImGui::Text("fps: %.1f frame: %llu", + 1.0f / GetDeltaTime(), + static_cast(GetFrameCount())); } - if (!vsync) - { - f32 target = app.GetTargetFps(); - if (ImGui::SliderFloat("target fps", &target, 24.0f, 360.0f, "%.0f")) - { - app.SetTargetFps(target); - } - } - - ImGui::Separator(); - ImGui::Text("fps: %.1f frame: %llu", - 1.0f / GetDeltaTime(), - static_cast(GetFrameCount())); ImGui::End();