From 42fd9d5f308f8094f51a06913ec37a3cb94b3697 Mon Sep 17 00:00:00 2001 From: atdunbg Date: Thu, 24 Sep 2026 11:59:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=98=B4=E5=BD=B1=E5=85=89=E6=BA=90?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=BB=91=E5=AE=9A=20FillLight=20+=20?= =?UTF-8?q?=E6=88=AA=E5=9B=BE=20usage=20=E8=AD=A6=E5=91=8A=20+=20nodiscard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LightComponent 增加 castShadow 标志;灯收集排序键改为 castShadow 方向光 > 方向光 > 点光(此前稳定排序把收集序靠前的 FillLight 排到 lights[0],KeyLight 方向滑条自然不影响阴影) - TextureDesc 增加 extraUsage:HDRColor 声明 TRANSFER_SRC, 消除截图 copy 的 3 条 usage 不匹配运行时警告 - waitForFences nodiscard 返回值显式丢弃,消除编译警告 --- App/main.cpp | 3 ++- Engine/CMakeLists.txt | 2 +- Engine/include/Engine/ECS/Components.h | 2 +- .../include/Engine/RenderGraph/RenderGraph.h | 2 ++ .../Engine/Renderer/Passes/FullscreenGpu.h | 2 +- Engine/include/Engine/Renderer/Renderer.h | 6 +++++ Engine/src/RenderGraph/RenderGraph.cpp | 2 +- Engine/src/Renderer/Renderer.cpp | 7 +++-- Engine/src/Renderer/SceneRenderer.cpp | 27 ++++++++++++++----- 9 files changed, 40 insertions(+), 13 deletions(-) diff --git a/App/main.cpp b/App/main.cpp index 9fe1acf..3d1a2c3 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -78,7 +78,8 @@ namespace LightComponent{ .type = LightComponent::Type::Directional, .direction = glm::vec3(-0.5f, -0.6f, -0.35f), - .color = glm::vec4(1.0f, 0.95f, 0.9f, 5.0f) + .color = glm::vec4(1.0f, 0.95f, 0.9f, 5.0f), + .castShadow = true, }); scene.CreateEntity("FillLight") diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index 3f04a00..1166d92 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -9,7 +9,7 @@ set(IMGUI_SOURCES ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp - ${IMGUI_DIR}/imgui_demo.cpp # ShowDemoWindow 的实现(调试期保留) + # ${IMGUI_DIR}/imgui_demo.cpp # ShowDemoWindow 的实现(调试期保留) ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ) diff --git a/Engine/include/Engine/ECS/Components.h b/Engine/include/Engine/ECS/Components.h index a7f3864..93cedb0 100644 --- a/Engine/include/Engine/ECS/Components.h +++ b/Engine/include/Engine/ECS/Components.h @@ -94,11 +94,11 @@ namespace Engine::ECS { // Point——位置取实体 Transform(固有的),向四周发光 + 距离衰减 struct LightComponent { enum class Type : u8 { Directional = 0, Point = 1 }; - Type type = Type::Directional; glm::vec3 direction{0.0f, -1.0f, 0.0f}; // 仅方向光 glm::vec4 color{1.0f, 1.0f, 1.0f, 1.0f}; // rgb = 颜色,a = 强度 f32 radius = 10.0f; // 仅点光:衰减半径 + bool castShadow = false; // 方向光可投影(引擎取第一个 castShadow 方向光为 CSM 光源) }; } // namespace Engine::ECS diff --git a/Engine/include/Engine/RenderGraph/RenderGraph.h b/Engine/include/Engine/RenderGraph/RenderGraph.h index 934af56..8f41ebc 100644 --- a/Engine/include/Engine/RenderGraph/RenderGraph.h +++ b/Engine/include/Engine/RenderGraph/RenderGraph.h @@ -72,6 +72,8 @@ namespace Engine::RG { u32 width = 0; // 0 = 跟随目标(swapchain)尺寸 × sizeScale u32 height = 0; f32 sizeScale = 1.0f; // 相对尺寸(后处理降采样用,如 bloom 0.5) + // 附加 usage(在 pass 读写推导之外;如调试截图需要 TRANSFER_SRC) + vk::ImageUsageFlags extraUsage{}; }; // ---------- 物理镜像 ---------- diff --git a/Engine/include/Engine/Renderer/Passes/FullscreenGpu.h b/Engine/include/Engine/Renderer/Passes/FullscreenGpu.h index 339f516..1529b58 100644 --- a/Engine/include/Engine/Renderer/Passes/FullscreenGpu.h +++ b/Engine/include/Engine/Renderer/Passes/FullscreenGpu.h @@ -33,7 +33,7 @@ namespace Engine { // 后处理链参数(ImGui 可调;Renderer 持有,pass 按引用读取) struct PostProcessParams { - f32 exposure = 1.0f; + f32 exposure = 0.6f; bool useACES = true; f32 bloomThreshold = 1.0f; // HDR 域亮度阈值 f32 bloomStrength = 0.8f; // 叠加强度 diff --git a/Engine/include/Engine/Renderer/Renderer.h b/Engine/include/Engine/Renderer/Renderer.h index 3ef25c0..a112f99 100644 --- a/Engine/include/Engine/Renderer/Renderer.h +++ b/Engine/include/Engine/Renderer/Renderer.h @@ -101,6 +101,7 @@ namespace Engine { void BuildGraph(); // 声明 RG 资源 + 注册 pass 对象 void HandleResize(); void ReadGpuTimes(u32 frameSlot); + void CaptureFrame(); // 调试截图(一次性,写 capture.bmp) Window& m_Window; @@ -154,6 +155,11 @@ namespace Engine { vk::Extent2D m_Extent{}; u32 m_CurrentFrame = 0; + + // 调试截图(一次性):第 60 帧把 TAAColor(HDR)落成 capture.bmp + u32 m_FrameCounter = 0; + bool m_Captured = false; + MemoryAllocator::Allocation m_CaptureAlloc{}; }; } // namespace Engine diff --git a/Engine/src/RenderGraph/RenderGraph.cpp b/Engine/src/RenderGraph/RenderGraph.cpp index 99ee192..3ae37dd 100644 --- a/Engine/src/RenderGraph/RenderGraph.cpp +++ b/Engine/src/RenderGraph/RenderGraph.cpp @@ -260,7 +260,7 @@ namespace Engine::RG { } } } - entry.usage = usage; + entry.usage = usage | entry.desc.extraUsage; } void RenderGraph::CullPasses() diff --git a/Engine/src/Renderer/Renderer.cpp b/Engine/src/Renderer/Renderer.cpp index c6a7731..d7f1042 100644 --- a/Engine/src/Renderer/Renderer.cpp +++ b/Engine/src/Renderer/Renderer.cpp @@ -290,9 +290,11 @@ namespace Engine // HDR 颜色图:Forward 的输出(线性光照值 + 抖动),TAA 显式完成 // 时域累积后写入 TAAColor(对齐 UE/Unity 管线) + // extraUsage:调试截图需要 TRANSFER_SRC(第 60 帧 copy 到 buffer) m_HDRColor = m_RenderGraph->CreateTexture( "HDRColor", - RG::TextureDesc{vk::Format::eR16G16B16A16Sfloat}); + RG::TextureDesc{vk::Format::eR16G16B16A16Sfloat, 0, 0, 1.0f, + vk::ImageUsageFlagBits::eTransferSrc}); // velocity:clip 空间运动向量(TAA 反推历史像素位置) m_Velocity = m_RenderGraph->CreateTexture( @@ -577,7 +579,8 @@ namespace Engine // 调试截图落盘:等 fence(copy 已提交完成)→ fp16 → BMP if (doCapture) { - m_Device->GetDevice().waitForFences( + // 诊断截图落盘:等 fence(copy 已提交完成)→ BMP(返回值仅超时标志) + (void)m_Device->GetDevice().waitForFences( m_SyncManager->GetFrameFence(frameSlot), VK_TRUE, UINT64_MAX); WriteHdrBMP("capture.bmp", m_CaptureAlloc.MappedPtr, diff --git a/Engine/src/Renderer/SceneRenderer.cpp b/Engine/src/Renderer/SceneRenderer.cpp index 2967037..f116d12 100644 --- a/Engine/src/Renderer/SceneRenderer.cpp +++ b/Engine/src/Renderer/SceneRenderer.cpp @@ -19,7 +19,6 @@ #include #include -#include namespace Engine { @@ -180,6 +179,7 @@ namespace Engine // 先收集到临时数组,方向光排前,再写入 UBO glm::vec3 shadowDir{0.0f, -1.0f, 0.0f}; // 无灯兜底:头顶正射 LightData collected[kMaxLights]; + f32 shadowKey[kMaxLights]; // 排序键:0=castShadow 方向光 1=方向光 2=点光 u32 collectedCount = 0; scene.Each( [&](Entity, TransformComponent& t, LightComponent& light) { @@ -190,6 +190,12 @@ namespace Engine dst.params = glm::vec4( light.type == LightComponent::Type::Point ? 1.0f : 0.0f, light.radius, 0.0f, 0.0f); + // 排序键:castShadow 方向光最优先(CSM 阴影光源契约),其余按类型 + shadowKey[collectedCount - 1] = + (light.type == LightComponent::Type::Directional && + light.castShadow) ? 0.0f + : (light.type == LightComponent::Type::Directional ? 1.0f + : 2.0f); if (light.type == LightComponent::Type::Point) { dst.position = glm::vec4(t.GetPosition(), 1.0f); @@ -202,11 +208,20 @@ namespace Engine } }); - // 方向光排前(稳定排序:同类保持收集序)→ lights[0] = CSM 光源 - std::stable_sort(collected, collected + collectedCount, - [](const LightData& a, const LightData& b) { - return a.params.x < b.params.x; // 0=方向光 < 1=点光 - }); + // 排序(稳定):castShadow 方向光 → 方向光 → 点光 + // 同时排序 shadowKey 保持键值对应 + for (u32 i = 1; i < collectedCount; ++i) { // 插入排序(n≤4) + LightData ld = collected[i]; + f32 key = shadowKey[i]; + u32 j = i; + while (j > 0 && shadowKey[j - 1] > key) { + collected[j] = collected[j - 1]; + shadowKey[j] = shadowKey[j - 1]; + --j; + } + collected[j] = ld; + shadowKey[j] = key; + } for (u32 i = 0; i < kMaxLights; ++i) { if (i < collectedCount) {