feat: Shadow pass 接入 RenderGraph,支持 SRT 变换与程序化平面
阴影(本修正的核心根因):
- Shadow pass 光源正交写深度(2048 D32),Forward 采样比较;
写入与采样共用同一 lightSpace 矩阵,杜绝姿态/镜像不一致
- 修复:push constant range 64B→128B(原 Shadow pass 推 {lightVP,model}
超出 layout 声明范围 = UB,阴影中模型矩阵读到垃圾导致旋转错乱)
- 修复:ShadowFactor 缺少 NDC→UV 映射(*0.5+0.5),采样区域整体错位
- 修复:RG ShaderRead stage 位值直转(eFragment=0x10 在 PipelineStage2
是 TESSELLATION_CONTROL),改为逐位显式映射
- Camera perspective 深度重映射到 Vulkan [0,1](公式与 ortho 不同:
M22=M22*0.5-0.5, M32*=0.5);光源 ortho remap 用 M32=M32*0.5+0.5
引擎配套:
- TransformComponent 重构为 position/rotation/scale + Compose()
- Texture::CreateSolidColor / Model::CreatePlane 程序化资产
(两段式上传公共路径),AssetManager.CreatePlane 带缓存入口
- RG 新增 GetPhysicalView(h, slot):按帧槽位把 RG 资源绑进外部描述符
(阴影图 per-slot 物理镜像各自绑定)
验证:validation 0 error 0 warning,阴影随实体旋转正确
This commit is contained in:
+24
-18
@@ -28,7 +28,7 @@ class SandboxApp final : public Application
|
||||
{
|
||||
public:
|
||||
SandboxApp()
|
||||
: Application("HelloVulkan", 1280, 720)
|
||||
: Application("HelloVulkan", 800, 600)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -42,29 +42,39 @@ protected:
|
||||
// 模型资产(AssetManager 负责加载/缓存/生命周期,返回句柄)
|
||||
auto backpack = GetAssets().LoadModel("assets/models/backpack/backpack.obj");
|
||||
|
||||
// 地面:程序化纯色平面(半边长 15,中心 y=-2)
|
||||
auto ground = GetAssets().CreatePlane(15.0f, 140, 140, 145);
|
||||
|
||||
m_Ground = scene.CreateEntity("Ground");
|
||||
m_Ground.AddComponent<TransformComponent>()
|
||||
.SetPosition(glm::vec3(0.0f, -0.5f, 0.0f))
|
||||
.Compose();
|
||||
m_Ground.AddComponent<MeshRendererComponent>(MeshRendererComponent{ground});
|
||||
|
||||
// 相机实体(primary = 当前渲染视角)
|
||||
m_Camera = scene.CreateEntity("MainCamera");
|
||||
auto& camera = m_Camera.AddComponent<CameraComponent>();
|
||||
camera.primary = true;
|
||||
camera.camera.SetPosition(glm::vec3(0.0f, 0.0f, 7.0f));
|
||||
|
||||
// 背包实体 × 3
|
||||
// 背包实体 × 3(悬浮在地面上方)
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
auto e = scene.CreateEntity("Backpack" + std::to_string(i));
|
||||
|
||||
e.AddComponent<TransformComponent>().world = glm::translate(
|
||||
glm::mat4(1.0f),
|
||||
glm::vec3((i - 1) * 1.5f, 0.0f, 0.0f));
|
||||
e.AddComponent<TransformComponent>()
|
||||
.SetPosition(glm::vec3((i - 1) * 1.5f, 0.0f, 0.0f))
|
||||
.SetScale(glm::vec3(0.5f))
|
||||
.Compose();
|
||||
|
||||
e.AddComponent<MeshRendererComponent>(MeshRendererComponent{backpack});
|
||||
|
||||
m_Spinners.push_back(e);
|
||||
}
|
||||
|
||||
// 灯光实体
|
||||
// 灯光实体(第一个灯 = 阴影光源)
|
||||
scene.CreateEntity("KeyLight")
|
||||
.AddComponent<LightComponent>(
|
||||
LightComponent{glm::vec3(-0.5f, -1.0f, -0.3f),
|
||||
LightComponent{glm::vec3(-0.5f, -0.6f, -0.35f),
|
||||
glm::vec4(1.0f, 0.95f, 0.9f, 1.0f)});
|
||||
|
||||
scene.CreateEntity("FillLight")
|
||||
@@ -81,18 +91,13 @@ protected:
|
||||
m_Camera.GetComponent<CameraComponent>()
|
||||
.camera.Update(GetWindow(), deltaTime);
|
||||
|
||||
// 旋转动画:直接写实体组件
|
||||
// 旋转动画:编辑 Transform 分量后 Compose 重算 world
|
||||
for (size_t i = 0; i < m_Spinners.size(); ++i) {
|
||||
f32 angle = m_Time * glm::radians(60.0f) + static_cast<f32>(i) * 0.7f;
|
||||
|
||||
auto& transform = m_Spinners[i].GetComponent<TransformComponent>();
|
||||
glm::mat4 t = glm::translate(
|
||||
glm::mat4(1.0f),
|
||||
glm::vec3((static_cast<f32>(i) - 1.0f) * 1.5f, 0.0f, 0.0f));
|
||||
glm::mat4 r = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
glm::mat4 s = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
|
||||
|
||||
transform.world = t * r * s;
|
||||
auto& t = m_Spinners[i].GetComponent<TransformComponent>();
|
||||
t.position = glm::vec3((static_cast<f32>(i) - 1.0f) * 1.5f, 0.0f, 0.0f);
|
||||
t.rotation.y = m_Time * 60.0f + static_cast<f32>(i) * 40.0f;
|
||||
t.scale = glm::vec3(0.5f);
|
||||
t.Compose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +120,7 @@ protected:
|
||||
|
||||
private:
|
||||
EntityHandle m_Camera{}; // Scene::CreateEntity 之前为空
|
||||
EntityHandle m_Ground{};
|
||||
std::vector<EntityHandle> m_Spinners;
|
||||
f32 m_Time = 0.0f;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user