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:
@@ -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
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <Engine/Renderer/SceneTypes.h>
|
||||
#include <Engine/RenderGraph/RenderGraph.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
@@ -125,7 +126,7 @@ namespace Engine {
|
||||
// ---- RenderGraph 资源句柄 ----
|
||||
RG::TextureHandle m_Backbuffer{};
|
||||
RG::TextureHandle m_Depth{};
|
||||
RG::TextureHandle m_ShadowMap{};
|
||||
std::array<RG::TextureHandle, kMaxCascades> m_ShadowMaps{}; // CSM 级联
|
||||
RG::TextureHandle m_HDRColor{}; // Forward 输出(线性 HDR),TAA 归一
|
||||
RG::TextureHandle m_Velocity{}; // Forward 输出(clip 空间运动向量)
|
||||
RG::TextureHandle m_TAAColor{}; // TAA 累积输出(自引用历史),后处理源
|
||||
|
||||
@@ -45,9 +45,10 @@ namespace Engine {
|
||||
f32 GetCollectMs() const { return m_Frame.collectMs; }
|
||||
|
||||
private:
|
||||
// 阴影光空间矩阵:光源正交投影(覆盖场景,[0,1] 深度重映射)。
|
||||
// 写入(Shadow pass push)与采样(Forward UBO)共用同一矩阵。
|
||||
void ComputeLightSpace(const glm::vec3& shadowDir);
|
||||
// CSM:把相机视锥按实用分割切 N 段,每段独立拟合光源正交投影
|
||||
//(含纹素对齐防阴影边缘闪烁)。写入(Shadow pass push)与采样
|
||||
//(Forward UBO)共用同一组矩阵。
|
||||
void ComputeCascades(const glm::vec3& shadowDir);
|
||||
|
||||
FrameSceneData m_Frame;
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ namespace Engine {
|
||||
|
||||
constexpr u32 kMaxLights = 4;
|
||||
constexpr u32 kMaxInstances = 16384; // 实例 SSBO 容量(矩阵数)
|
||||
constexpr u32 kShadowMapSize = 2048; // 阴影图边长
|
||||
constexpr u32 kMaxCascades = 3; // CSM 级联数
|
||||
constexpr u32 kCascadeRes = 1024; // 每级联阴影图边长
|
||||
|
||||
// 镜像 shader 侧 UBO 布局的灯光项
|
||||
struct LightData {
|
||||
@@ -43,15 +44,16 @@ namespace Engine {
|
||||
};
|
||||
|
||||
// 镜像 simple_shader 的 UBO 布局(std140 语义由 shader 侧对齐)。
|
||||
// 字段只能追加在尾部(shadow.vert 共用本 set 前缀,前插会错位)。
|
||||
// 字段顺序改动必须同步 simple_shader.vert/frag(shadow.vert 只用 SSBO)。
|
||||
struct UniformBufferObject {
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj; // 抖动后的投影(光栅化用)
|
||||
glm::mat4 lightSpace; // 阴影光源 VP(写入与采样共用同一矩阵)
|
||||
glm::mat4 lightSpace[kMaxCascades]; // CSM 各级联光空间 VP([0,1] 重映射)
|
||||
glm::vec4 cascadeSplits; // xyz = 级联 0..2 远边界(视图深度,正值),w 未用
|
||||
glm::vec4 ambientColor;
|
||||
LightData lights[kMaxLights];
|
||||
|
||||
// ---- TAA(尾部追加;velocity 在 vertex 里算)----
|
||||
// ---- TAA(velocity 在 vertex 里算)----
|
||||
glm::mat4 projNoJitter; // 未抖动投影(velocity 当前帧 clip 用)
|
||||
glm::mat4 prevView; // 上一帧视图(velocity)
|
||||
glm::mat4 prevProj; // 上一帧未抖动投影(velocity)
|
||||
|
||||
Reference in New Issue
Block a user