网格着色器管线
Mesh Shader Pipeline
网格着色器管线(也叫网格几何管线)是 GPU 厂商为取代传统光栅管线前段而推出的新架构:光栅化器和像素着色器不变,网格着色器和可选的放大着色器(任务着色器)接管顶点、外壳、域和几何着色器的全部工作。它以类似计算着色器的线程组处理叫 meshlet 的小批图元,像启动计算着色器一样启动绘制,还能把部分应用层工作搬到 GPU 上。2019 年进入 DirectX 12,2022 年以 VK_EXT_mesh_shader 扩展进入 Vulkan。
当今 GPU 的四种管线(卷 II 11.4.6)
| 管线 | 说明 |
|---|---|
| 传统光栅管线 | 固定顺序连接的一组阶段,见 渲染管线 |
| 计算管线 | 独立于光栅管线的通用着色器程序,即 GPGPU,见 计算着色器 |
| 光线追踪管线 | 专用硬件对两层加速结构做实时光线投射,见 硬件光线追踪管线 |
| 网格着色器管线 | 只有两个可编程阶段,却涵盖传统管线全部功能,还能把应用层的许多工作从 CPU 移到 GPU |
四类工作负载可在 GPU 上同时执行,都可由 CPU 提交,部分也可由 GPU 上的着色器发起。
传统管线的问题(卷 II 11.4.6.4)
- 传统光栅管线脱胎于 Voodoo、GeForce 256 的固定功能硬件,存在一些性能局限,已不能很好地对应最新的 GPU 架构。
- 关键问题在大型索引三角形列表:索引理论上让每个顶点只写一次,但每个顶点都要经过顶点着色器,输出要暂存到光栅化器用完为止。显存宝贵,不能为结果另开一个同样大的顶点缓冲,所以传统管线按网格的小"块"分批处理,结果暂存在顶点缓存中,GPU 常常对同一顶点多次运行顶点着色器。
- 离线的顶点缓存优化器能重排顶点减少重复处理,效果可观,但有根本上限(见 三角形带、扇与索引网格)。真正需要的是一种给程序员更多控制、顶点处理更高效、更契合统一着色器架构的新管线。
管线结构
下图是网格着色器管线的阶段,虚线框为可选的放大着色器。
flowchart LR
APP["应用: DispatchMesh / vkCmdDrawMeshTasksEXT"] --> AS["放大着色器 任务着色器"]:::opt --> MS["网格着色器"] --> RS["光栅化器"] --> PS["像素着色器"] --> OM["输出合并"]
APP --> MS
classDef opt stroke-dasharray: 5 5- 网格着色器以线程组运行,源码很像通用计算着色器。每次调用处理一个 meshlet:一组顶点加上说明如何组成三角形(或线)的索引。GPU 和 API 对 meshlet 大小有各种限制,最大顶点数通常在 256 到 1,024 之间。
原书问题(11.4.6.4):"256 到 1,024"偏大。D3D12 规定单个网格着色器线程组最多输出 256 个顶点、256 个图元(DirectX-Specs "Mesh Shader",Output limits);Vulkan
VK_EXT_mesh_shader要求maxMeshOutputVertices/maxMeshOutputPrimitives至少 256,主流实现报告的也就是 256。实际推荐的 meshlet 更小:NVIDIA 建议 64 顶点 / 126 图元,AMD 建议约 64–128(NVIDIA "Introduction to Turing Mesh Shaders";AMD GPUOpen "Mesh shaders on AMD RDNA graphics cards")。 另:GEA 在 11.4.6 开头说网格着色器管线"只有两个可编程阶段",但其图 11.51 和本节正文都表明像素着色器仍然保留,可编程阶段实为放大(任务)着色器、网格着色器、像素着色器三个;被两个新阶段取代的只是传统管线前端的顶点、外壳、域、几何着色器(及输入装配)。 - 网格着色器可以对 meshlet 做任何处理,把数量可变的输出顶点和图元直接送进光栅化器,数量不必与输入一致;它不经过传统的输入装配器。这让它完全掌控哪些图元最终被光栅化,也更自然地映射到现代 GPU 的 SIMD 核心。
发起绘制
- 传统管线用 draw call 给出要渲染的顶点和索引数量;网格着色器管线则像启动计算着色器一样,用三维网格启动网格着色器线程组:DirectX 12 用
DispatchMesh,Vulkan 用vkCmdDrawMeshTasksEXT。 - 线程组既可由 CPU 上的应用启动,也可由放大着色器(任务着色器)在 GPU 上直接启动。放大着色器同样采用计算着色器的编程范式,启用时在网格着色器之前运行,能启动网格着色器线程组,但不能启动自己的新实例。
与传统几何放大的区别
- 外壳/细分器/域着色器和几何着色器通过把输入面片拆成更多更细的网格来放大几何;放大着色器则通过发起任意数量的网格着色器调用来放大。
- 传统的细分功能可以由放大着色器与网格着色器协作模拟(见 曲面细分与几何着色器)。
特性级别与硬件
GEA 表 11.2 中,网格着色器管线从特性级别 11_0 起为可选,在 12_2 成为必需(见 图形 API 设备、管线状态与资源)。
取舍
- 好处:程序员拥有更大权力,顶点处理效率更高,更契合统一着色器架构;剔除等应用层工作可以随之移到 GPU,与 Nanite 一类 GPU 驱动渲染的方向一致(见 图形栈与渲染引擎架构、Nanite 虚拟化几何体)。
- 代价:需要较新的硬件和 API 支持(DX12 2019 年、Vulkan 2022 年才引入);绘制模型从"提交顶点和索引"变成"启动线程组",引擎的网格数据组织需要相应改为 meshlet。GEA 只做概览,推荐进一步阅读 AMD 和 NVIDIA 关于网格着色的文章。
出处
- Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.4.6、11.4.6.4 节