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:
@@ -562,6 +562,17 @@ namespace Engine::RG {
|
||||
return img.release();
|
||||
}
|
||||
|
||||
vk::ImageView RenderGraph::GetPhysicalView(TextureHandle h, u32 frameSlot) const
|
||||
{
|
||||
const auto& entry = GetEntry(h);
|
||||
if (entry.imported) return entry.importedView;
|
||||
if (frameSlot >= entry.physical.size() || !entry.physical[frameSlot]) {
|
||||
ENGINE_FATAL("RenderGraph: no physical image for '{}' slot {} "
|
||||
"(compile first?)", entry.name, frameSlot);
|
||||
}
|
||||
return entry.physical[frameSlot]->view;
|
||||
}
|
||||
|
||||
// ---------- 执行 ----------
|
||||
|
||||
void RenderGraph::Execute(const FrameContext& frame)
|
||||
@@ -679,11 +690,28 @@ namespace Engine::RG {
|
||||
case ResourceUse::DepthAttachment:
|
||||
return vk::PipelineStageFlagBits2::eEarlyFragmentTests |
|
||||
vk::PipelineStageFlagBits2::eLateFragmentTests;
|
||||
case ResourceUse::ShaderRead:
|
||||
// ShaderStageFlags 与 PipelineStageFlags2 位值兼容,需显式转换
|
||||
return vk::PipelineStageFlags2(
|
||||
static_cast<VkPipelineStageFlags2>(
|
||||
static_cast<VkShaderStageFlags>(use.readStage)));
|
||||
case ResourceUse::ShaderRead: {
|
||||
// ShaderStageFlags 与 PipelineStageFlags2 位值不同
|
||||
//(eFragment=0x10 vs eFragmentShader=0x80),禁止位值直转,逐位映射
|
||||
vk::PipelineStageFlags2 mapped{};
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eVertex)
|
||||
mapped |= vk::PipelineStageFlagBits2::eVertexShader;
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eFragment)
|
||||
mapped |= vk::PipelineStageFlagBits2::eFragmentShader;
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eCompute)
|
||||
mapped |= vk::PipelineStageFlagBits2::eComputeShader;
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eGeometry)
|
||||
mapped |= vk::PipelineStageFlagBits2::eGeometryShader;
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eTessellationControl)
|
||||
mapped |= vk::PipelineStageFlagBits2::eTessellationControlShader;
|
||||
if (use.readStage & vk::ShaderStageFlagBits::eTessellationEvaluation)
|
||||
mapped |= vk::PipelineStageFlagBits2::eTessellationEvaluationShader;
|
||||
if (!mapped) {
|
||||
ENGINE_FATAL("RenderGraph: ShaderRead stage not mappable: {}",
|
||||
static_cast<u32>(use.readStage));
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
case ResourceUse::TransferSrc:
|
||||
case ResourceUse::TransferDst:
|
||||
return vk::PipelineStageFlagBits2::eTransfer;
|
||||
|
||||
Reference in New Issue
Block a user