- image/view/显存分配收口为 EnvTexture 单元(RHI 惯例:三者同生共死), Cubemap = 4 个 EnvTexture + 2 采样器的组合,构造 17 参 → 8 参 - UploadCube/UploadTexture2D 直接返回完整资源单元(view 创建收进 helper),工厂函数只做"生成数据 → 上传 → 组装" - 析构循环成对释放,杜绝半套泄漏;删除无调用者的 Get()/GetFaceSize()/ GetPrefilteredMipCount()(shader mip 上限以常量契约)
91 lines
3.8 KiB
C++
91 lines
3.8 KiB
C++
//
|
||
// 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
|