- 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 全活跃)
158 lines
6.7 KiB
C++
158 lines
6.7 KiB
C++
//
|
||
// 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 ImGuiLayer;
|
||
|
||
namespace ECS { class Scene; }
|
||
namespace Assets { class AssetManager; class IAssetUploader; }
|
||
namespace Passes { class RenderPass; class SceneGpu; class FullscreenGpu; class PostProcessParams; }
|
||
|
||
class Renderer {
|
||
public:
|
||
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);
|
||
// 调试视图:显示帧历史差异(TemporalDiff pass 产出)
|
||
bool GetShowTemporalDiff() const;
|
||
void SetShowTemporalDiff(bool b);
|
||
|
||
// 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;
|
||
|
||
// 垂直同步开关(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 共享装配
|
||
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}; // 每槽位首帧跳过读取
|
||
|
||
vk::Extent2D m_Extent{};
|
||
u32 m_CurrentFrame = 0;
|
||
};
|
||
|
||
} // namespace Engine
|
||
|
||
#endif //HELLOVULKAN_RENDERER_H
|