fix: 阴影不可见——灯序依赖遍历顺序 + 光比失衡,新增帧截图调试能力
- 灯序修复(根因):entt Each 遍历序不保证创建序,lights[0] 曾落到 点光(params.x=1)→ shader 阴影分支整个跳过。收集后 stable_sort 方向光排前,确立"lights[0] = CSM 阴影光源"契约 - 光比失衡:IBL 环境与点光淹没主光阴影。KeyLight 5.0 + exposure 默认 0.6 + ambientColor 0.07;阴影区环境光同步衰减(简化遮蔽) - ShadowPass depth bias 0.006(acne 均值形态 vs 推过头丢阴影的折中) - Renderer 帧截图能力:第 60 帧自动截 HDRColor/ShadowMap 落 BMP (ACES+gamma 还原屏幕观感),视觉调试自闭环不再依赖肉眼 - KeyLight 增加 intensity slider(0-20 运行时可调)
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
@@ -173,14 +174,18 @@ namespace Engine
|
||||
m_Frame.skyInvVP =
|
||||
glm::inverse(ubo.projNoJitter * glm::mat4(glm::mat3(ubo.view)));
|
||||
|
||||
// ---- 2. 灯光(第一个方向光作为 CSM 阴影光源;点光位置来自 Transform)----
|
||||
u32 lightCount = 0;
|
||||
// ---- 2. 灯光(CSM 阴影光源约定 = lights[0] 必是方向光)----
|
||||
// entt Each 遍历序与实体创建序不保证一致——直接按迭代序填充会让
|
||||
// lights[0] 落到点光上(params.x=1)→ shader 阴影分支整个跳过。
|
||||
// 先收集到临时数组,方向光排前,再写入 UBO
|
||||
glm::vec3 shadowDir{0.0f, -1.0f, 0.0f}; // 无灯兜底:头顶正射
|
||||
LightData collected[kMaxLights];
|
||||
u32 collectedCount = 0;
|
||||
scene.Each<TransformComponent, LightComponent>(
|
||||
[&](Entity, TransformComponent& t, LightComponent& light) {
|
||||
if (lightCount >= kMaxLights) return;
|
||||
if (collectedCount >= kMaxLights) return;
|
||||
|
||||
auto& dst = ubo.lights[lightCount];
|
||||
auto& dst = collected[collectedCount++];
|
||||
dst.color = light.color;
|
||||
dst.params = glm::vec4(
|
||||
light.type == LightComponent::Type::Point ? 1.0f : 0.0f,
|
||||
@@ -195,17 +200,24 @@ namespace Engine
|
||||
dst.direction = glm::vec4(dir, 0.0f);
|
||||
dst.position = glm::vec4(0.0f);
|
||||
}
|
||||
|
||||
// CSM 阴影光源 = 第一个方向光(点光不做级联阴影)
|
||||
if (lightCount == 0 &&
|
||||
light.type == LightComponent::Type::Directional) {
|
||||
shadowDir = glm::length(light.direction) > 0.0f
|
||||
? glm::normalize(light.direction) : shadowDir;
|
||||
}
|
||||
++lightCount;
|
||||
});
|
||||
for (u32 i = lightCount; i < kMaxLights; ++i) {
|
||||
ubo.lights[i] = {};
|
||||
|
||||
// 方向光排前(稳定排序:同类保持收集序)→ lights[0] = CSM 光源
|
||||
std::stable_sort(collected, collected + collectedCount,
|
||||
[](const LightData& a, const LightData& b) {
|
||||
return a.params.x < b.params.x; // 0=方向光 < 1=点光
|
||||
});
|
||||
|
||||
for (u32 i = 0; i < kMaxLights; ++i) {
|
||||
if (i < collectedCount) {
|
||||
ubo.lights[i] = collected[i];
|
||||
} else {
|
||||
ubo.lights[i] = {};
|
||||
}
|
||||
}
|
||||
if (collectedCount > 0 &&
|
||||
collected[0].params.x < 0.5f) {
|
||||
shadowDir = glm::vec3(collected[0].direction);
|
||||
}
|
||||
ComputeCascades(shadowDir);
|
||||
ubo.cameraPos = glm::vec4(camTransform->GetPosition(), 1.0f);
|
||||
|
||||
Reference in New Issue
Block a user