中EN
概念页

图形栈与渲染引擎架构

Graphics Stack & Rendering Engine Architecture

渲染引擎要解决的"渲染问题"是:给定由场景元素、虚拟光源和虚拟相机组成的虚拟世界,生成相机看到的二维彩色图像。GEA 把它拆成可见性问题和光照问题,按解法把引擎分为光线追踪、深度缓冲光栅化、辐射度和混合四类;光栅化引擎通常采用立即模式的两层结构:下层是图形管线,上层是负责剔除、提交几何和设置着色器参数的应用层。本页讲这套整体架构,管线内部见 渲染管线。

渲染问题的四种看法(卷 II 11.1.1)

  • 数据转换:输入是三维空间中场景元素、光源和相机的数学模型,输出是 W×HW\times H 的二维数组,每个元素(像素)以适合显示设备的数字格式存颜色。
  • 几何问题:物体表面被拆成三角形等简单图元,顶点变换到相机坐标系再投影到屏幕;在屏幕空间可以只连线画线框,也可以填充内部像素,颜色来自纹理和/或光照计算。
  • 可见性判定与着色:相机有 NN 个传感器(像素),先解决可见性问题——找出每个传感器 jj 直接看到的表面点 xj\mathbf{x}_j;再解决光照问题——求每个 xj\mathbf{x}_j 朝相机反射的光的强度和颜色。(MSAA 等技术会让一个像素混合多个表面点,二者并非严格一一对应。)
  • 相机模拟:理解光的行为、光与物质的交互、数码相机怎样测量光子,需要几何光学、光传输物理、辐射度量学与光度学、色彩理论和数值积分。可以接受非真实感时,可做简化:光源当理想点、只算直接光照、把最贵的计算离线预计算;追求真实感时则用有面积的光源和间接光照。

"可见性"一词也指判断某个物体是否可能被相机看到,这是一种避免渲染无贡献物体的优化,即剔除(见 剔除技术)。

渲染引擎的类型(卷 II 11.1.2)

类型可见性怎么解光照怎么解特点
光线追踪从焦点穿过每个像素发射视线 (eye ray),第一个交点即可见点通常也用光线追踪,配合蒙特卡洛积分等随机方法追求照片级真实;每条光线可能与整个场景的任何几何相交,缓存不友好、难以并行,所以昂贵
深度缓冲光栅化表面拆成三角形投影到屏幕,用深度缓冲保留每个像素最近的片元传统上不发射光线:逐顶点算局部光照再插值,或光栅化后逐像素(世界空间或屏幕空间)结合近似局部光照与运行时近似或离线预计算的全局光照三角形、顶点、像素基本相互独立,极易并行,催生了 GPU
辐射度与光栅化技术配合把几何拆成小的有限元,计算每个面元向各方向反射的漫反射光适合只有相机移动的静态场景;难以处理镜面高光、焦散和镜面反射,所以很少作为游戏唯一的光照方案;游戏用的预计算辐射传输 (PRT) 实际上是辐射度方法的离线应用
混合光栅化借助 GPU 硬件光追做有限的光线追踪GEA 对"在光栅化引擎中用部分光线追踪"的称呼

把图形计算从 CPU 移到 GPU 有双重好处:画面保真度远高于 CPU 能做到的,同时 CPU 腾出来做音频、物理、NPC 的 AI 和玩家操控。GEA 认为这也是实时三维渲染几乎一直用光栅化而非光线追踪的另一个原因。光传输理论见 渲染方程,PRT 见 预计算辐射传输,GPU 光追见 硬件光线追踪管线。

原书问题(11.1.2):

  • GEA 说光线投射"缓存不友好、难以并行"。缓存不友好成立(相邻光线,尤其是反弹后的次级光线,访问的几何和 BVH 节点很分散,在 SIMD 硬件上还会发散),但"难以并行"不准确:各像素的光线彼此独立,逐像素光线追踪是"易并行 (embarrassingly parallel)"问题的标准例子(Wikipedia "Embarrassingly parallel",引 Chalmers 等《Practical Parallel Rendering》)。真正的难点是并行之后的访存一致性和每条光线遍历加速结构的代价,而不是能否并行。
  • GEA 把 PRT 说成"实际上是辐射度方法的离线应用",这是简化说法。Sloan、Kautz、Snyder 的原始 PRT(SIGGRAPH 2002,"Precomputed Radiance Transfer for Real-Time Rendering in Dynamic, Low-Frequency Lighting Environments")用蒙特卡洛光线追踪离线算出物体的 SH 传输函数,运行时光照可以动态变化,也能处理光泽反射;只有 Enlighten 一类表面间传输的变体才接近辐射度(形状因子),且也不解辐射度的线性方程组。见 预计算辐射传输(RTR4 11.5.3)。

图形栈(卷 II 11.3.1)

渲染引擎由多层软硬件组成,称为图形栈 (graphics stack)。下图自下而上画出典型的管线式渲染引擎各层。

flowchart BT
    HW["硬件: CPU 与主内存, GPU 与显存"] --> DRV["操作系统与 GPU 驱动"]
    DRV --> API["底层图形 API: OpenGL, D3D, Vulkan, Metal"]
    API --> RE["渲染引擎"]
    RE --> GE["游戏引擎"]
  • 硬件:主板、一个或多个 CPU 核心、多级 CPU 缓存、内存;几乎所有游戏 PC 和主机都有 GPU。GPU 在主机上位于主板,在 PC 上位于扩展卡,直接访问显存(见 GPU 内存、缓冲压缩与多重缓冲、计算机硬件与内存层次)。
  • 操作系统与驱动:PC 上是 Windows、macOS 或 Linux,主机用定制系统(如通过 PS5 SDK 编程的 PS5 系统)。Steam Deck 底层运行 Linux,但通常通过 Windows 兼容层 Proton 运行 Windows 游戏,无需移植。(GEA 原文称 Proton 为"Windows 模拟层",并说 Steam Deck"通过 Proton 编程"。原书问题:Proton 基于 Wine,是把 Windows API/Direct3D 调用翻译成 Linux/Vulkan 调用的兼容层,不模拟 CPU 或硬件(Wine 的名字本身就是 "Wine Is Not an Emulator");开发者照常面向 Windows(或原生 Linux)编程,Proton 是运行时层而非编程接口(Valve Proton GitHub 仓库 README;Wikipedia "Proton (software)")。)
  • 渲染引擎:游戏引擎众多子系统之一,内部通常也是分层的(见 运行时引擎分层架构)。

保留模式与立即模式(卷 II 11.3.1.3)

两种架构都用某种场景图在内存中表示场景内容、支持快速随机访问,都有一个或多个虚拟相机提供视图;区别在于场景图由谁管理:

模式场景图由谁管客户端做什么典型
保留模式 (Retained mode)渲染引擎内部初始填充场景图、每帧更新、请求按各视图渲染;怎么渲染对客户端基本隐藏1980 年代末的 PHIGS(1990 年代中被 OpenGL 取代);辐射度和光线追踪引擎,因为算法需要随机访问整个场景
立即模式 (Immediate mode)上层(应用层)下层是只渲染单个场景元素(三角网格或高阶参数曲面)的数据处理管线;上层管理场景图、配置控制管线、提交元素,图像由各元素的渲染结果合成光栅化引擎的常规做法

立即模式的下层就是三维图形管线,结构由 API 固定,部分阶段可用着色器定制;上层应用层通常是 CPU 上的软件,设计因引擎而异(见 渲染管线 中关于"应用阶段还是应用层"的分歧)。

应用层的三项职责(卷 II 11.5)

  1. 剔除与可见性判定:只把可见(至少可能可见)的物体交给 GPU,见 剔除技术、遮挡剔除,空间组织见 空间数据结构。
  2. 提交几何:把子网格-材质对用 DrawIndexedPrimitive()(DirectX)、glDrawArrays()(OpenGL)之类的调用或直接构建 GPU 命令列表提交给 GPU;可为性能排序;场景需要多遍渲染时同一几何可能提交多次。
  3. 控制着色器参数和渲染状态:按图元配置经常量寄存器传入的 uniform 参数,并设置不可编程阶段的所有可配置参数(见 绘制调用与状态切换优化、图形 API 设备、管线状态与资源)。

边界上移:走向 GPU 驱动与保留模式

  • 应用与管线的边界一直在沿图形栈上移:最早整条管线是 CPU 软件;3Dfx Voodoo 把最贵的后段搬进硬件;GPU 又接管了更多原属应用层的工作。如今的渲染引擎负责配置和场景管理,大部分实际渲染交给 GPU(卷 II 11.3.1.5)。
  • 新趋势是把应用层也以计算着色器的形式搬到 GPU,释放 CPU;加上网格着色器(见 网格着色器管线),GPU 上的管线本身也变得不那么"管线"、更随机访问。GEA 认为这实际上是在回归保留模式,代表是 UE5 的 Nanite(见 Nanite 虚拟化几何体),顽皮狗的引擎也在朝这个方向发展。UE5 的线程与渲染结构见 UE5 渲染架构。

取舍

  • 保留模式把渲染细节对客户端隐藏,客户端只管填充和更新场景图;它适合需要随机访问整个场景的算法(光线追踪、辐射度)。
  • 立即模式由应用层自己管理场景图、配置管线和提交元素,是光栅化引擎的常态;代价是剔除、排序、状态管理等工作都落在应用层(通常是 CPU)上,这正是 GEA 第 11.5 节要讨论的内容。
  • 把应用层搬到 GPU 能释放 CPU 去做其他引擎工作,但会模糊应用与管线的界线,使引擎重新带上保留模式的特点(卷 II 11.3.1.5)。

PBRT 的视角:图形状态与扩展点(PBRT 4e C.2.3–C.4)

  • 两个区块:WorldBegin 之前只能指定相机、胶片、采样器、积分器等全局选项,之后只能指定形状、光源、纹理、材质;变换和介质两边都可以。这样创建形状时相机和分辨率已经确定,例如曲面可以按屏幕覆盖面积立即细分。
  • 图形状态:当前材质、当前变换矩阵 (CTM)、RGB 色彩空间、面光源设定、当前介质。CTM 实际上是两个矩阵(起止时刻),activeTransformBits 决定变换语句作用于哪一个,两者不同就构成动画变换(练习 C.2 建议推广到任意关键帧或时间函数)。Translate() 等把变换右乘到 CTM。AttributeBegin/AttributeEnd 压入、弹出整个 GraphicsState,用于层级建模(先放车身,再相对放车轮)。
  • 变换的内存:单精度下每个 Transform(矩阵及其逆)占 128 字节,用 InternCache 驻留后,形状只存 const Transform *。形状最终使用的是"渲染空间 ← 物体"的变换,需要乘上由相机定义的"渲染空间 ← 世界"变换。
  • 新增一种对象类型的三步:把源文件加入 CMakeLists.txt;把类型名加入对应接口所继承的 TaggedPointer 类型列表;在接口的 Create() 中按名称分派到新类型。
  1. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  2. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.1、11.3.1、11.5 节引言
  3. PBRT 4e source excerpt: chapter C (Processing the Scene Description)
  4. Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)附录 C C.1–C.4 节与延伸阅读,pbr-book.org/4ed/Processing_the_Scene_Description

相关页面

图形学渲染管线Rendering Pipeline渲染管线是实时图形的核心:给定虚拟相机、三维物体、光源等,把场景转换成一张二维图像。RTR4 把它粗分为四个功能阶段:应用、几何处理、光栅化、像素处理,各阶段并行执行,整体速度由最慢的阶段决定。图形学实时渲染Real-Time Rendering实时渲染是在计算机上快速生成图像、并让图像随用户输入即时变化的技术。RTR4 认为它由三个要素共同定义:交互性、三维空间感,以及图形加速硬件 (GPU)。图形学渲染方程Rendering Equation渲染方程 (Kajiya, 1986) 把"某点接收到的光就是其他点发出或反射的光"写成递归积分,概括了光从光源出发经任意次反弹到达眼睛的所有路径。反射方程是它的受限特例。离线用辐射度 (Radiosity) 或蒙特卡洛路径追踪求解;实时渲染则靠简化和预计算逼近它(RTR4 第 11 章)。图形学图形 API 设备、管线状态与资源Graphics API Devices, Pipeline State & Resources所有图形 API(OpenGL、DirectX、Vulkan、Metal)都围绕同一组概念:代表 GPU 的设备、描述各阶段配置的管线状态、承载数据的资源及其视图。GEA 把 API 分成高层(OpenGL、D3D11 及更早)和底层(D3D12、Vulkan、Metal、PlayStation 的 Gnm),并介绍 D3D11 的特性级别、设备上下文与延迟上下文、D3D12 的命令列表、PSO 和根签名。本页按 GEA 的整理讲这些跨 API 的共同概念,不是任何一个 API 的教程。图形学剔除技术Culling Techniques剔除 (culling) 是在渲染前尽快去掉对最终图像没有贡献的部分。本页讲几何类剔除:背面剔除(含成簇背面剔除与法线锥)、视锥剔除(层次化、平面掩码)、室内场景的入口剔除,以及牺牲质量换速度的细节剔除和小三角形剔除。更复杂的遮挡剔除见 遮挡剔除。图形学绘制调用与状态切换优化Draw Calls & State Change Optimization调用图形 API 的开销主要在 CPU 端的驱动里:状态切换昂贵,每次绘制调用有固定开销,大量小批次会让 GPU"饿死"。对策是:合理放置缓冲;按状态代价排序分组;共享纹理和着色器;合并网格和实例化以减少调用;并用一个整数排序键同时兼顾状态分组与前后排序。图形学空间数据结构Spatial Data Structures空间数据结构把几何体按 n 维空间组织起来,通常是层次化的树,使"几何体是否重叠"一类查询从 O(n) 降到大约 O(\log n)。常见类型有包围体层次 (BVH)、BSP 树(轴对齐的 k-d 树与多边形对齐两种)、四叉树/八叉树(含松散八叉树),以及更偏向组织模型关系的场景图。它们是剔除、光线求交、碰撞检测等加速算法的基础。图形学硬件光线追踪管线Hardware Ray Tracing Pipeline高端 GPU 提供硬件加速的光线追踪,它像 GPU 中独立于光栅管线和计算管线的另一条管线,但能与它们协调同步。场景几何要先组织成两层加速结构(TLAS 实例层与 BLAS 几何层),光线发射后由 any-hit、closest-hit、miss 等着色器处理结果。由于还不够快,GPU 光追通常与光栅化结合成混合渲染:先光栅化 G-buffer,再对镜面、反射和间接光发射光线。图形学网格着色器管线Mesh Shader Pipeline网格着色器管线(也叫网格几何管线)是 GPU 厂商为取代传统光栅管线前段而推出的新架构:光栅化器和像素着色器不变,网格着色器和可选的放大着色器(任务着色器)接管顶点、外壳、域和几何着色器的全部工作。它以类似计算着色器的线程组处理叫 meshlet 的小批图元,像启动计算着色器一样启动绘制,还能把部分应用层工作搬到 GPU 上。2019 年进入 DirectX 12,2022 年以 VKEXTmeshshader 扩展进入 Vulkan。游戏开发 · UE5Nanite 虚拟化几何体Nanite Virtualized GeometryNanite 是 UE5 的虚拟化几何体 (Virtualized Geometry) 系统:导入时把网格切成分层的三角形簇 (Cluster),渲染时按相机视角逐簇选择细节层次并无缝拼接,按需从磁盘流送,并在绕过传统绘制调用 (Draw Call) 的独立通道中渲染,使帧预算不再受多边形数、绘制调用和网格内存约束。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。游戏开发运行时引擎分层架构Runtime Engine ArchitectureGregory 把游戏视为“软实时、交互式、基于代理的计算机模拟”,把游戏引擎定义为数据驱动、可复用来做多款游戏的软件。运行时引擎按层组织:从目标硬件、驱动、操作系统、第三方 SDK、平台无关层、核心系统、资源管理器,到渲染、物理、动画、音频、网络等子系统,再到游戏性基础层和游戏专属子系统;上层依赖下层,避免循环依赖。图形学GPU 内存、缓冲压缩与多重缓冲GPU Memory, Buffer Compression & Multiple Buffering带宽是稀缺资源。GPU 通过独立显存或统一内存架构 (UMA)、多级缓存与按瓦片存储提高局部性,并用基于瓦片表的无损压缩和快速清除减少渲染目标的带宽(注意:无损压缩只省带宽,不省内存)。颜色缓冲有高彩、真彩、深色三种模式;显示控制器以固定刷新率或 FreeSync/G-sync 自适应同步把颜色缓冲送到显示器;单/双/三缓冲在撕裂、等待与延迟之间取舍。游戏开发计算机硬件与内存层次Computer Hardware & Memory Hierarchy从冯·诺依曼结构讲起,依次是 CPU 的组成(ALU、VPU、寄存器、控制单元、时钟)、总线与字长、机器语言、汇编和寻址方式,再到内存体系:内存映射、虚拟内存和 TLB,以及为了缩小“内存鸿沟”而设计的寄存器文件、多级缓存(缓存行、标签、组相联、替换和写策略、一致性协议)和 NUMA(PS3 的 SPU 本地存储、PS2 的 scratchpad)。对游戏程序员最重要的结论是:数据要连续、紧凑、顺序访问;热循环的代码要小。图形学遮挡剔除Occlusion Culling遮挡剔除尽早剔除被其他物体挡住的物体,避免它们在 z-buffer 中被光栅化、深度比较甚至着色。本页覆盖遮挡剔除的分类与通用框架、GPU 遮挡查询、层次 Z 缓冲 (HZB) 及其在现代引擎中的简化变体(含两遍法、软件光栅化遮挡),以及在 CPU/GPU 上按物体—簇—三角形多粒度组合剔除并用间接绘制提交的剔除系统。图形学预计算辐射传输Precomputed Radiance Transfer预计算传输 (PRT) 假设几何不变、只有光照变化,预先计算"输入光照 → 场景辐射亮度分布"的传输函数,运行时注入直接光再应用传输。它依赖光传输的线性性:各"基础光源"的单位响应按当前强度加权求和即得完整反弹光照。变体包括 Sloan 的 SH 环境光 PRT、点光源簇 PRT,以及 Enlighten 一类的表面间传输(RTR4 11.5.3 节)。图形学随机光线追踪与路径追踪Stochastic Ray Tracing & Path Tracing光线追踪用投射光线同时解决可见性问题和光照问题。GEA 从最简单的"眼睛光线 + 着色方程"讲起,逐步加入阴影光线、透射光线、用蒙特卡洛估计渲染方程的随机光线追踪、递归间接光照,再到每次只走一条路径的路径追踪、双向路径追踪和 Metropolis 光传输,最后讨论降噪与光线投射效率(GEA4 卷 II 12.6.3–12.6.5)。游戏开发自定义内存分配器Custom Memory Allocators内存从两方面影响性能:动态分配(malloc / 全局 new)很慢,以及访问模式主导现代 CPU 的性能。GEA 的经验法则是「尽量少做堆分配,绝不在紧密循环里做堆分配」,并介绍游戏引擎常用的自定义分配器:栈分配器(含双端栈)、池分配器、对齐分配、单帧与双缓冲分配器;以及如何用栈/池避免碎片,或用碎片整理加指针重定位(智能指针、句柄)解决碎片。

被这些页面引用1 篇

输入关键词开始搜索

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