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:
2026-09-24 01:49:11 +08:00
parent 8c0a11d2e8
commit 4d3963e291
8 changed files with 218 additions and 25 deletions
+8 -7
View File
@@ -51,9 +51,11 @@ namespace
// 模型资产(PBR 验证场景:backpack 为旧式贴图资产,
// 退化为电介质因子路径——albedo+normal,metallic=0/roughness=0.5)
const auto model = GetAssets().LoadModel("assets/models/backpack/backpack.obj");
// const auto model = GetAssets().LoadModel("assets/models/pocket_watch_4k.gltf/pocket_watch_4k.gltf");
m_Spinners.push_back(scene.CreateEntity("backpack"));
m_Spinners[0].AddComponent<MeshRendererComponent>(MeshRendererComponent{model});
m_Spinners[0].GetComponent<TransformComponent>().SetScale(glm::vec3{1.0});
// 地面:程序化纯色平面(半边长 15,中心 y=-2)
const auto ground = GetAssets().CreatePlane(15.0f, 140, 140, 145);
@@ -76,7 +78,7 @@ namespace
LightComponent{
.type = LightComponent::Type::Directional,
.direction = glm::vec3(-0.5f, -0.6f, -0.35f),
.color = glm::vec4(1.0f, 0.95f, 0.9f, 1.0f)
.color = glm::vec4(1.0f, 0.95f, 0.9f, 5.0f)
});
scene.CreateEntity("FillLight")
@@ -84,7 +86,7 @@ namespace
LightComponent{
.type = LightComponent::Type::Directional,
.direction = glm::vec3(0.5f, -0.5f, 0.3f),
.color = glm::vec4(0.3f, 0.5f, 1.0f, 0.8f)
.color = glm::vec4(0.3f, 0.5f, 1.0f, 1.5f)
});
// 点光源(位置 = 实体 Transform,出生即有;无阴影,距离衰减)
@@ -93,7 +95,7 @@ namespace
fire.AddComponent<LightComponent>(
LightComponent{
.type = LightComponent::Type::Point,
.color = glm::vec4(1.0f, 0.6f, 0.3f, 2.0f), // 暖橙
.color = glm::vec4(1.0f, 0.6f, 0.3f, 1.0f), // 暖橙
.radius = 8.0f,
});
@@ -127,7 +129,6 @@ namespace
{
auto& t = m_Spinners[i].GetComponent<TransformComponent>();
t.SetRotation(glm::vec3(0.0f, m_Time * 60.0f + static_cast<f32>(i) * 40.0f, 0.0f));
t.SetScale(glm::vec3(0.5f));
}
}
@@ -137,8 +138,6 @@ namespace
void OnRenderOverlay() override
{
ImGui::ShowDemoWindow();
ImGui::Begin("Scene Debug");
// 阴影光源方向:拖动滑条实时看影子变化
@@ -147,9 +146,11 @@ namespace
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;
}
}
@@ -302,7 +303,7 @@ namespace
EntityHandle m_KeyLight{};
std::vector<EntityHandle> m_Spinners;
f32 m_Time = 0.0f;
bool m_PauseAnim = false; // 冻结动画时钟(帧历史 diff 验证用)
bool m_PauseAnim = true; // 冻结动画时钟(帧历史 diff 验证用)
};
}