核心变更: - 实现 d3d12_render_texture 类,支持多 Mip 级别 RTV - 实现 d3d12_depth_buffer 类,支持 DSV 和 SRV 双视图 - 为所有纹理类添加析构函数,确保资源自动释放 - 深度缓冲区格式转换处理(D32_FLOAT -> R32_TYPELESS) 文档完善: - 新增变更记录文档 - 更新 D3D12 学习 Wiki,添加渲染目标纹理和深度缓冲区章节
6.0 KiB
6.0 KiB
变更记录:渲染目标纹理与深度缓冲区实现
提交日期: 2026-04-01
提交哈希: 57afd12
变更类型: 功能新增
变更概述
本次提交实现了 d3d12_render_texture(渲染目标纹理)和 d3d12_depth_buffer(深度缓冲区)类,为纹理资源类添加了析构函数。
修改文件
| 文件 | 变更说明 |
|---|---|
D3D12Resources.h |
为纹理类添加析构函数,完善 d3d12_render_texture 和 d3d12_depth_buffer 类定义 |
D3D12Resource.cpp |
实现 d3d12_render_texture 和 d3d12_depth_buffer 构造与释放逻辑 |
d3d12_render_texture 类
功能说明
渲染目标纹理类,支持多 Mip 级别的渲染目标视图(RTV):
class d3d12_render_texture
{
public:
d3d12_render_texture() = default;
explicit d3d12_render_texture(d3d12_texture_init_info info);
~d3d12_render_texture() { release(); }
// 移动语义
d3d12_render_texture(d3d12_render_texture&& o);
d3d12_render_texture& operator=(d3d12_render_texture&& o);
// 禁用拷贝
DISABLE_COPY(d3d12_render_texture);
void release();
u32 mip_count() const;
D3D12_CPU_DESCRIPTOR_HANDLE rtv(u32 mip) const;
descriptor_handle srv() const;
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _rtv[d3d12_texture::max_mips]{}; // 每个 Mip 一个 RTV
u32 _mip_count{0};
};
构造流程
d3d12_render_texture::d3d12_render_texture(d3d12_texture_init_info info)
: _texture(info) // 先创建基础纹理
{
// 获取 Mip 级别数
_mip_count = resource()->GetDesc().MipLevels;
// 为每个 Mip 级别创建 RTV
D3D12_RENDER_TARGET_VIEW_DESC desc{};
desc.Format = info.desc->Format;
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
for(u32 i = 0; i < _mip_count; ++i)
{
_rtv[i] = rtv_heap.allocate();
device->CreateRenderTargetView(resource(), &desc, _rtv[i].cpu);
++desc.Texture2D.MipSlice; // 下一个 Mip 切片
}
}
使用场景
- 离屏渲染(Render-to-Texture)
- 多级渐远纹理生成
- 后处理效果
d3d12_depth_buffer 类
功能说明
深度缓冲区类,封装深度模板视图(DSV)和着色器资源视图(SRV):
class d3d12_depth_buffer
{
public:
d3d12_depth_buffer() = default;
explicit d3d12_depth_buffer(d3d12_texture_init_info info);
~d3d12_depth_buffer() { release(); }
// 移动语义
d3d12_depth_buffer(d3d12_depth_buffer&& o);
d3d12_depth_buffer& operator=(d3d12_depth_buffer&& o);
// 禁用拷贝
DISABLE_COPY(d3d12_depth_buffer);
void release();
D3D12_CPU_DESCRIPTOR_HANDLE dsv() const;
descriptor_handle srv() const;
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _dsv{};
};
构造流程
d3d12_depth_buffer::d3d12_depth_buffer(d3d12_texture_init_info info)
{
// 深度缓冲区需要特殊处理格式
// DSV 使用 D32_FLOAT,SRV 使用 R32_FLOAT
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc{};
if(info.desc->Format == DXGI_FORMAT_D32_FLOAT)
{
info.desc->Format = DXGI_FORMAT_R32_TYPELESS; // 资源使用无类型格式
srv_desc.Format = DXGI_FORMAT_R32_FLOAT; // SRV 使用浮点格式
}
// 创建纹理和 SRV
info.srv_desc = &srv_desc;
_texture = d3d12_texture(info);
// 创建 DSV
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc{};
dsv_desc.Format = DXGI_FORMAT_D32_FLOAT; // DSV 使用深度格式
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
_dsv = dsv_heap.allocate();
device->CreateDepthStencilView(resource(), &dsv_desc, _dsv.cpu);
}
格式转换说明
┌─────────────────────────────────────────────────────────────┐
│ 深度缓冲区格式处理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户指定格式:DXGI_FORMAT_D32_FLOAT │
│ │ │
│ ▼ │
│ 资源格式:DXGI_FORMAT_R32_TYPELESS(无类型) │
│ │ │
│ ┌──────────┴──────────┐ │
│ ▼ ▼ │
│ DSV 格式:D32_FLOAT SRV 格式:R32_FLOAT │
│ (深度测试用) (着色器采样用) │
│ │
└─────────────────────────────────────────────────────────────┘
为什么要这样处理?
- 深度缓冲区需要作为着色器资源被采样(如阴影映射、SSAO)
- DSV 格式(D32_FLOAT)不能直接用于 SRV
- 使用 TYPELESS 格式允许同一资源创建不同格式的视图
析构函数添加
为所有纹理类添加了析构函数,确保资源自动释放:
class d3d12_texture {
public:
~d3d12_texture() { release(); }
// ...
};
class d3d12_render_texture {
public:
~d3d12_render_texture() { release(); }
// ...
};
class d3d12_depth_buffer {
public:
~d3d12_depth_buffer() { release(); }
// ...
};
后续工作
- 实现根签名和管线状态对象
- 渲染第一个三角形
- 实现常量缓冲区