← ALL ARTICLES
渲染架构3 MIN READ

Render Pass与附件

全库目录221
本文目录11

一个全屏效果接进来以后,颜色被清掉或深度突然失效,往往不是滤波公式的问题,而是附件在通道边界怎样保留没有说清。Render Pass把这段执行范围里的颜色、深度和模板联系起来。先问开始要读什么、结束谁还要用,再确定load/store、格式和样本数。

附件契约

附件的内容需求

颜色、深度和模板附件定义尺寸、格式、样本数与子资源。开始时有三种典型需求:保留已有内容、清为指定值、允许丢弃旧内容。结束时决定结果是否需要保留供后续使用。

加载与存储的选择来自消费者。需要叠加已有颜色时必须 load 或先准备底色;整张完整覆盖可以允许丢弃旧内容。只有后续不再需要的结果才可丢弃,深度拷贝、后处理和回读也是使用者。

text
通道 A:清除颜色与深度 → 写入场景
                      ↓ 保留颜色供采样
通道 B:读取场景颜色 → 写后处理结果
                      ↓ 保留呈现颜色
显示系统:呈现

“完整覆盖”还受 viewport、scissor、裁剪和深度测试影响。全屏三角形只覆盖一个小 scissor 时,附件其他区域仍未初始化;如果后续要采样整张纹理,必须先清除或由其他写入覆盖这些像素。将目标预填成洋红色,再执行该通道,可以直接发现错误的丢弃声明。

后端表达

Vulkan 动态渲染示例

以下机制片段面向Vulkan 1.3;创建设备时先查询并启用dynamicRendering特性,API版本本身不能代替特性启用。片段只描述颜色附件开始信息。进入前已将图像转换到指定布局;之后还需要绘制、结束和后续资源同步。

cpp
VkRenderingAttachmentInfo color{};
color.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
color.imageView = colorView;
color.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color.clearValue.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
VkRenderingInfo rendering{};
rendering.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
rendering.renderArea = {{0, 0}, extent};
rendering.layerCount = 1;
rendering.colorAttachmentCount = 1;
rendering.pColorAttachments = &color;
vkCmdBeginRendering(commandBuffer, &rendering);
DrawScene(commandBuffer);
vkCmdEndRendering(commandBuffer);

动态渲染省去部分预先建立的 render pass/framebuffer 对象,布局与同步仍由应用表达。传统 subpass、input attachment 与动态渲染 local read 是相关但不同的接口,支持能力要按版本和扩展核对。

OpenGL 帧缓冲与对象状态

OpenGL 帧缓冲绑定颜色和深度附件,DSA 接口直接指定修改对象。下例输入已创建的纹理,输出完整的帧缓冲对象;使用 OpenGL 4.5 或相应扩展。

cpp
GLuint framebuffer = 0;
glCreateFramebuffers(1, &framebuffer);
glNamedFramebufferTexture(framebuffer, GL_COLOR_ATTACHMENT0, colorTexture, 0);
glNamedFramebufferTexture(framebuffer, GL_DEPTH_ATTACHMENT, depthTexture, 0);
GLenum outputs[] = {GL_COLOR_ATTACHMENT0};
glNamedFramebufferDrawBuffers(framebuffer, 1, outputs);
GLenum status = glCheckNamedFramebufferStatus(framebuffer, GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
    ReportFramebufferError(framebuffer);
}

纹理尺寸、样本数和附件能力需兼容。DSA 减少隐式对象绑定误操作,绘制仍需设置 viewport、clear、深度和混合状态。写入后的采样遵守资源访问规则;DSA 不改变附件带宽或同步成本。

平台与采样

Tile GPU 与带宽

Tile GPU 在片上处理一块画面的附件。保留同一执行范围内的结果可以减少主存往返,但附件数量、样本数和总字节会限制片上容量。要求采样邻域的后处理通常需要已物化的图像内容,可能打断片上复用。

MSAA resolve 把多样本结果转换为单样本资源。普通颜色 resolve、深度 resolve 和具体样本规则有不同支持条件。分辨率、样本数和切片必须与相机目标匹配。

采样快照与反馈回路

普通全屏效果采样源颜色并写入另一子资源。需要保留原图时先建立快照;连续效果可在兼容资源间交替读写,是否能省拷贝由后续消费者决定。

Framebuffer Fetch或附件反馈扩展允许的访问有专门API条件,不能把开发机偶然可用当作常规同资源采样保证。图必须知道真实读写,才能生成同步与分配。

验证方法

  • 在捕获中检查实际附件、load/store、clear 值、样本数和 resolve 目标。
  • 首次写入前填充高对比调试色,检查声明完整覆盖的通道是否残留旧内容。
  • 将可丢弃附件改为保留,确认输出相同,并比较目标设备带宽。
  • 测试 XR 数组切片、相机堆栈和动态分辨率,检查附件尺寸和生命周期。

相关主题

示例状态:本页代码用于解释对应的数据和调用约束,完整资源创建、类型与调用环境由项目提供。除文中另列的实际实验外,本页未执行目标引擎编译、GPU捕获或性能计时。

参考资料