feat: CSM 级联阴影(3 级联 × 1024²,实用分割 + 纹素对齐)

- SceneRenderer::ComputeCascades:相机视锥实用分割(λ=0.6)→ 反投影
  取切片角点 → 光空间 AABB 拟合 → 纹素对齐(消除相机移动时阴影边缘
  闪烁)→ [0,1] 深度重映射
- Shadow pass 单 pass 渲 3 个 region,每级联 push 各自光空间 VP
- Forward:UBO lightSpace[3]+cascadeSplits(视图深度选级联),Set2
  三张级联图按 binding 0/1/2 采样;vertex 输出 fragViewDepth
- 光源视锥剔除用最远级联(覆盖全阴影范围);双视锥独立剔除铁律保留
- 旧单张 2048 全场景图退役;近处级联分辨率 ~128px/unit(约 2× 提升)
- 编译零错误、validation 零警告、8 秒冒烟通过(10 pass 全活跃)
This commit is contained in:
2026-09-23 13:48:43 +08:00
parent 27b7f8785c
commit 0328d4aaeb
13 changed files with 250 additions and 141 deletions
@@ -19,10 +19,11 @@ namespace Engine::Passes {
public:
ForwardPass(SceneGpu& gpu, FrameSceneData& frame,
RG::TextureHandle hdrColor, RG::TextureHandle velocity,
RG::TextureHandle depth, RG::TextureHandle shadowMap)
RG::TextureHandle depth,
const std::array<RG::TextureHandle, kMaxCascades>& shadowMaps)
: m_Gpu(gpu), m_Frame(frame),
m_HDRColor(hdrColor), m_Velocity(velocity),
m_Depth(depth), m_ShadowMap(shadowMap) {}
m_Depth(depth), m_ShadowMaps(shadowMaps) {}
void Register(RG::RenderGraph& rg) override;
@@ -32,7 +33,7 @@ namespace Engine::Passes {
RG::TextureHandle m_HDRColor;
RG::TextureHandle m_Velocity; // TAA 运动向量(第二颜色附件)
RG::TextureHandle m_Depth;
RG::TextureHandle m_ShadowMap;
std::array<RG::TextureHandle, kMaxCascades> m_ShadowMaps;
};
} // namespace Engine::Passes
@@ -12,8 +12,10 @@
#define HELLOVULKAN_SCENEGPU_H
#include <Engine/Core/FrameContext.h>
#include <Engine/Renderer/SceneTypes.h>
#include <Engine/RenderGraph/RenderGraph.h>
#include <vulkan/vulkan.hpp>
#include <array>
#include <vector>
namespace Engine {
@@ -39,7 +41,7 @@ namespace Engine {
// ---- set 布局(shader 契约,改绑定必须同步 shaders/)----
vk::DescriptorSetLayout uboSetLayout; // Set0 = {UBO, ObjectBuffer, PrevObjectBuffer}
vk::DescriptorSetLayout textureSetLayout; // Set1 = {albedo}
vk::DescriptorSetLayout shadowSetLayout; // Set2 = {shadow map}
vk::DescriptorSetLayout shadowSetLayout; // Set2 = {级联 0/1/2 阴影图}
vk::PipelineLayout forwardLayout; // 3 sets,无 push(GPUDriven 经 SSBO)
vk::PipelineLayout shadowLayout; // Set0,push = lightVP 64B
@@ -55,7 +57,8 @@ namespace Engine {
vk::ShaderEXT shadowVert{}, shadowFrag{};
// RG 重编译后重绑阴影图(物理镜像按槽位各一份)
void BindShadowMap(RG::RenderGraph& rg, RG::TextureHandle shadowMap);
void BindShadowMaps(RG::RenderGraph& rg,
const std::array<RG::TextureHandle, kMaxCascades>& maps);
private:
Device& m_Device;
@@ -1,8 +1,9 @@
//
// Created by atdunbg on 2026/9/23.
//
// ShadowPass:光源视角写深度。GPUDriven batch 消费光源视锥剔除结果
// (FrameSceneData::shadowView——相机外实体仍投影子)。
// ShadowPass:CSM 级联阴影。单 pass 渲 kMaxCascades 个 region,
// 每级联独立光源 VP(FrameSceneData::lightSpace[c],SceneRenderer 拟合),
// 消费光源视锥剔除结果(FrameSceneData::shadowView——相机外实体仍投影子)。
//
#ifndef HELLOVULKAN_SHADOWPASS_H
@@ -11,13 +12,15 @@
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/SceneGpu.h>
#include <Engine/Renderer/SceneTypes.h>
#include <array>
namespace Engine::Passes {
class ShadowPass final : public RenderPass {
public:
ShadowPass(SceneGpu& gpu, FrameSceneData& frame, RG::TextureHandle shadowMap)
: m_Gpu(gpu), m_Frame(frame), m_ShadowMap(shadowMap) {}
ShadowPass(SceneGpu& gpu, FrameSceneData& frame,
const std::array<RG::TextureHandle, kMaxCascades>& shadowMaps)
: m_Gpu(gpu), m_Frame(frame), m_ShadowMaps(shadowMaps) {}
void Register(RG::RenderGraph& rg) override;
void OnTargetsRebuilt(RG::RenderGraph& rg) override;
@@ -25,7 +28,7 @@ namespace Engine::Passes {
private:
SceneGpu& m_Gpu;
FrameSceneData& m_Frame;
RG::TextureHandle m_ShadowMap;
std::array<RG::TextureHandle, kMaxCascades> m_ShadowMaps;
};
} // namespace Engine::Passes