refactor: 解耦重构——还清四处架构债(对齐 UE/Unity 分层)

- SceneRenderer:场景→渲染数据翻译层(UE FSceneRenderer / Unity CullingResults
  模式),收口相机/灯光/光空间矩阵/双视图剔除,Renderer 只编排
- pass 对象化(Unity ScriptableRenderPass 模式):8 个 pass lambda 拆为
  Passes::{Shadow,Forward,Bloom,Tonemap,ImGui,Present},BuildGraph 超级函数消失;
  SceneGpu/FullscreenGpu 承接共享装配
- 中性 AssetRef(Core 层):ECS 组件不再依赖 Assets 模块(Unity InstanceID 思路)
- IAssetUploader 接口:AssetManager 不感知 Vulkan 具体类,上传服务由渲染层
  VulkanAssetUploader 提供
- Renderer 公共 API 不变(App 层零改动),编译零错误 validation 零警告
This commit is contained in:
2026-09-23 12:02:49 +08:00
parent 91880d88fe
commit 718a658f5d
30 changed files with 1777 additions and 1054 deletions
@@ -0,0 +1,44 @@
//
// Created by atdunbg on 2026/9/23.
//
// BloomPass:Extract(HDR 软阈值)→ BlurH → BlurV,全部半分辨率。
// 一个"效果"对应多个 RG pass 的例子(Unity 的一个 ScriptableRenderPass
// 常含多个 PassEvent 阶段,同构)。
//
#ifndef HELLOVULKAN_BLOOMPASS_H
#define HELLOVULKAN_BLOOMPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/FullscreenGpu.h>
#include <vulkan/vulkan.hpp>
#include <vector>
namespace Engine::Passes {
class BloomPass final : public RenderPass {
public:
BloomPass(FullscreenGpu& gpu, PostProcessParams& params,
RG::TextureHandle hdrColor,
RG::TextureHandle bloomA, RG::TextureHandle bloomB);
~BloomPass() override = default;
void Register(RG::RenderGraph& rg) override;
void OnTargetsRebuilt(RG::RenderGraph& rg) override;
private:
FullscreenGpu& m_Gpu;
PostProcessParams& m_Params;
RG::TextureHandle m_HDR;
RG::TextureHandle m_A; // 提取 + 垂直模糊结果
RG::TextureHandle m_B; // 水平模糊中间结果
// per-slot 输入描述符
std::vector<vk::DescriptorSet> m_ExtractSets;
std::vector<vk::DescriptorSet> m_BlurHSets;
std::vector<vk::DescriptorSet> m_BlurVSets;
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_BLOOMPASS_H
@@ -0,0 +1,38 @@
//
// Created by atdunbg on 2026/9/23.
//
// ForwardPass:相机视角渲染到 HDR 颜色图(线性光照值)。
// 显示变换不在本 pass——HDRColor 经 Tonemap 归一后才写 Backbuffer
// (对齐 UE/Unity:SceneColor(HDR) → tonemapper → UI)。
//
#ifndef HELLOVULKAN_FORWARDPASS_H
#define HELLOVULKAN_FORWARDPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/SceneGpu.h>
#include <Engine/Renderer/SceneTypes.h>
namespace Engine::Passes {
class ForwardPass final : public RenderPass {
public:
ForwardPass(SceneGpu& gpu, FrameSceneData& frame,
RG::TextureHandle hdrColor, RG::TextureHandle depth,
RG::TextureHandle shadowMap)
: m_Gpu(gpu), m_Frame(frame),
m_HDRColor(hdrColor), m_Depth(depth), m_ShadowMap(shadowMap) {}
void Register(RG::RenderGraph& rg) override;
private:
SceneGpu& m_Gpu;
FrameSceneData& m_Frame;
RG::TextureHandle m_HDRColor;
RG::TextureHandle m_Depth;
RG::TextureHandle m_ShadowMap;
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_FORWARDPASS_H
@@ -0,0 +1,78 @@
//
// Created by atdunbg on 2026/9/23.
//
// FullscreenGpu:全屏后处理共享装配(Tonemap/Bloom 系 pass 共用)。
//
// 全屏 pass 的共性收口在这里:Set0 = {输入0, 输入1}、push 16B 通用结构
// (规避 VUID-08878 的"range 定义必须一致")、无顶点输入全屏三角、
// 公共录制函数。新增全屏效果 = 复用本类 + 新增一个 frag shader。
//
#ifndef HELLOVULKAN_FULLSCREENGPU_H
#define HELLOVULKAN_FULLSCREENGPU_H
#include <Engine/Core/Types.h>
#include <Engine/RenderGraph/RenderGraph.h>
#include <vulkan/vulkan.hpp>
namespace Engine {
class Device;
class DescriptorManager;
class ShaderManager;
namespace Passes {
// 全屏 pass 通用 push(16B):所有全屏 pass 统一声明与推送
struct FullscreenPush {
f32 exposure;
f32 param0; // 各 pass 自定语义(tonemap: aces 开关)
f32 param1;
f32 param2;
};
// 后处理链参数(ImGui 可调;Renderer 持有,pass 按引用读取)
struct PostProcessParams {
f32 exposure = 1.0f;
bool useACES = true;
f32 bloomThreshold = 1.0f; // HDR 域亮度阈值
f32 bloomStrength = 0.8f; // 叠加强度
};
class FullscreenGpu {
public:
FullscreenGpu(Device& device, DescriptorManager& descriptors,
ShaderManager& shaders);
~FullscreenGpu();
FullscreenGpu(const FullscreenGpu&) = delete;
FullscreenGpu& operator=(const FullscreenGpu&) = delete;
vk::DescriptorSetLayout setLayout; // Set0 = {输入0, 输入1}
vk::PipelineLayout layout; // push 16B(FullscreenPush)
vk::Sampler sampler;
vk::ShaderEXT vert{}, extractFrag{}, blurFrag{}, tonemapFrag{};
// 各 pass 自己持有 per-slot set;分配统一走这里
vk::DescriptorSet AllocateSet();
// 输入图片绑定(RG 重编译后重绑;物理镜像按槽位各一份)
void UpdateSetInput(vk::DescriptorSet set, u32 binding,
RG::RenderGraph& rg, RG::TextureHandle input,
u32 slot);
// 全屏 pass 公共录制:动态状态/draw 全一致,仅附件 view、
// 输入 set、push 值不同
void RecordFullscreen(RG::RenderGraphContext& ctx, vk::ImageView view,
vk::ShaderEXT frag, const vk::DescriptorSet& set,
const FullscreenPush& push);
private:
Device& m_Device;
DescriptorManager& m_Descriptors;
};
} // namespace Passes
} // namespace Engine
#endif //HELLOVULKAN_FULLSCREENGPU_H
@@ -0,0 +1,38 @@
//
// Created by atdunbg on 2026/9/23.
//
// ImGuiPass:叠加层(loadOp=Load,不清屏)。
// 框架只负责把 draw data 录进 cmd;UI 内容全部由派生类在
// OnRenderOverlay() 里构建,框架自身不画任何 ImGui 控件。
// 未启用叠加层时空转(begin/end 一次空 rendering region)。
//
#ifndef HELLOVULKAN_IMGUIPASS_H
#define HELLOVULKAN_IMGUIPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
namespace Engine {
class ImGuiLayer;
namespace Passes {
class ImGuiPass final : public RenderPass {
public:
// 二级指针:Renderer::SetImGuiLayer 在 Register 之后才可能被调
//(EnableImGui 时机由派生类决定),执行期解引用取最新值
ImGuiPass(ImGuiLayer** layer, RG::TextureHandle backbuffer)
: m_Layer(layer), m_Backbuffer(backbuffer) {}
void Register(RG::RenderGraph& rg) override;
private:
ImGuiLayer** m_Layer;
RG::TextureHandle m_Backbuffer;
};
} // namespace Passes
} // namespace Engine
#endif //HELLOVULKAN_IMGUIPASS_H
@@ -0,0 +1,32 @@
//
// Created by atdunbg on 2026/9/23.
//
// PresentPass:transition 到 ePresentSrcKHR。
// layout 转换由 RG 的 barrier 完成,实际 vkQueuePresentKHR 由 Renderer 驱动。
//
#ifndef HELLOVULKAN_PRESENTPASS_H
#define HELLOVULKAN_PRESENTPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
namespace Engine::Passes {
class PresentPass final : public RenderPass {
public:
explicit PresentPass(RG::TextureHandle backbuffer)
: m_Backbuffer(backbuffer) {}
void Register(RG::RenderGraph& rg) override
{
rg.AddPass("Present", [](RG::RenderGraphContext&) {})
.Read(m_Backbuffer, RG::ResourceUse::Present);
}
private:
RG::TextureHandle m_Backbuffer;
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_PRESENTPASS_H
@@ -0,0 +1,34 @@
//
// Created by atdunbg on 2026/9/23.
//
// RenderPass:渲染 pass 对象基类(Unity ScriptableRenderPass 思路)。
//
// pass 自己负责两件事,框架(Renderer)不再手写"超级函数":
// Register —— 向 RenderGraph 声明资源使用 + 录制 lambda;
// 执行序由 RG 拓扑排序决定(writer 必先于 reader),
// 与注册顺序无关
// OnTargetsRebuilt —— RG 重编译(resize / vsync 切换)后重绑描述符
// (物理镜像按槽位可能全部换新)
//
// pass 之间不互相依赖:数据流只经 RG 资源句柄。新增效果 = 新增一个
// RenderPass 子类 + Renderer::BuildGraph 里注册一行,其它代码不动。
//
#ifndef HELLOVULKAN_RENDERPASS_H
#define HELLOVULKAN_RENDERPASS_H
#include <Engine/RenderGraph/RenderGraph.h>
namespace Engine::Passes {
class RenderPass {
public:
virtual ~RenderPass() = default;
virtual void Register(RG::RenderGraph& rg) = 0;
virtual void OnTargetsRebuilt(RG::RenderGraph& rg) { (void)rg; }
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_RENDERPASS_H
@@ -0,0 +1,67 @@
//
// Created by atdunbg on 2026/9/23.
//
// SceneGpu:场景级 GPU 共享装配(Shadow/Forward 及未来几何类 pass 共用)。
//
// 从 Renderer 拆出的装配体:set 布局 / pipeline 布局 / shader object /
// 采样器 / per-slot 描述符集合。新增几何 pass(延迟、调试线框等)直接
// 复用本装配,不必碰 Renderer。
//
#ifndef HELLOVULKAN_SCENEGPU_H
#define HELLOVULKAN_SCENEGPU_H
#include <Engine/Core/FrameContext.h>
#include <Engine/RenderGraph/RenderGraph.h>
#include <vulkan/vulkan.hpp>
#include <vector>
namespace Engine {
class Device;
class DescriptorManager;
class ShaderManager;
class UniformBuffer;
namespace Passes {
class SceneGpu {
public:
SceneGpu(Device& device, DescriptorManager& descriptors,
ShaderManager& shaders,
UniformBuffer& ubo, UniformBuffer& objectBuffer);
~SceneGpu();
SceneGpu(const SceneGpu&) = delete;
SceneGpu& operator=(const SceneGpu&) = delete;
// ---- set 布局(shader 契约,改绑定必须同步 shaders/)----
vk::DescriptorSetLayout uboSetLayout; // Set0 = {UBO, ObjectBuffer}
vk::DescriptorSetLayout textureSetLayout; // Set1 = {albedo}
vk::DescriptorSetLayout shadowSetLayout; // Set2 = {shadow map}
vk::PipelineLayout forwardLayout; // 3 sets,无 push(GPUDriven 经 SSBO)
vk::PipelineLayout shadowLayout; // Set0,push = lightVP 64B
// per-slot 描述符:Set0(UBO+实例 SSBO)与 Set2(阴影图采样)
std::vector<vk::DescriptorSet> uboSets;
std::vector<vk::DescriptorSet> shadowSets;
// 阴影采样器:clamp-to-border 白色 = 光视锥外自动无阴影
//(省 shader 出界分支)
vk::Sampler shadowSampler;
vk::ShaderEXT forwardVert{}, forwardFrag{};
vk::ShaderEXT shadowVert{}, shadowFrag{};
// RG 重编译后重绑阴影图(物理镜像按槽位各一份)
void BindShadowMap(RG::RenderGraph& rg, RG::TextureHandle shadowMap);
private:
Device& m_Device;
DescriptorManager& m_Descriptors;
};
} // namespace Passes
} // namespace Engine
#endif //HELLOVULKAN_SCENEGPU_H
@@ -0,0 +1,33 @@
//
// Created by atdunbg on 2026/9/23.
//
// ShadowPass:光源视角写深度。GPUDriven batch 消费光源视锥剔除结果
// (FrameSceneData::shadowView——相机外实体仍投影子)。
//
#ifndef HELLOVULKAN_SHADOWPASS_H
#define HELLOVULKAN_SHADOWPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/SceneGpu.h>
#include <Engine/Renderer/SceneTypes.h>
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) {}
void Register(RG::RenderGraph& rg) override;
void OnTargetsRebuilt(RG::RenderGraph& rg) override;
private:
SceneGpu& m_Gpu;
FrameSceneData& m_Frame;
RG::TextureHandle m_ShadowMap;
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_SHADOWPASS_H
@@ -0,0 +1,41 @@
//
// Created by atdunbg on 2026/9/23.
//
// TonemapPass:HDR(+bloom)→ 显示空间,全屏三角写 Backbuffer。
// 显示变换在此显式建模(对齐 UE/Unity:HDR SceneColor → tonemapper → UI)。
// Backbuffer 从此只接收"显示空间"颜色:tonemap 直接写、ImGui 叠加。
//
#ifndef HELLOVULKAN_TONEMAPPASS_H
#define HELLOVULKAN_TONEMAPPASS_H
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/Passes/FullscreenGpu.h>
#include <vulkan/vulkan.hpp>
#include <vector>
namespace Engine::Passes {
class TonemapPass final : public RenderPass {
public:
TonemapPass(FullscreenGpu& gpu, PostProcessParams& params,
RG::TextureHandle hdrColor, RG::TextureHandle bloomA,
RG::TextureHandle backbuffer);
~TonemapPass() override = default;
void Register(RG::RenderGraph& rg) override;
void OnTargetsRebuilt(RG::RenderGraph& rg) override;
private:
FullscreenGpu& m_Gpu;
PostProcessParams& m_Params;
RG::TextureHandle m_HDR;
RG::TextureHandle m_A;
RG::TextureHandle m_Backbuffer;
std::vector<vk::DescriptorSet> m_Sets; // per-slot
};
} // namespace Engine::Passes
#endif //HELLOVULKAN_TONEMAPPASS_H