feat: 特性开关 + Pass 调试视图接口(ImGui 可控,统一帧契约)

三个运行时开关(Shadows/TAA/Bloom)与 9 种调试视图(Final/
TemporalDiff/HDR/TAAColor/Bloom/Velocity/ShadowMap0-2)。

统一设计:开关状态收敛 FrameSceneData 契约,SceneRenderer 唯一
写入、各 pass 只读(零虚接口路由);调试视图经 tonemap push
int 路由已绑定的中间目标(声明超集、运行时零重绑);HDR 域
资源过同一 tonemap 保证观感可比。

- Shadows:ShadowPass lambda 空转 + frag cascadeSplits.w 短路
- TAA:alpha=0 直通 + SceneRenderer 停投影抖动(同一持有者同步)
- Bloom:3 子 pass 空转 + tonemap 强度归零
- Renderer 门面 Get/Set 转发,App ImGui 3 Checkbox + Combo
- PostProcessParams 瘦身为纯数值参数,showTemporalDiff 被取缔
This commit is contained in:
2026-09-24 13:03:00 +08:00
parent 708d714459
commit a1c6ad20be
17 changed files with 271 additions and 66 deletions
@@ -11,6 +11,7 @@
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/FullscreenGpu.h>
#include <Engine/Renderer/SceneTypes.h>
#include <vulkan/vulkan.hpp>
#include <vector>
@@ -19,6 +20,7 @@ namespace Engine::Passes {
class BloomPass final : public RenderPass {
public:
BloomPass(FullscreenGpu& gpu, PostProcessParams& params,
FrameSceneData& frame,
RG::TextureHandle hdrColor,
RG::TextureHandle bloomA, RG::TextureHandle bloomB);
~BloomPass() override = default;
@@ -29,6 +31,7 @@ namespace Engine::Passes {
private:
FullscreenGpu& m_Gpu;
PostProcessParams& m_Params;
FrameSceneData& m_Frame; // bloomEnabled 开关(帧契约)
RG::TextureHandle m_HDR;
RG::TextureHandle m_A; // 提取 + 垂直模糊结果
RG::TextureHandle m_B; // 水平模糊中间结果
@@ -31,13 +31,28 @@ namespace Engine {
f32 param2;
};
// 后处理链参数(ImGui 可调;Renderer 持有,pass 按引用读取)
// 后处理数值参数(ImGui 可调;Renderer 持有,pass 按引用读取)。
// 运行时开关/调试视图不在这里——统一进 FrameSceneData(帧契约)
struct PostProcessParams {
f32 exposure = 0.6f;
bool useACES = true;
f32 bloomThreshold = 1.0f; // HDR 域亮度阈值
f32 bloomStrength = 0.8f; // 叠加强度
bool showTemporalDiff = false; // 调试视图:显示帧历史差异
};
// 调试视图枚举:TonemapPass 按值把对应中间目标路由上屏。
// 与 Renderer 的 DebugViewNames 表下标一一对应
enum DebugView : int {
kDebugFinal = 0, // 正常画面(tonemap 输出)
kDebugTemporalDiff, // 帧历史差异(TAA 链路验证)
kDebugHDR, // Forward 原始 HDR(无 bloom/TAA)
kDebugTAAColor, // TAA resolve 后
kDebugBloom, // bloom 模糊结果
kDebugVelocity, // 运动向量(|uv| 增益显示)
kDebugShadowMap0, // CSM 级联 0 深度(近=白)
kDebugShadowMap1, // 级联 1
kDebugShadowMap2, // 级联 2
kDebugViewCount
};
class FullscreenGpu {
@@ -12,6 +12,7 @@
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/FullscreenGpu.h>
#include <Engine/Renderer/SceneTypes.h>
#include <vulkan/vulkan.hpp>
#include <vector>
@@ -19,7 +20,7 @@ namespace Engine::Passes {
class TAAPass final : public RenderPass {
public:
TAAPass(FullscreenGpu& gpu, f32 historyAlpha,
TAAPass(FullscreenGpu& gpu, FrameSceneData& frame, f32 historyAlpha,
RG::TextureHandle hdrColor, RG::TextureHandle velocity,
RG::TextureHandle taaColor);
~TAAPass() override = default;
@@ -29,7 +30,8 @@ namespace Engine::Passes {
private:
FullscreenGpu& m_Gpu;
f32 m_HistoryAlpha;
FrameSceneData& m_Frame; // taaEnabled 开关(帧契约)
f32 m_HistoryAlpha; // 开启时的历史权重
RG::TextureHandle m_HDR;
RG::TextureHandle m_Velocity;
RG::TextureHandle m_TAAColor; // 输出 = 下一帧的历史
@@ -11,6 +11,7 @@
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/FullscreenGpu.h>
#include <Engine/Renderer/SceneTypes.h>
#include <vulkan/vulkan.hpp>
#include <vector>
@@ -19,8 +20,12 @@ namespace Engine::Passes {
class TonemapPass final : public RenderPass {
public:
TonemapPass(FullscreenGpu& gpu, PostProcessParams& params,
FrameSceneData& frame,
RG::TextureHandle hdrColor, RG::TextureHandle bloomA,
RG::TextureHandle temporalDiff, RG::TextureHandle backbuffer);
RG::TextureHandle temporalDiff, RG::TextureHandle backbuffer,
RG::TextureHandle rawHdr, RG::TextureHandle velocity,
RG::TextureHandle shadowMap0, RG::TextureHandle shadowMap1,
RG::TextureHandle shadowMap2);
~TonemapPass() override = default;
void Register(RG::RenderGraph& rg) override;
@@ -29,10 +34,16 @@ namespace Engine::Passes {
private:
FullscreenGpu& m_Gpu;
PostProcessParams& m_Params;
FrameSceneData& m_Frame; // debugView / bloomEnabled(帧契约)
RG::TextureHandle m_HDR;
RG::TextureHandle m_A;
RG::TextureHandle m_TemporalDiff; // 调试视图输入(当前帧槽位)
RG::TextureHandle m_TemporalDiff;
RG::TextureHandle m_Backbuffer;
// ---- 调试视图源(binding 3-7,Register 时声明读防止剔除)----
// 注:TAAColor 视图直接用 binding0(主输入即 TAA 输出),无需重复绑
RG::TextureHandle m_RawHDR; // Forward 直出(TAA 前)
RG::TextureHandle m_Velocity;
RG::TextureHandle m_ShadowMaps[3];
std::vector<vk::DescriptorSet> m_Sets; // per-slot
};
+13 -3
View File
@@ -81,9 +81,19 @@ namespace Engine {
void SetBloomThreshold(f32 v);
f32 GetBloomStrength() const;
void SetBloomStrength(f32 v);
// 调试视图:显示帧历史差异(TemporalDiff pass 产出)
bool GetShowTemporalDiff() const;
void SetShowTemporalDiff(bool b);
// ---- 特性开关 / 调试视图(转发到 SceneRenderer,每帧落
// FrameSceneData 契约,pass 只读;ImGui 直接对接)----
bool GetShadowsEnabled() const;
void SetShadowsEnabled(bool b);
bool GetTAAEnabled() const;
void SetTAAEnabled(bool b);
bool GetBloomEnabled() const;
void SetBloomEnabled(bool b);
int GetDebugView() const;
void SetDebugView(int v); // Passes::DebugView 枚举值
// 调试视图名表(下标 = DebugView 枚举值,ImGui combo 直接枚举)
const std::vector<const char*>& GetDebugViewNames() const;
// pass 级 GPU 耗时(最近完成帧,毫秒;与 GetPassGpuMs 下标对应)
const std::vector<std::string>& GetPassNames() const { return m_PassNames; }
@@ -49,6 +49,14 @@ namespace Engine {
}
f32 GetCollectMs() const { return m_Frame.collectMs; }
// ---- 运行时开关/调试视图(ImGui 经 Renderer 门面调用)。
// 状态唯一持有者在此,BuildFrame 每帧落入 FrameSceneData;
// TAA 开关同时控制投影抖动,同一持有者天然同步 ----
void SetShadowsEnabled(bool b) { m_ShadowsEnabled = b; }
void SetTAAEnabled(bool b) { m_TAAEnabled = b; }
void SetBloomEnabled(bool b) { m_BloomEnabled = b; }
void SetDebugView(int v) { m_DebugView = v; }
private:
// CSM:把相机视锥按实用分割切 N 段,每段独立拟合光源正交投影
//(含纹素对齐防阴影边缘闪烁)。写入(Shadow pass push)与采样
@@ -86,6 +94,12 @@ namespace Engine {
std::unordered_map<u32, glm::mat4> m_CurWorlds;
bool m_TruncationWarned = false; // 实例缓冲打满只告警一次
// ---- 运行时开关/调试视图状态(本类是唯一写入者)----
bool m_ShadowsEnabled = true;
bool m_TAAEnabled = true;
bool m_BloomEnabled = true;
int m_DebugView = 0;
};
} // namespace Engine
+9 -1
View File
@@ -52,7 +52,8 @@ namespace Engine {
glm::mat4 view;
glm::mat4 proj; // 抖动后的投影(光栅化用)
glm::mat4 lightSpace[kMaxCascades]; // CSM 各级联光空间 VP([0,1] 重映射)
glm::vec4 cascadeSplits; // xyz = 级联 0..2 远边界(视图深度,正值),w 未用
glm::vec4 cascadeSplits; // xyz = 级联 0..2 远边界(视图深度,正值)
// w = shadowsEnabled(1.0/0.0,frag 阴影短路用)
glm::vec4 ambientColor;
LightData lights[kMaxLights];
@@ -82,6 +83,13 @@ namespace Engine {
// 级联盒沿光方向加了 caster pad,影子不会被剔除裁掉)
CullResult shadowCascades[kMaxCascades];
// ---- 运行时开关/调试视图(ImGui 经 Renderer 门面写入,
// SceneRenderer 唯一落帧,各 pass 只读;每帧确定性)----
bool shadowsEnabled = true; // ShadowPass 空转 + frag ShadowFactor 短路
bool taaEnabled = true; // TAAPass 直通(alpha=0) + 停投影抖动
bool bloomEnabled = true; // BloomPass 子 pass 空转 + tonemap 强度归零
int debugView = 0; // Passes::DebugView 枚举(tonemap 路由上屏)
f32 collectMs = 0.0f; // 收集+剔除 CPU 耗时(遥测)
};