中EN
概念页

合并阶段与帧缓冲

Merging & Framebuffer

更新于 2026-10-12 约 6 分钟基础缓冲区混合

合并阶段把像素着色算出的片元颜色和缓冲区里已有的颜色结合起来,同时负责深度测试、模板测试和混合。它通常不可编程但高度可配置,也叫 ROP(光栅操作或渲染输出单元)。帧缓冲是系统中所有缓冲区的总称。

合并阶段负责什么

  • 可见性:用 深度缓冲 决定哪个图元可见。
  • 混合 (Blending):把新颜色和已有颜色混合,用来实现透明、颜色累积等效果。混合通常通过 API 配置,而不是编程;有些 API 支持光栅顺序视图 (raster order views),也叫像素着色器排序,可以实现可编程混合。

Early-Z(提前深度测试)

如果一个片元跑完像素着色器后才发现被挡住,之前的计算就全浪费了。所以很多 GPU 会在像素着色器之前先做深度测试(以及模板、裁剪矩形测试),被挡住的片元直接剔除,这叫 early-z。

  • 如果像素着色器会修改深度或者discard,early-z 通常就无法使用而被关闭,管线效率会变差。
  • DirectX 11 和 OpenGL 4.2 允许强制开启 early-z,但有不少限制。
  • 用好 early-z 对性能影响很大(RTR4 第 18.4.5 节)。

混合的能力和限制

  • 最常见的是颜色和 alpha 值的乘、加、减组合,也支持最小值、最大值和位运算。
  • DirectX 10 的双源颜色混合 (dual source-color blending):像素着色器输出两个颜色和帧缓冲混合,不能和多渲染目标一起用。
  • 多渲染目标也支持混合,DirectX 10.1 起每个缓冲区可以用不同的混合方式。
  • 可编程混合可以用 ROV 实现,但有性能代价(见 像素着色器)。
  • 输出不变性 (output invariance):不管像素着色器结果的生成顺序如何,API 都要求按输入顺序(逐物体、逐三角形)送到合并阶段。

DirectX 把这个阶段叫 output merger,OpenGL 叫 per-sample operations。

各种缓冲区

缓冲区存什么用途
颜色缓冲 (Color Buffer)每个像素的 RGB 颜色最终显示的内容
Alpha 通道每个像素的不透明度透明效果(RTR4 第 5.5 节)
深度缓冲 (Z-Buffer)每个像素的深度可见性判断
模板缓冲 (Stencil Buffer)通常每像素 8 位记录图元绘制的位置,用来控制之后哪些地方可以写入颜色和深度

模板缓冲例子:先在模板缓冲里画一个实心圆,之后只允许在圆内渲染。游戏里常用来做传送门、镜子、描边、遮罩等特效。

双缓冲 (Double Buffering)

为了不让玩家看到画面一点点被画出来,渲染在屏幕外的后缓冲里进行,画完后与正在显示的前缓冲交换。交换通常在垂直回扫 (vertical retrace) 期间进行,这时交换是安全的,也就是常说的垂直同步,可以避免画面撕裂。更多缓冲方式见 RTR4 第 5.4.2、23.6、23.7 节。

GEA 的视角:帧缓冲的图像平面与输出合并器(卷 II 11.3.4.3、11.3.11、11.4.6.1)

帧缓冲由多个图像平面组成

GEA 把帧缓冲整体看作多个与颜色缓冲同尺寸的图像平面 (image planes):一个存颜色,其余存各种逐像素数据(卷 II 11.3.4.3)。

  • 深度缓冲:存每个像素的深度。因为存的是投影后齐次点的 z 或 w 分量,也叫 z-buffer 或 w-buffer。通常与模板缓冲合成一个深度/模板平面:最早的 GPU 用每像素 32 位,24 位定点深度加 8 位模板;如今也支持 16 位和 32 位浮点深度。

    原书问题(11.3.4.3):主流 API 中没有 16 位浮点深度格式。16 位深度是归一化定点 DXGI_FORMAT_D16_UNORM / VK_FORMAT_D16_UNORM,浮点深度只有 32 位的 D32_FLOAT(及带模板的 D32_FLOAT_S8X24_UINT)(MS Learn "DXGI_FORMAT enumeration";Vulkan 规范 "Depth/stencil formats")。另外"最早的 GPU 用 D24S8"也偏简化:早期 3D 加速卡(如 3dfx Voodoo)只有 16 位深度缓冲,24 位深度加 8 位模板是后来(RIVA TNT 一代)才普及的。

  • 模板缓冲:每像素通常 8 位整数,可以统计像素被绘制的次数,或给像素编码 ID。例如把敌方 NPC 标为 1、其他几何标为 0,渲染后查模板值就知道某像素是不是敌人。
  • 传送门例子:Valve 的《Portal》中,主场景模板值为 0,橙色门为 1,蓝色门为 2;先画主场景,再限制只在模板为 1 的像素上从橙色门视角重画场景,然后对蓝色门做同样的事,共三遍。这与本页「模板缓冲例子」的思路相同,GEA 给了完整的多 pass 流程。
  • G-buffer:除颜色、深度、模板外再加平面(如屏幕空间速度、法线)时,整个帧缓冲常被称为 G-buffer,用于屏幕空间光照(见 延迟着色)。

深度测试与深度写入可以分开开关

  • 深度测试失败的片元被丢弃;通过测试的片元可以再做深度写入。两者可以独立开关:关闭测试,所有片元都会写颜色;关闭写入,片元不影响之后的深度测试(卷 II 11.3.11)。
  • 用法和实例见 深度缓冲 中的 GEA 部分。
  • 裁剪矩形测试 (scissor test):只允许落在一个或多个屏幕矩形内的片元写入,例如把三维场景画进二维 UI 中的一个矩形窗口(卷 II 11.3.11.1)。

输出合并器的别名与职责

  • 也叫光栅输出单元/光栅操作管线 (ROP),AMD 称为渲染后端 (RB)。主要工作是 alpha 混合,同时负责深度和模板测试、深度写入,以及把 MSAA 的多个采样合并成一个输出像素。
  • Direct3D 9 及更早的特性级别中它还做 alpha 测试;Direct3D 10 起不再支持 alpha 测试,需要在像素着色器中实现类似功能(卷 II 11.4.6.1)。这与 深度缓冲 中"早期 API 用 alpha 测试、现在用 discard"的说法一致。
  1. realtime_rendering_4ed.pdf 第 2 章 The Graphics Rendering Pipeline
  2. realtime_rendering_4ed.pdf 第 3 章 The Graphics Processing Unit
  3. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  4. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.3.4.3、11.3.11、11.4.6.1 节

相关页面

图形学渲染管线Rendering Pipeline渲染管线是实时图形的核心:给定虚拟相机、三维物体、光源等,把场景转换成一张二维图像。RTR4 把它粗分为四个功能阶段:应用、几何处理、光栅化、像素处理,各阶段并行执行,整体速度由最慢的阶段决定。图形学深度缓冲Z-Buffer深度缓冲是几乎所有图形硬件用来解决可见性的算法:为每个像素存一个当前最近图元的深度值,新片元更近才写入颜色和深度。它简单、和图元数量成线性关系、允许大多数图元以任意顺序绘制,但不能直接处理半透明。图形学像素着色器Pixel Shader像素着色器(OpenGL 里叫片元着色器)对光栅化产生的每个片元运行,用插值后的顶点数据算出颜色,也可以输出不透明度、修改深度或直接丢弃片元。多渲染目标让它一次输出多组数据,催生了延迟着色。它通常只能写自己所在的像素,但能通过 2×2 quad 拿到相邻像素的导数。图形学透明渲染与 Alpha 混合Transparency & Alpha Blending本页讲最简单的"视角相关"透明:半透明物体只衰减其后方物体的颜色。z-buffer 每像素只存一个表面,所以透明物体通常要从后往前用 over 运算符混合;顺序无关透明 (OIT) 方法用多遍渲染、逐像素链表或近似公式避免排序,各有内存、性能或准确性代价。预乘 alpha 让过滤、混合和合成更正确高效。图形学抗锯齿Antialiasing渲染本质上是采样,采样频率不足就会混叠(锯齿、闪烁的"萤火虫"、车轮倒转)。屏幕空间抗锯齿在每个像素取多个样本并加权求和:超采样最直接但最贵,MSAA 每像素只着色一次,时间抗锯齿 (TAA) 把样本分散到多帧,形态学方法 (FXAA/SMAA) 作为后处理重建边缘。没有一种方法在所有方面最好。图形学阴影基础与阴影体Shadow Basics & Shadow Volumes阴影帮助玩家判断物体的位置。精确光源只产生硬阴影,面光源产生带本影和半影的软阴影。最简单的情况是投射到平面上的投影阴影;投影纹理可把阴影扩展到曲面;阴影体用模板缓冲计数,能在任意表面得到精确硬阴影,但开销极不稳定,如今很少使用。图形学像素与帧缓冲优化Pixel & Framebuffer Optimization需要着色的像素通常远多于顶点,所以像素处理优化往往最划算。核心手段:保证占用率以隐藏纹理延迟、按距离切换着色器 LOD、利用 early-z 并通过从前往后排序或 z-prepass 减少过度绘制、缩小帧缓冲每像素存储(色度子采样、YCoCg 棋盘),以及只在需要时开启混合、避免 GPU 回读。几何与光栅化阶段的常用优化也一并列出。图形学剔除技术Culling Techniques剔除 (culling) 是在渲染前尽快去掉对最终图像没有贡献的部分。本页讲几何类剔除:背面剔除(含成簇背面剔除与法线锥)、视锥剔除(层次化、平面掩码)、室内场景的入口剔除,以及牺牲质量换速度的细节剔除和小三角形剔除。更复杂的遮挡剔除见 遮挡剔除。图形学贴花渲染Decal Rendering贴花 (decal) 是叠加在表面上的图案或纹理,如轮胎印、弹孔、玩家喷漆、标志。贴花可只改颜色(纹身)、只改凹凸(压印标志)或换成完全不同的材质(车窗贴纸),可多个叠在同一几何上,也可横跨多个模型。主流做法是用有向盒做正交投影的投影贴花;延迟着色把贴花效果直接写进 G-buffer,分簇前向着色则把贴花像光源一样放进簇列表。图形学GPU 内存、缓冲压缩与多重缓冲GPU Memory, Buffer Compression & Multiple Buffering带宽是稀缺资源。GPU 通过独立显存或统一内存架构 (UMA)、多级缓存与按瓦片存储提高局部性,并用基于瓦片表的无损压缩和快速清除减少渲染目标的带宽(注意:无损压缩只省带宽,不省内存)。颜色缓冲有高彩、真彩、深色三种模式;显示控制器以固定刷新率或 FreeSync/G-sync 自适应同步把颜色缓冲送到显示器;单/双/三缓冲在撕裂、等待与延迟之间取舍。图形学多边形三角化Polygon Triangulation模型数据很少恰好是渲染需要的格式。图形 API 和硬件都针对三角形优化,所以复杂多边形要先剖分 (tessellation),最常见的是三角化 (triangulation)。本页讲三维数据的来源、三角化算法(耳切法、凸剖分、模板缓冲法)、四边形对角线选择与纹理扭曲,以及边缘裂缝和 T 型顶点。图形学线框与线条渲染Wireframe & Line Rendering实心"硬"线条看似简单,却在 CAD、选中高亮、技术插图中很重要。难点在于:线与三角形位于同一位置时如何保证线在前面;如何隐藏或淡化被遮挡的线;线交叉时如何用光晕表现前后关系。图形学延迟着色Deferred Shading延迟着色先用一遍几何 pass 把所有可见表面的材质参数写入多张渲染目标(G-buffer),再以后处理方式对这些存储值逐光源计算光照,从而把"几何可见性"与"光照"彻底解耦,并把材质与光源分离。它避免了着色的过度绘制、简化了着色器管理、天然适合贴花,但 G-buffer 占用显存和带宽,且难以直接支持透明和 MSAA。本页也覆盖前向渲染下限制光源影响范围的基础手段与"光照预通道 (light prepass)"类混合方案。图形学可编程着色器与 GPU 管线Programmable Shaders & GPU PipelineGPU 把第 2 章的概念管线实现为一组硬件阶段,分为完全可编程、可配置但不可编程、完全固定三类。现代 GPU 采用统一着色器架构:各类着色器共用同一套编程模型和核心,由 GPU 自行分配负载。着色器用 HLSL、GLSL 等类 C 语言编写,输入分为 uniform 和 varying 两类。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原