news 2026/4/19 17:58:07

讲透RenderTarget 第十四章:前沿与展望

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
讲透RenderTarget 第十四章:前沿与展望

第十四章:前沿与展望

一句话概括:RT 的形态在变,但"中间画布"的思想永远不会消失。

生活类比:从纸质草稿到 iPad 画板——载体换了,但"先画草稿再定稿"的工作流没变。


⏱ 30 秒概览

RT 的形态正在快速演变。Visibility Buffer把 G-Buffer 从 4~6 张 MRT 压缩到 1~2 张(只存 Triangle/Instance ID,Lighting 时反查材质),UE5 Nanite 已采用。VRS让 RT 同尺寸但不同区域着色率不同,需额外着色率控制 RT。光线追踪的输出走 UAV 而非 ROP,UAV 成为与 RT Attachment 并列的一等公民。UE5 三大件(Nanite + VSM + Lumen)一帧可用 60~80 张 RT,Frame Graph 成为刚需。Bindless让 RT 作为纹理读取不再受 Slot 限制。Neural Rendering可能带来 Tensor 格式的 RT。XR需要 Texture2DArray 双目渲染 + VRS Foveated + 跨帧 RT 缓存做 Timewarp。不变的本质:"先画到中间画布,再加工输出"的思想永远不会消失。


14.1 Visibility Buffer——G-Buffer 的挑战者

传统延迟渲染的 G-Buffer 方阵——4~6 张 MRT 存储材质属性——正在被一种更轻量的方案挑战:Visibility Buffer

核心思想

Visibility Buffer 只存两样东西:

RT格式内容
Vis BufferR32_UINT 或 RG32_UINTTriangle ID + Instance ID
DepthD32F硬件深度

就这两张 RT。不存颜色、法线、粗糙度——什么材质属性都不存。

Lighting Pass 时,对每个像素:

  1. 从 Vis Buffer 读取 Triangle ID + Instance ID
  2. 用 Triangle ID 反查顶点数据
  3. 用重心坐标插值得到 UV、法线等属性
  4. 采样贴图、计算材质参数
  5. 做光照

对 RT 的影响

维度G-BufferVisibility Buffer
MRT 数量4~61~2
G-Buffer 带宽极大(第 8.5 节)极小
Lighting Pass 复杂度简单(数据在 RT 中)复杂(需要重新获取材质数据)
三角形过小时Quad Overdraw 浪费严重影响小(只写 ID)

Visibility Buffer 大幅减少了 MRT 的数量和带宽,但把计算压力转移到了 Lighting Pass。

UE5 的 Nanite 就使用了类似 Visibility Buffer 的方案——结合硬件光栅化和软件光栅化,输出的是 Visibility 信息而非完整的 G-Buffer。The Matrix Awakens(2021 技术演示)首次展示了 Nanite 驱动的城市级场景,FortniteChapter 4(2022)和黑神话:悟空(2024)是最早大规模上线的 Nanite 游戏。

RT 视角的趋势

G-Buffer 的"宽而浅"(多张 RT,每张存一种属性)→ Visibility Buffer 的"窄而深"(极少 RT,计算时再查)。这是 RT 历史上的一次范式转移。


14.2 Variable Rate Shading(VRS)与 RT

VRS 允许 GPU 对屏幕不同区域以不同的着色频率渲染——中心区域每像素着色,边缘区域可能 2×2 像素共用一次着色。

VRS 对 RT 的影响

传统 RT:每个像素独立。VRS 下:一个 2×2 区域可能只有一个着色值,然后广播到 4 个像素。

┌──┬──┬──┬──┐ │ │ │ │ │ ← 每像素着色(1×1) ├──┼──┼──┼──┤ │ │ │ ← 2×2 组共用一次着色 ├─────┼─────┤ │ │ ← 4×4 组共用一次着色 └───────────┘

RT 本身的分辨率不变——还是每像素一个值。但着色器执行次数减少了。

VRS 需要一张额外的"着色率控制图":

Shading Rate Image: 格式:R8_UINT 尺寸:通常是屏幕尺寸 / 16(每 16×16 像素一个着色率值) 值:0=1×1, 1=1×2, 2=2×1, 3=2×2, 4=2×4, ...

这张图本身也是一种 RT——需要生成、绑定、被 GPU 读取。

VRS 的两种模式

  • Per-Draw VRS:整个 Draw Call 用同一个着色率——不需要额外 RT
  • Per-Tile VRS:通过 Shading Rate Image 控制每个 Tile 的着色率——需要额外的 R8 RT

VRS 的工业落地早于很多人印象中:Wolfenstein II(2018)和Gears 5(2019)是最早应用 Tier 2 VRS 的 3A 游戏。VR 场景中 Foveated VRS(眼动追踪+边缘降频)已是标准配置,在 Meta Quest Pro(2022)上省了约 25% 的片段着色开销。


14.3 Ray Tracing 的输出:UAV 代替传统 RT

硬件光线追踪(DXR / Vulkan Ray Tracing)改变了 RT 的生产方式。

传统光栅化

三角形 → 光栅化 → Fragment Shader → ROP → RT

光线追踪

Ray Generation Shader → TraceRay() → Hit/Miss Shader → UAV Write

光线追踪没有 ROP。输出直接通过RWTexture2D(UAV)写入:

RWTexture2D<float4> outputRT : register(u0); [shader("raygeneration")] void RayGen() { uint2 pixel = DispatchRaysIndex().xy; RayDesc ray = generateCameraRay(pixel); TraceRay(accelerationStructure, ...); // 直接写入 UAV outputRT[pixel] = finalColor; }

对 RT 的影响

维度光栅化光线追踪
输出方式ROP → RT AttachmentUAV Write → Storage Image
混合(Blending)硬件 ROP 免费手动实现
MSAA硬件支持不支持(需要用其他 AA 方案)
随机写入❌ 只能写当前像素✅ 可以写任意位置
管线绑定Render Pass + RT只需要 UAV 绑定

趋势:光线追踪的普及让UAV(Storage Image)成为和传统 RT Attachment 同等重要的输出目标

混合管线

现实中多数游戏采用混合管线——光栅化产生 G-Buffer,光线追踪做反射/阴影/GI:

光栅化 → G-Buffer RT(MRT) 光线追踪 → Reflection RT(UAV) 光线追踪 → Shadow RT(UAV) 光线追踪 → GI RT(UAV) 全屏 Pass → 合成所有 RT → Final Color

RT 的"身份"越来越模糊——有些是 ROP 写的,有些是 UAV 写的,有些是 Compute 写的,但在数据流中它们的角色完全一样。


14.4 Nanite / Virtual Shadow Map / Lumen 中的 RT 使用

UE5 三大件——Nanite、Virtual Shadow Map(VSM)、Lumen——对 RT 的使用都有创新。

Nanite

Nanite 的核心创新是软件光栅化+ Visibility Buffer:

  • 小三角形用 Compute Shader 直接写 Visibility Buffer(Atomic 写入R64_UINT
  • 大三角形用硬件光栅化输出到同一张 Visibility Buffer
  • 最终结果:一张 Visibility Buffer RT + Depth RT

这是 RT 使用的新范式——混合软硬件光栅化,统一输出到同一张 RT

Virtual Shadow Map

传统 Shadow Map 是固定分辨率的。VSM 使用虚拟纹理思想——一张巨大的虚拟 Shadow Map(如 16K×16K),但只实际分配有内容的区域(Page)。

RT 视角:

  • 物理存储是一张 Shadow Map Atlas(多个物理 Page 拼接)
  • 渲染时只渲染发生变化的 Page(增量更新)
  • 每帧实际写入的 Page 数量远小于全部

这是 RT 管理中按需分配思想的极致体现。

Lumen

UE5 的全局光照系统 Lumen 使用了大量 RT:

  • Surface Cache:存储场景表面的低分辨率光照数据
  • Radiance Cache:3D 纹理存储空间中的辐射度
  • Screen Probe:屏幕空间的探针 RT,用于最终 GI 采样
  • Temporal History:多帧累积降噪

Lumen 一帧的 RT 数量可以达到 60~80 张——Frame Graph(RDG)的自动管理成为刚需。


14.5 Bindless Rendering 对 RT 工作流的影响

传统渲染中,每个 Draw Call 需要绑定当前使用的纹理/RT 到特定的 Slot:

// 传统:每次 Draw 前绑定context->PSSetShaderResources(0,1,&shadowMapSRV);context->PSSetShaderResources(1,1,&gbuffer0SRV);

Bindless Rendering 让所有纹理放在一个大的 Descriptor 数组中,Shader 通过索引访问任意纹理:

// Bindless:所有纹理在一个数组中 Texture2D allTextures[] : register(t0, space0); // 无界数组 // Shader 中通过索引访问 float4 shadowValue = allTextures[shadowMapIndex].Sample(sampler, uv);

对 RT 的影响

  1. RT 作为纹理读取变得更灵活——不再受 Slot 数量限制(DX11 最多 128 个 SRV Slot)
  2. Pass 合并更容易——一个 Pass 可以读取"任意多张" RT(通过索引访问 Bindless 数组)
  3. Frame Graph 可以更激进地合并 Pass——不再因为"Slot 不够"而拆分 Pass

14.6 Neural Rendering:从 RT 到 Tensor

AI 渲染正在从"后处理辅助"走向"直接参与渲染管线"。

当前阶段:RT 作为 AI 的输入/输出

传统管线降分辨率渲染 → [低分辨率 RT] → DLSS / FSR 2 / XeSS(AI 网络) → [高分辨率 RT]

这里 RT 只是 AI 网络的输入输出容器。

新兴阶段:NeRF / 3D Gaussian Splatting 与 RT

NeRF(Neural Radiance Fields)3D Gaussian Splatting代表了一类全新的渲染范式——不再手动建模几何体,而是用神经网络或点云表示场景。

从 RT 视角看:

  • NeRF:每条光线通过 MLP 网络查询颜色和密度,最终逐像素写入 UAV。没有三角形、没有光栅化——输出方式和 Ray Tracing 一样是 Compute + UAV。
  • 3D Gaussian Splatting:用可微光栅化器把高斯椭球 Splat 到屏幕上,输出到传统 RT。但排序和 Alpha 混合的实现在 Compute Shader 中完成,涉及 UAV Atomic 操作(类似第 9.7 节的 OIT 链表)。
  • 共同点:输出的 RT 格式仍然是 RGBA16F 或 RGBA32F——但数据含义可能不再是简单的"颜色",而是特征向量(Latent Feature),需要后续的解码网络转换为最终颜色。
3D Gaussian Splatting 数据流: 高斯点云 → Compute 排序 → 光栅化/Splat → [Color RT + Depth RT] ↓ 后续合成管线

未来阶段:Tensor 替代部分 RT?

实验性技术(如 Neural Radiance Cache、Neural Texture Compression)正在探索:

  • 神经网络推理结果直接作为 Lighting 数据——替代传统的 GI RT
  • Tensor Core 做去噪——输入和输出不一定是标准 RT 格式

但目前这些技术还在研究阶段。可以预见的是:

  • RT 的格式可能不再只局限于传统的 RGBA 像素——可能出现Tensor 格式的 RT(如 NV12 用于视频,未来可能有 Latent Feature 格式)
  • GPU 的 Tensor Core / NPU 可能直接参与 RT 的读写
  • Frame Graph 需要能编排"Tensor 操作"和"传统光栅化操作"的混合流
  • RT 的本质不会变——它仍然是"中间结果的持久化"——但"中间结果"不再只是像素颜色,而可能是高维特征向量

14.7 XR 渲染中的 RenderTarget——双目、Foveated、Timewarp

VR/AR 设备对 RT 的使用有几个独特需求。

双眼 RT:每眼一张 vs Multiview 单 Pass 写两层

VR 需要为左眼和右眼各渲染一张图像。两种方案:

方案 A:两遍渲染

Pass 1: Camera=左眼 → RT_Left (单独的 2D RT) Pass 2: Camera=右眼 → RT_Right (单独的 2D RT)

Draw Call 数量翻倍,CPU/GPU 开销大。

方案 B:Multiview / Instanced Stereo

单 Pass: Camera=两眼 → RT_Stereo (Texture2DArray, 2 层) Vertex Shader 中用 gl_ViewIndex / SV_ViewID 区分左右眼 GPU 一次 Draw Call 输出两层

RT 角度:Texture2DArray代替两张独立Texture2D。Draw Call 数减少一半,顶点处理共享。

所有现代 VR API(OpenXR)都推荐 Multiview。

Foveated Rendering:中心高分辨率 + 边缘低分辨率的变尺寸 RT

人眼中央视觉敏锐,边缘模糊。Foveated Rendering 利用这一点,中心区域全分辨率渲染,边缘区域降分辨率。

Fixed Foveated Rendering(FFR)

不追踪眼球,假设用户看中心。用 VRS(第 14.2 节)实现:

  • 中心区域:1×1 着色率
  • 边缘区域:4×4 着色率

RT 大小不变,但带宽大幅降低(边缘像素着色次数少)。

Eye-tracked Foveated Rendering

用眼球追踪硬件确定注视点,动态调整着色率区域。需要每帧更新 VRS Shading Rate Image。

Foveated Rendering 变种——变尺寸 RT

更激进的方案:边缘区域用独立的低分辨率 RT 渲染,最终拼接。

中心 RT: 1440×1440(全分辨率) 左 RT: 360×1440(1/4 宽度) 右 RT: 360×1440 上 RT: 1440×360 下 RT: 1440×360 ↓ 拼接合成 → 最终输出

这种方案需要管理 5 张不同尺寸的 RT,Pass 也要执行多次——复杂度高但带宽节省显著。

Timewarp / Spacewarp 的 RT 缓存需求

VR 的关键挑战是延迟。如果渲染跟不上 90 FPS,用户会感到眩晕。Timewarp / ASW(Asynchronous SpaceWarp)通过复用上一帧的 RT来弥补:

帧 N 渲染完成 → RT_N 存储 帧 N+1 来不及渲染 → 取 RT_N + Depth_N + 当前头部姿态 → 做 Reprojection(根据新姿态重投影旧图像) → 输出到 Back Buffer 下一帧: 帧 N+2 渲染完成 → RT_N+2 存储

RT 需求:

  • 必须保留上一帧的 Color RT + Depth RT——不能被 Pool 回收
  • Reprojection 可能产生"空洞"——被遮挡区域会露出,需要填充
  • Motion Vector RT辅助 SpaceWarp 做运动补偿

这和 TAA 的历史帧需求类似(第 11.10 节),但要求更严格——VR 的 Reprojection 对延迟极其敏感。


本章小结

技术趋势对 RT 的影响
Visibility BufferMRT 从 4~6 张降到 1~2 张
VRSRT 大小不变,但着色率可变;需要额外的着色率控制 RT
光线追踪UAV 成为和 RT Attachment 并列的输出目标
Nanite / VSM / Lumen更多 RT(60~80 张/帧),Frame Graph 成为刚需
BindlessRT 作为纹理读取时不再受 Slot 限制
Neural Rendering未来可能出现 Tensor 格式的 RT
XRTexture2DArray 双目;VRS Foveated;跨帧缓存 RT 用于 Timewarp

不变的本质:不管技术怎么演进,"先画到中间画布,再加工输出"的思想从 1996 年到 2035 年——始终不变。RenderTarget 的名字可能会变,但这个抽象不会消失。


📘精通篇回顾:第十二到第十四章完成了从"怎么用"到"怎么精通"的最后一程——性能优化(第 12 章)教你把带宽砍到平衡点,调试诊断(第 13 章)教你在 RT 出错时系统化地找到病因,前沿展望(第 14 章)让你看到 RT 在 Visibility Buffer、光线追踪、Neural Rendering 等新范式中的形态演变。


📕全书回望:四篇十四章,我们走过了一条完整的路径——从"RT 是什么"(认知篇)到"GPU 怎么写、API 怎么说"(原理篇),再到"MRT/Compute/Frame Graph/经典效果"(实践篇),最后抵达"优化/调试/未来"(精通篇)。回头看,贯穿全书的只有一个不变量:流水线的中间产物需要一个地方暂存,这个地方就是 RenderTarget。载体会变,但需求不会消失。如果你内化了这一点,任何新 API、新 GPU、新范式,都只是"老朋友换了件衣服"。


设计哲学:从 RenderTarget 看技术演进的不变量

💡 回顾全书十四章,RenderTarget 经历了从"一块固定的显存"到"声明式资源图中的虚拟节点"的演变。但剥去所有 API 差异和硬件优化,RT 的本质始终是同一件事:流水线中间阶段的持久化。

编译器领域有个类似的观察:从 Fortran 到 LLVM,语言和后端不断变化,但SSA(Static Single Assignment)这种中间表示的理念从未消失——它只是换了名字、换了载体。RT 亦然:从 GL Renderbuffer 到 Vulkan Image,从 UAV 到 Tensor,从单张纹理到 Frame Graph 中的虚拟句柄——载体在变,但"把计算结果暂存下来、供后续阶段使用"的需求永远存在。

如果你掌握了这个不变量,那么不管未来出现什么新 API、新 GPU 架构、新渲染范式,你都能快速定位 RT 在其中扮演的角色。真正的技术深度,不在于记住每个 API 的调用方式,而在于看穿表面差异背后的统一模式。


🤔 思考题

  1. 如果未来出现一种全新的 GPU 架构,完全没有光栅化管线(纯计算+光线追踪),RT 的概念还会存在吗?会以什么形态存在?
  2. 随着 AI 渲染(Neural Rendering)的发展,"像素"是否还会是 RT 的基本单位?如果 RT 的内容是 Latent Feature 而非颜色值,格式和色彩空间的讨论会怎样变化?
  3. Frame Graph 的声明式范式已经成为现代引擎的标配。下一代的"Frame Graph"会长什么样?可能吸收哪些来自编译器优化、函数式编程的思想?

写在最后

2024 年回头看,RenderTarget 已经从 DirectX 7 时代那张"离屏 Surface",长成了一个包含格式、状态机、Tile Buffer、Subpass、Frame Graph、UAV、Visibility Buffer 的庞大知识体系。但当你合上这本书、打开 RenderDoc 抓下一帧的时候,你会发现——不管管线有多复杂,每一帧的故事仍然是同一个:

数据从一张 RT 流向另一张 RT,直到抵达屏幕。

如果你在读完十四章之后,看到一张新的 RT 时能条件反射地问出三个问题——“它的格式是什么?谁写的、谁读的?生命周期到哪里结束?”——那这本书就完成了它的使命。

技术会迭代,API 会更替,但**"中间画布"这个抽象不会消失**。它可能叫 RenderTarget,可能叫 Storage Image,可能叫 Tensor Buffer——名字不重要。重要的是你已经掌握了看穿它的眼睛。

祝你写的每个像素都落在正确的地方。


恭喜你读到这里。附录中提供了各 API 的代码对照和配套 Demo,帮助你从理论走向实践。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 1:29:05

Win11 下 Gemini CLI 的安装与 Traefik 集成指南

1. 环境准备与Node.js配置 在Windows 11上玩转Gemini CLI的第一步&#xff0c;就是搭建好Node.js运行环境。我强烈推荐使用Node.js 18或更高版本&#xff0c;因为Gemini CLI的部分功能依赖较新的ECMAScript特性。安装Node.js时有个小技巧&#xff1a;不要直接点"下一步&q…

作者头像 李华
网站建设 2026/4/19 17:55:16

2025届最火的AI科研神器推荐榜单

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 用于学术写作辅助范畴的人工智能技术&#xff0c;获得了极为广泛的运用。在开题报告撰写这一…

作者头像 李华
网站建设 2026/4/19 17:52:02

杭电计算机复试编程题保姆级解析:从暴力到双指针,手把手教你拿分

杭电计算机复试编程题深度解析&#xff1a;从暴力破解到算法优化的思维跃迁 第一次面对杭电计算机复试编程题时&#xff0c;很多考生会陷入"能写出来就行"的误区。直到我在模拟测试中因为暴力解法超时被扣分&#xff0c;才真正明白复试考察的不仅是代码正确性&#x…

作者头像 李华