fix: 阴影光源错误绑定 FillLight + 截图 usage 警告 + nodiscard
- LightComponent 增加 castShadow 标志;灯收集排序键改为 castShadow 方向光 > 方向光 > 点光(此前稳定排序把收集序靠前的 FillLight 排到 lights[0],KeyLight 方向滑条自然不影响阴影) - TextureDesc 增加 extraUsage:HDRColor 声明 TRANSFER_SRC, 消除截图 copy 的 3 条 usage 不匹配运行时警告 - waitForFences nodiscard 返回值显式丢弃,消除编译警告
This commit is contained in:
+2
-1
@@ -78,7 +78,8 @@ namespace
|
|||||||
LightComponent{
|
LightComponent{
|
||||||
.type = LightComponent::Type::Directional,
|
.type = LightComponent::Type::Directional,
|
||||||
.direction = glm::vec3(-0.5f, -0.6f, -0.35f),
|
.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")
|
scene.CreateEntity("FillLight")
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ set(IMGUI_SOURCES
|
|||||||
${IMGUI_DIR}/imgui_draw.cpp
|
${IMGUI_DIR}/imgui_draw.cpp
|
||||||
${IMGUI_DIR}/imgui_tables.cpp
|
${IMGUI_DIR}/imgui_tables.cpp
|
||||||
${IMGUI_DIR}/imgui_widgets.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_glfw.cpp
|
||||||
${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp
|
${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -94,11 +94,11 @@ namespace Engine::ECS {
|
|||||||
// Point——位置取实体 Transform(固有的),向四周发光 + 距离衰减
|
// Point——位置取实体 Transform(固有的),向四周发光 + 距离衰减
|
||||||
struct LightComponent {
|
struct LightComponent {
|
||||||
enum class Type : u8 { Directional = 0, Point = 1 };
|
enum class Type : u8 { Directional = 0, Point = 1 };
|
||||||
|
|
||||||
Type type = Type::Directional;
|
Type type = Type::Directional;
|
||||||
glm::vec3 direction{0.0f, -1.0f, 0.0f}; // 仅方向光
|
glm::vec3 direction{0.0f, -1.0f, 0.0f}; // 仅方向光
|
||||||
glm::vec4 color{1.0f, 1.0f, 1.0f, 1.0f}; // rgb = 颜色,a = 强度
|
glm::vec4 color{1.0f, 1.0f, 1.0f, 1.0f}; // rgb = 颜色,a = 强度
|
||||||
f32 radius = 10.0f; // 仅点光:衰减半径
|
f32 radius = 10.0f; // 仅点光:衰减半径
|
||||||
|
bool castShadow = false; // 方向光可投影(引擎取第一个 castShadow 方向光为 CSM 光源)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Engine::ECS
|
} // namespace Engine::ECS
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ namespace Engine::RG {
|
|||||||
u32 width = 0; // 0 = 跟随目标(swapchain)尺寸 × sizeScale
|
u32 width = 0; // 0 = 跟随目标(swapchain)尺寸 × sizeScale
|
||||||
u32 height = 0;
|
u32 height = 0;
|
||||||
f32 sizeScale = 1.0f; // 相对尺寸(后处理降采样用,如 bloom 0.5)
|
f32 sizeScale = 1.0f; // 相对尺寸(后处理降采样用,如 bloom 0.5)
|
||||||
|
// 附加 usage(在 pass 读写推导之外;如调试截图需要 TRANSFER_SRC)
|
||||||
|
vk::ImageUsageFlags extraUsage{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------- 物理镜像 ----------
|
// ---------- 物理镜像 ----------
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Engine {
|
|||||||
|
|
||||||
// 后处理链参数(ImGui 可调;Renderer 持有,pass 按引用读取)
|
// 后处理链参数(ImGui 可调;Renderer 持有,pass 按引用读取)
|
||||||
struct PostProcessParams {
|
struct PostProcessParams {
|
||||||
f32 exposure = 1.0f;
|
f32 exposure = 0.6f;
|
||||||
bool useACES = true;
|
bool useACES = true;
|
||||||
f32 bloomThreshold = 1.0f; // HDR 域亮度阈值
|
f32 bloomThreshold = 1.0f; // HDR 域亮度阈值
|
||||||
f32 bloomStrength = 0.8f; // 叠加强度
|
f32 bloomStrength = 0.8f; // 叠加强度
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ namespace Engine {
|
|||||||
void BuildGraph(); // 声明 RG 资源 + 注册 pass 对象
|
void BuildGraph(); // 声明 RG 资源 + 注册 pass 对象
|
||||||
void HandleResize();
|
void HandleResize();
|
||||||
void ReadGpuTimes(u32 frameSlot);
|
void ReadGpuTimes(u32 frameSlot);
|
||||||
|
void CaptureFrame(); // 调试截图(一次性,写 capture.bmp)
|
||||||
|
|
||||||
Window& m_Window;
|
Window& m_Window;
|
||||||
|
|
||||||
@@ -154,6 +155,11 @@ namespace Engine {
|
|||||||
|
|
||||||
vk::Extent2D m_Extent{};
|
vk::Extent2D m_Extent{};
|
||||||
u32 m_CurrentFrame = 0;
|
u32 m_CurrentFrame = 0;
|
||||||
|
|
||||||
|
// 调试截图(一次性):第 60 帧把 TAAColor(HDR)落成 capture.bmp
|
||||||
|
u32 m_FrameCounter = 0;
|
||||||
|
bool m_Captured = false;
|
||||||
|
MemoryAllocator::Allocation m_CaptureAlloc{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Engine
|
} // namespace Engine
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ namespace Engine::RG {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry.usage = usage;
|
entry.usage = usage | entry.desc.extraUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderGraph::CullPasses()
|
void RenderGraph::CullPasses()
|
||||||
|
|||||||
@@ -290,9 +290,11 @@ namespace Engine
|
|||||||
|
|
||||||
// HDR 颜色图:Forward 的输出(线性光照值 + 抖动),TAA 显式完成
|
// HDR 颜色图:Forward 的输出(线性光照值 + 抖动),TAA 显式完成
|
||||||
// 时域累积后写入 TAAColor(对齐 UE/Unity 管线)
|
// 时域累积后写入 TAAColor(对齐 UE/Unity 管线)
|
||||||
|
// extraUsage:调试截图需要 TRANSFER_SRC(第 60 帧 copy 到 buffer)
|
||||||
m_HDRColor = m_RenderGraph->CreateTexture(
|
m_HDRColor = m_RenderGraph->CreateTexture(
|
||||||
"HDRColor",
|
"HDRColor",
|
||||||
RG::TextureDesc{vk::Format::eR16G16B16A16Sfloat});
|
RG::TextureDesc{vk::Format::eR16G16B16A16Sfloat, 0, 0, 1.0f,
|
||||||
|
vk::ImageUsageFlagBits::eTransferSrc});
|
||||||
|
|
||||||
// velocity:clip 空间运动向量(TAA 反推历史像素位置)
|
// velocity:clip 空间运动向量(TAA 反推历史像素位置)
|
||||||
m_Velocity = m_RenderGraph->CreateTexture(
|
m_Velocity = m_RenderGraph->CreateTexture(
|
||||||
@@ -577,7 +579,8 @@ namespace Engine
|
|||||||
|
|
||||||
// 调试截图落盘:等 fence(copy 已提交完成)→ fp16 → BMP
|
// 调试截图落盘:等 fence(copy 已提交完成)→ fp16 → BMP
|
||||||
if (doCapture) {
|
if (doCapture) {
|
||||||
m_Device->GetDevice().waitForFences(
|
// 诊断截图落盘:等 fence(copy 已提交完成)→ BMP(返回值仅超时标志)
|
||||||
|
(void)m_Device->GetDevice().waitForFences(
|
||||||
m_SyncManager->GetFrameFence(frameSlot), VK_TRUE,
|
m_SyncManager->GetFrameFence(frameSlot), VK_TRUE,
|
||||||
UINT64_MAX);
|
UINT64_MAX);
|
||||||
WriteHdrBMP("capture.bmp", m_CaptureAlloc.MappedPtr,
|
WriteHdrBMP("capture.bmp", m_CaptureAlloc.MappedPtr,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace Engine
|
namespace Engine
|
||||||
{
|
{
|
||||||
@@ -180,6 +179,7 @@ namespace Engine
|
|||||||
// 先收集到临时数组,方向光排前,再写入 UBO
|
// 先收集到临时数组,方向光排前,再写入 UBO
|
||||||
glm::vec3 shadowDir{0.0f, -1.0f, 0.0f}; // 无灯兜底:头顶正射
|
glm::vec3 shadowDir{0.0f, -1.0f, 0.0f}; // 无灯兜底:头顶正射
|
||||||
LightData collected[kMaxLights];
|
LightData collected[kMaxLights];
|
||||||
|
f32 shadowKey[kMaxLights]; // 排序键:0=castShadow 方向光 1=方向光 2=点光
|
||||||
u32 collectedCount = 0;
|
u32 collectedCount = 0;
|
||||||
scene.Each<TransformComponent, LightComponent>(
|
scene.Each<TransformComponent, LightComponent>(
|
||||||
[&](Entity, TransformComponent& t, LightComponent& light) {
|
[&](Entity, TransformComponent& t, LightComponent& light) {
|
||||||
@@ -190,6 +190,12 @@ namespace Engine
|
|||||||
dst.params = glm::vec4(
|
dst.params = glm::vec4(
|
||||||
light.type == LightComponent::Type::Point ? 1.0f : 0.0f,
|
light.type == LightComponent::Type::Point ? 1.0f : 0.0f,
|
||||||
light.radius, 0.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) {
|
if (light.type == LightComponent::Type::Point) {
|
||||||
dst.position = glm::vec4(t.GetPosition(), 1.0f);
|
dst.position = glm::vec4(t.GetPosition(), 1.0f);
|
||||||
@@ -202,11 +208,20 @@ namespace Engine
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 方向光排前(稳定排序:同类保持收集序)→ lights[0] = CSM 光源
|
// 排序(稳定):castShadow 方向光 → 方向光 → 点光
|
||||||
std::stable_sort(collected, collected + collectedCount,
|
// 同时排序 shadowKey 保持键值对应
|
||||||
[](const LightData& a, const LightData& b) {
|
for (u32 i = 1; i < collectedCount; ++i) { // 插入排序(n≤4)
|
||||||
return a.params.x < b.params.x; // 0=方向光 < 1=点光
|
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) {
|
for (u32 i = 0; i < kMaxLights; ++i) {
|
||||||
if (i < collectedCount) {
|
if (i < collectedCount) {
|
||||||
|
|||||||
Reference in New Issue
Block a user