feat: ACES tonemap + Bloom 后处理链(Extract/BlurH/BlurV 半分辨率)

- ACES(Narkowicz) 经 push 开关启用,exposure 接 ImGui 滑条
- RG: TextureDesc 支持 sizeScale 相对尺寸;per-pass 渲染尺寸解析
  (半分辨率 pass 的 viewport 由此决定)
- RG Toposort 重写:RAW+WAR+WAW 按声明序逐资源建边,支持多写者
  ping-pong 资源(旧逻辑对 reader 连接所有 writer,ping-pong 成环)
- GetPhysicalView 缺物理镜像时 throw(ENGINE_FATAL 只记日志不中止)
- 全屏 pass 通用 16B push + 公共录制 lambda,Extract/Blur/Tonemap 复用
This commit is contained in:
2026-09-22 19:18:51 +08:00
parent 601fd8997c
commit 908e688178
9 changed files with 352 additions and 67 deletions
@@ -70,8 +70,9 @@ namespace Engine::RG {
struct TextureDesc {
vk::Format format = vk::Format::eUndefined;
u32 width = 0; // 0 = 跟随目标(swapchain)尺寸
u32 width = 0; // 0 = 跟随目标(swapchain)尺寸 × sizeScale
u32 height = 0;
f32 sizeScale = 1.0f; // 相对尺寸(后处理降采样用,如 bloom 0.5)
};
// ---------- 物理镜像 ----------
@@ -154,6 +155,7 @@ namespace Engine::RG {
ExecuteFn exec;
bool sideEffect = false; // 无读写但必须执行(compute 写 buffer 等)
bool culled = false;
vk::Extent2D extent{}; // 本 pass 的渲染尺寸(写入附件的最大分辨率,Compile 期解析)
// Compile 期预算好的 barrier:每个资源两个变体
// steady = 该槽位已被使用过(从 resting 状态出发)
+31 -2
View File
@@ -64,7 +64,7 @@ namespace Engine {
void BuildGraph(); // 声明 pass 结构 + 首次 Compile
void HandleResize();
void UpdateShadowDescriptors();
void UpdateTonemapDescriptors();
void UpdateFullscreenDescriptors();
Window& m_Window;
@@ -97,7 +97,8 @@ namespace Engine {
vk::ShaderEXT m_ShadowVertShader{};
vk::ShaderEXT m_ShadowFragShader{};
// Tonemap pass 装配:Set0 = HDR 颜色图,push = {exposure}(fragment)
// Tonemap pass 装配:Set0 = {HDR 颜色图, Bloom 图},push = 16B
//(全屏 pass 通用:exposure/aces/bloomStrength/pad)
vk::PipelineLayout m_TonemapPipelineLayout;
vk::DescriptorSetLayout m_TonemapSetLayout;
std::vector<vk::DescriptorSet> m_TonemapDescriptorSets; // 每帧槽位一个
@@ -105,11 +106,21 @@ namespace Engine {
vk::ShaderEXT m_TonemapVertShader{};
vk::ShaderEXT m_TonemapFragShader{};
// Bloom:Extract(HDR→A) → BlurH(A→B) → BlurV(B→A),半分辨率
// 与 Tonemap 共用 set layout/pipeline layout/vertex shader
std::vector<vk::DescriptorSet> m_BloomExtractSets; // 每帧槽位
std::vector<vk::DescriptorSet> m_BloomBlurHSets;
std::vector<vk::DescriptorSet> m_BloomBlurVSets;
vk::ShaderEXT m_BloomExtractFrag{};
vk::ShaderEXT m_BloomBlurFrag{};
// ---- RenderGraph 资源句柄 ----
RG::TextureHandle m_Backbuffer{};
RG::TextureHandle m_Depth{};
RG::TextureHandle m_ShadowMap{};
RG::TextureHandle m_HDRColor{}; // Forward 输出(线性 HDR),Tonemap 归一
RG::TextureHandle m_BloomA{}; // 半分辨率:提取 + 垂直模糊结果
RG::TextureHandle m_BloomB{}; // 半分辨率:水平模糊中间结果
// ---- 当帧绑定(Render() 期间有效,供 pass 回调读取)----
ECS::Scene* m_BoundScene = nullptr;
@@ -119,6 +130,24 @@ namespace Engine {
// 可选叠加层(不拥有;Application 持有)
ImGuiLayer* m_ImGuiLayer = nullptr;
// ---- Tonemap/Bloom 参数(ImGui 可调)----
f32 m_Exposure = 1.0f;
bool m_UseACES = true;
f32 m_BloomThreshold = 1.0f; // HDR 域亮度阈值
f32 m_BloomStrength = 0.8f; // 叠加强度
public:
f32 GetExposure() const { return m_Exposure; }
void SetExposure(f32 e) { m_Exposure = e; }
bool GetUseACES() const { return m_UseACES; }
void SetUseACES(bool b) { m_UseACES = b; }
f32 GetBloomThreshold() const { return m_BloomThreshold; }
void SetBloomThreshold(f32 v) { m_BloomThreshold = v; }
f32 GetBloomStrength() const { return m_BloomStrength; }
void SetBloomStrength(f32 v) { m_BloomStrength = v; }
private:
vk::Extent2D m_Extent{};
u32 m_CurrentFrame = 0;
};