Files
HelloVulkan/Engine/include/Engine/Renderer/Renderer.h
T

188 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// Created by atdunbg on 2026/9/20.
//
// Renderer:渲染门面 + 渲染侧组合根。
//
// 分工(对照 UE/Unity 的渲染架构):
// Renderer —— 装配模块、声明 RG 资源、注册 pass 对象、
// 每帧编排(翻译场景 → 写 buffer → 驱动 RG → 提交呈现)。
// 不理解场景细节,不含 pass 实现。
// SceneRenderer —— 场景 → FrameSceneData 的翻译层(相机/灯光/剔除,
// 对应 UE FSceneRenderer / Unity CullingResults)。
// Passes::* —— 各 pass 的声明与录制(对应 Unity ScriptableRenderPass)。
// 新增效果 = 新增 pass 类 + BuildGraph 注册一行。
//
// 对外只暴露两个入口:Render(Scene&, Assets&) 和给 App 层调参的访问器。
//
#ifndef HELLOVULKAN_RENDERER_H
#define HELLOVULKAN_RENDERER_H
#pragma once
#include <Engine/Core/Types.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 {
class Window;
class Device;
class MemoryAllocator;
class DescriptorManager;
class ShaderManager;
class Swapchain;
class SyncManager;
class CommandManager;
class UniformBuffer;
class SceneRenderer;
class VulkanAssetUploader;
class Cubemap;
class IblGenerator;
class ImGuiLayer;
class TracyGpuProfiler;
namespace ECS { class Scene; }
namespace Assets { class AssetManager; class IAssetUploader; }
namespace Passes { class RenderPass; class SceneGpu; class FullscreenGpu; class PostProcessParams; }
class Renderer {
public:
explicit Renderer(Window& window);
~Renderer();
Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete;
void Render(ECS::Scene& scene, Assets::AssetManager& assets);
// ---- 组合根(Application)装配其他模块时需要的访问器 ----
Device& GetDevice() const { return *m_Device; }
MemoryAllocator& GetAllocator() const { return *m_Allocator; }
DescriptorManager& GetDescriptorManager() const { return *m_DescriptorManager; }
vk::DescriptorSetLayout GetTextureSetLayout() const; // 实现在 cpp(SceneGpu 成员)
vk::Format GetSwapchainFormat() const;
u32 GetSwapchainImageCount() const;
// 资产上传服务(渲染层对资产层提供的 IAssetUploader 实现)
Assets::IAssetUploader& GetAssetUploader() const;
// 可选叠加层(ImGui):不设置则 RG 里的 ImGui pass 为空转。
// 生命周期:层必须先于 Renderer 析构(Application 成员序保证)。
void SetImGuiLayer(ImGuiLayer* layer) { m_ImGuiLayer = layer; }
// ---- 后处理参数(ImGui 可调,转发到 pass 共享的 PostProcessParams)----
f32 GetExposure() const;
void SetExposure(f32 e);
bool GetUseACES() const;
void SetUseACES(bool b);
f32 GetBloomThreshold() const;
void SetBloomThreshold(f32 v);
f32 GetBloomStrength() const;
void SetBloomStrength(f32 v);
// ---- 特性开关 / 调试视图(转发到 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);
bool GetLodEnabled() const;
void SetLodEnabled(bool b); // 关 = 全部强制 LOD0
int GetDebugView() const;
void SetDebugView(int v); // Passes::DebugView 枚举值
// 调试视图名表(下标 = DebugView 枚举值,ImGui combo 直接枚举)
const std::vector<const char*>& GetDebugViewNames() const;
// ---- 动态环境切换(资产归 Assets 层,Renderer 只消费)----
// env 传 AssetManager::GetEnvironment(ref) 的指针;nullptr 回中性兜底。
// 内部 waitIdle 后统一换绑(引用环境描述符的 pass 全部同步);
// compute 预积分已把生成成本压到毫秒级,waitIdle 尾巴 ≈ 单帧
void SetEnvironment(const Cubemap* env);
// pass 级 GPU 耗时(最近完成帧,毫秒;与 GetPassGpuMs 下标对应)
const std::vector<std::string>& GetPassNames() const { return m_PassNames; }
const std::vector<f32>& GetPassGpuMs() const { return m_PassGpuMs; }
// 双视图剔除后的实例数(遥测)
u32 GetMainInstanceCount() const;
u32 GetShadowInstanceCount() const;
bool GetInstancesTruncated() const; // 实例预算溢出(遥测红字)
f32 GetCollectMs() const; // CPU 收集+剔除段耗时
// 垂直同步开关(present mode 切换会重建 swapchain),
// 只应在帧 UI 构建段调用(Render 之前)
void SetVSync(bool vsync);
private:
void BuildGraph(); // 声明 RG 资源 + 注册 pass 对象
void HandleResize();
void ReadGpuTimes(u32 frameSlot);
Window& m_Window;
// ---- 底层模块(析构序:后声明者先析构;引用他人者先析构)----
Scope<Device> m_Device;
Scope<MemoryAllocator> m_Allocator;
Scope<DescriptorManager> m_DescriptorManager;
Scope<ShaderManager> m_ShaderManager;
Scope<UniformBuffer> m_UniformBuffer; // per-slot UBO ring
Scope<UniformBuffer> m_ObjectBuffer; // GPUDriven 实例矩阵 ring(SSBO)
Scope<UniformBuffer> m_PrevObjectBuffer; // 上一帧实例矩阵 ring(TAA velocity)
Scope<Passes::SceneGpu> m_SceneGpu; // 场景类 pass 共享装配
Scope<Passes::FullscreenGpu> m_FullscreenGpu; // 全屏 pass 共享装配
// 环境预积分生成端(compute 链),先于 m_Environment/m_Passes 构造
Scope<IblGenerator> m_Ibl;
// 中性兜底环境(IBL 四件套):Application 未加载/加载失败时保底;
// 声明在 m_Passes 之前 → 析构晚于 pass(引用安全)
Scope<Cubemap> m_Environment;
Scope<Swapchain> m_Swapchain;
Scope<SyncManager> m_SyncManager;
Scope<CommandManager> m_CommandManager;
Scope<SceneRenderer> m_SceneRenderer; // 场景翻译层(先于 pass 构造)
Scope<RG::RenderGraph> m_RenderGraph;
Scope<VulkanAssetUploader> m_AssetUploader;
// pass 对象(注册序;执行序由 RG 拓扑排序决定)
std::vector<Scope<Passes::RenderPass>> m_Passes;
// ---- RenderGraph 资源句柄 ----
RG::TextureHandle m_Backbuffer{};
RG::TextureHandle m_Depth{};
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 累积输出(自引用历史),后处理源
RG::TextureHandle m_BloomA{}; // 半分辨率:提取 + 垂直模糊结果
RG::TextureHandle m_BloomB{}; // 半分辨率:水平模糊中间结果
RG::TextureHandle m_TemporalDiff{}; // 半分辨率:帧历史差异(调试)
// pass 共享的可调参数(Renderer 持有,App 层访问器转发)
Scope<Passes::PostProcessParams> m_PostParams;
// 可选叠加层(不拥有;Application 持有)
ImGuiLayer* m_ImGuiLayer = nullptr;
// GPU timestamp(pass 级耗时,ImGui 可读)
vk::QueryPool m_QueryPool;
u32 m_QueriesPerFrame = 0; // 每帧槽位的查询数 = pass 数 × 2
f32 m_TimestampPeriod = 1.0f; // ns/tick(设备属性缓存)
std::vector<std::string> m_PassNames; // 执行序 pass 名
std::vector<f32> m_PassGpuMs; // 最近一帧各 pass 耗时
bool m_TimesPrimed[2] = {false, false}; // 每槽位首帧跳过读取
// Tracy GPU 时间线(pass zone;TRACY_ENABLE 关闭时空实现)
Scope<TracyGpuProfiler> m_TracyProfiler;
vk::Extent2D m_Extent{};
u32 m_CurrentFrame = 0;
};
} // namespace Engine
#endif //HELLOVULKAN_RENDERER_H