WebGPU 光栅化:硬件管线与软件实现
原作者:webgpufundamentals Contributors
原始链接:https://webgpufundamentals.org/webgpu/lessons/webgpu-rasterization.html
原文主旨编译
本文提供一些关于 WebGPU 如何绘制点、线和三角形的细节。渲染管线通常渲染点、线或三角形。计算管线可以直接更新纹理或缓冲区,实际上执行“软件光栅化”。本文讨论前者,有时称为“硬件光栅化”。
原文开篇即点明核心:在 WebGPU 中,渲染管线(render pipeline) 使用 GPU 的固定功能硬件来完成光栅化,而 计算管线(compute pipeline) 则可以在计算着色器中手动实现光栅化逻辑,即软件光栅化。硬件光栅化是实时图形渲染的默认选择,因为它更高效、功耗更低。
深度解读
什么是光栅化?
光栅化(Rasterization)是将几何图元(点、线、三角形)从顶点数据转换为屏幕像素上的片元(fragment) 覆盖信息的过程。在 GPU 图形管线中,光栅化位于顶点处理之后、片元着色之前,是一个固定功能阶段,不可编程。
在 WebGPU 中,渲染管线通过 GPURenderPipeline 描述,其中 primitive 字段定义了图元类型:
"point-list"— 每个顶点渲染为一个点"line-list"/"line-strip"— 每 2 个连续顶点构成一条线段 / 连续的线条"triangle-list"/"triangle-strip"— 每 3 个连续顶点构成一个三角形 / 连续的三角形条带
硬件光栅化 vs 软件光栅化
| 特性 | 硬件光栅化(渲染管线) | 软件光栅化(计算管线) |
|---|---|---|
| 实现方式 | GPU 固定功能单元 | 在 WGSL 计算着色器中手动实现 |
| 性能 | 极高,专为实时渲染优化 | 通常较低,受限于计算单元和内存带宽 |
| 灵活性 | 有限,必须遵循标准规则 | 极高,可实现自定义光栅化算法 |
| 用途 | 常规三角形/线/点渲染 | 体素化、自定义裁剪、剔除、光线投射等 |
原文强调的“软件光栅化”是因为计算管线可以写入纹理或缓冲区,开发者可以完全控制像素覆盖逻辑,但这通常是针对特殊需求的权衡,而非默认选择。
从裁剪空间到纹素
光栅化的输入通常是裁剪空间(clip space) 中的图元坐标。顶点着色器输出裁剪空间坐标,GPU 会对其进行透视除法得到 NDC(归一化设备坐标),然后映射到帧缓冲区的像素坐标(纹素 / texel)。这一过程涉及:
- 裁剪:剔除裁剪空间外的图元
- 透视除法:将齐次坐标转换为 NDC
- 视口变换:将 NDC 映射到像素坐标
- 光栅化:确定图元覆盖哪些像素中心,并生成对应的片元
这些步骤由硬件批量完成,效率远高于任何手动实现。
3 个核心优化要点
-
优先使用硬件光栅化管线
对于常规的点、线、三角形渲染,务必使用GPURenderPipeline。GPU 的光栅化单元专为大规模并行处理设计,内部已深度优化,使用计算着色器手动光栅化会浪费灵活性且性能往往差几个数量级。只有在需要完全自定义的行为(如保守光栅化、体素化)时才考虑计算管线。 -
合理选择图元拓扑减少顶点冗余
使用triangle-strip或line-strip配合索引缓冲区(index buffer)可以大幅减少重复顶点数据,从而降低顶点着色器的调用次数,并提高顶点缓存(post-transform cache)命中率。例如,一个四边形用triangle-list需要 6 个顶点,而用triangle-strip只需 4 个顶点。 -
利用硬件内置的片元阶段优化特性
硬件光栅化器天然支持 Early-Z / 深度测试提前剔除,可以在片元着色器执行前丢弃被遮挡的片元。配合合理的前后渲染顺序、不透明物体优先,可以显著减少无效片元着色。此外,多重采样抗锯齿(MSAA) 也是硬件光栅化的一部分,相比后期处理抗锯齿,其带宽和计算开销更可控。
GLSL/WebGL 专业术语检查
原文讨论的是 WebGPU 技术,其着色语言为 WGSL,并非 GLSL。但用户要求检查 GLSL/WebGL 相关术语,这里列出关键术语的翻译与准确性:
- Rasterization → 光栅化 ✅
- Render pipeline → 渲染管线 ✅
- Compute pipeline → 计算管线 ✅
- Software rasterization → 软件光栅化 ✅
- Hardware rasterization → 硬件光栅化 ✅
- Clip space → 裁剪空间 ✅
- Texel → 纹素 ✅(像素与纹素的区别:纹素是纹理或帧缓冲区中的离散采样点)
- Points, lines, triangles → 点、线、三角形 ✅
- Primitive topology → 图元拓扑 ✅
- Fragment → 片元 ✅(WebGPU 中使用 “fragment”,WebGL/GLSL 中常用 “fragment”,对应概念一致)
注意:WebGPU 的 WGSL 中片元着色器入口为 @fragment,WebGL/GLSL 中是 fragmentShader,虽然语言不同,但术语语义一致。
关于核心代码
原文页面仅包含导航与示意图占位符,未直接提供可运行的代码片段。文章正文主要为概念性介绍,因此没有需要保留的核心代码。如需实际渲染管线示例,可参考 WebGPU Fundamentals 的 “Fundamentals” 章节,其中包含 GPURenderPipeline 的完整配置代码。
