Files
HelloVulkan/Engine/include/Engine/Renderer/Cubemap.h
T
atdunbg d2b878c077 refactor: Cubemap 拆掉 17 参超级构造——资源三元组 EnvTexture
- image/view/显存分配收口为 EnvTexture 单元(RHI 惯例:三者同生共死),
  Cubemap = 4 个 EnvTexture + 2 采样器的组合,构造 17 参 → 8 参
- UploadCube/UploadTexture2D 直接返回完整资源单元(view 创建收进
  helper),工厂函数只做"生成数据 → 上传 → 组装"
- 析构循环成对释放,杜绝半套泄漏;删除无调用者的 Get()/GetFaceSize()/
  GetPrefilteredMipCount()(shader mip 上限以常量契约)
2026-09-23 19:25:32 +08:00

91 lines
3.8 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/23.
//
// Cubemap:环境立方体贴图 + IBL 预积分资源(阶段②③,split-sum)。
//
// 从等距柱状 HDR(.hdr,polyhaven 等)生成,CPU 一次性预积分:
// env cube —— 重采样 6 面(Skybox 背景)
// irradiance cube —— 半球 Lambert 积分(PBR 漫反射 ambient)
// prefilter cube —— GGX 重要性采样 × mip 分级 roughness(镜面 IBL)
// BRDF LUT —— 2D 积分表(纯数学,与环境内容无关)
// 全部 fp16 上传,运行时采样零积分开销。
//
// 后续演进:CPU 预积分 → compute pass(动态环境零卡顿);本类的
// 方向表/上传路径届时整体迁移,接口不变。
//
#ifndef HELLOVULKAN_CUBEMAP_H
#define HELLOVULKAN_CUBEMAP_H
#include <Engine/Core/Types.h>
#include <Engine/Vulkan/MemoryAllocator.h>
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
namespace Engine {
class Device;
// GPU 纹理资源三元组(RHI 惯例):image/view/显存分配同生共死,
// 析构统一释放——杜绝"建了 image 丢了 view"类半套泄漏。
// 上传 helper 直接以此为单位产出,消费端只拿引用计数语义的整单元
struct EnvTexture {
vk::Image image{};
vk::ImageView view{};
MemoryAllocator::Allocation allocation;
};
class Cubemap {
public:
// 从等距柱状 HDR 生成(CPU 重采样 + irradiance/prefilter/BRDF 预积分)
static Scope<Cubemap> CreateFromHdrEquirect(Device& device,
MemoryAllocator& allocator,
const std::string& path,
u32 faceSize);
// 中性兜底(无 HDR 资产时):cube 均为常数色;BRDF LUT 仍为
// 真实积分(纯数学)。保证引用侧描述符恒有效(validation)
static Scope<Cubemap> CreateNeutral(Device& device,
MemoryAllocator& allocator,
const glm::vec3& rgb);
~Cubemap();
Cubemap(const Cubemap&) = delete;
Cubemap& operator=(const Cubemap&) = delete;
// ---- 消费端契约(SkyboxPass:背景;SceneGpu:PBR ambient)----
vk::ImageView GetView() const { return m_Env.view; } // 环境 cube
vk::ImageView GetIrradianceView() const { return m_Irr.view; } // 漫反射
vk::ImageView GetPrefilteredView() const { return m_Pref.view; } // 镜面
vk::ImageView GetBrdfLutView() const { return m_Lut.view; } // LUT
// cube 资源共享采样器(maxLod 覆盖 pre-filter mip 链)
vk::Sampler GetSampler() const { return m_EnvSampler; }
// LUT 专用采样器(clamp-to-edge):共享的 border 白采样器会在
// uv=1.0 处混入 50% 白色 border,导致高 roughness 镜面偏大
vk::Sampler GetBrdfLutSampler() const { return m_LutSampler; }
private:
Cubemap(Device& device, MemoryAllocator& allocator,
EnvTexture env, EnvTexture irr, EnvTexture pref,
EnvTexture lut, vk::Sampler envSampler, vk::Sampler lutSampler)
: m_Device(device), m_Allocator(allocator),
m_Env(env), m_Irr(irr), m_Pref(pref), m_Lut(lut),
m_EnvSampler(envSampler), m_LutSampler(lutSampler) {}
Device& m_Device;
MemoryAllocator& m_Allocator;
EnvTexture m_Env; // 环境 cube(Skybox 背景)
EnvTexture m_Irr; // 漫反射辐照度 cube
EnvTexture m_Pref; // pre-filtered cube(mip 分 roughness)
EnvTexture m_Lut; // BRDF 积分 LUT(2D)
vk::Sampler m_EnvSampler;
vk::Sampler m_LutSampler;
};
} // namespace Engine
#endif //HELLOVULKAN_CUBEMAP_H