渲染
GPU 与着色器术语表
WebGPU/WebGLShaderGLSL/WGSL术语表
直觉问题
- 刚接触 GPU 渲染时,那些让人晕头转向的缩写究竟是啥意思?Vertex、Fragment、Primitive……这些词和日常英语里的含义完全不同吗?
- 当你看到
vec4<f32>、@location(0)和layout(location = 0)时,能快速认出它们本质是同一回事吗?
这篇笔记的目的就是建立一张“术语地图”,把 GLSL 和 WGSL 世界中的核心概念用一张表串起来,方便你在后续学习中随时查阅。
核心概念白话讲:GPU 渲染为什么需要一套新词汇体系?
CPU 上编程时,我们讲“变量”“函数”“内存地址”。但 GPU 是一个高度并行化的处理器阵列,它处理的是像素、顶点和纹理,有自己独特的硬件和软件概念。
如果把 CPU 编程理解为“指挥一个工人按部就班完成流水线任务”,GPU 编程更像是**“同时指挥成千上万个微型流水线车间,每个车间只负责画面上的一个最小单元”。这种大规模的并发和专精,决定了 GPU 必须有一套围绕空间、颜色、几何图元**展开的独特术语体系。
原理与机制:三大术语板块
1. 核心渲染术语(Geometry & Rasterization)
| 术语 | 定义 | 为什么重要 | 类比 |
|---|---|---|---|
| Vertex | 3D 空间中的一个点,包含位置、颜色、法线等属性 | 一切 3D 模型的基础单元 | 构成物体的“原子” |
| Primitive | 由顶点的连接关系定义的图形(点、线、三角形) | GPU 硬件唯一能直接绘制的图形 | 乐高积木块 |
| Fragment | 经过光栅化后生成的“候选像素”数据 | 代表最终颜色、需要经过所有 Per-Sample 测试 | 一名等待面试的候选人 |
| Pixel | 屏幕上的最终物理点 | 屏幕显示的最小单位 | 工地的最终成果 |
| Rasterization | 将几何图元转换为像素网格上离散的片元/像素的过程 | 连接 3D 世界与 2D 屏幕的关键桥梁 | 连续的画作转化为像素点阵 |
| Shader | 运行在 GPU 上的小程序,处理渲染管线中的特定阶段 | 控制 GPU 如何处理三角形和像素 | 车间里的定制化工序 |
| Texture | 存储在 GPU 上的图像数据(2D/3D),用于贴图 | 用于模拟物体表面细节 | 建筑的外墙贴纸 |
| Draw Call | CPU 向 GPU 发出的“绘制一次”的指令 | CPU 与 GPU 的核心通信方式,是常见的性能瓶颈 | 快递单号 |
2. 核心术语中英对照与缩写表
| 缩写 | 全称 | GL 含义 | 贯穿笔记时的注意事项 |
|---|---|---|---|
| GLSL | OpenGL Shading Language | OpenGL 的着色器语言(WebGL 1.0 原生) | 语法类似 C,面向图形的 C 语言。 |
| WGSL | WebGPU Shading Language | WebGPU 的官方着色器语言 | 语法类似 TypeScript,强类型、显式内存布局。 |
| SPIR-V | Standard Portable Intermediate Representation - Vulkan | 跨平台的着色器中间代码(.spirv 文件) | 通常是 GLSL/HLSL 的编译目标。 |
| RT | Reflection / Ray Tracing | 光线追踪 | 现代 GPU 的硬件级光线(Intersection)计算。 |
| SM | Streaming Multipro (in GPU) | 流多处理器 (NVIDIA) | GPU 并行计算的基本单元。 |
| VBO | Vertex Buffer Object | 存储顶点数据的缓冲区 | 提到“Buffer”时需要确认是 Vertex/Index/Uniform 哪一种。 |
| IBO | Index Buffer Object | 存储索引数据的缓冲区 | 与 VBO 成对使用,组装三角形。 |
| FBO | Framebuffer Object | 离屏渲染目标 | 主要用于多 Pass 渲染、后处理 (Post-processing)。 |
| FBO | Front Buffer Object | 屏幕显示缓冲区 | 双缓冲(Double Buffering)机制的一部分。 |
| MVP | Model-View-Projection | 模型-视图-投影矩阵 | NDC(标准化设备坐标系)的生成过程。 |
| SSBO | Shader Storage Buffer Object | 着色器存储缓冲 | GLSL 中用于通用存储的读写缓冲区。 |
| UBO | Uniform Buffer Object | 着色器常量缓冲区 | 存储视图矩阵、光照颜色等全局数据。 |
| MIP | Mipmap | 多级渐远纹理 | 提升纹理采样质量与性能。 |
| SRGB | Standard Red Green Blue | 非线性色彩空间 | 人眼感知友好,工程中需要线性与非线性转换。 |
| HDR | High Dynamic Range | 高动态范围 | 提高画面亮度和对比度,需要 Tone Mapping。 |
| LDR | Low Dynamic Range | 低动态范围 | 8-bit 颜色通道,屏幕显示的标准格式。 |
| SSAO | Screen Space Ambient Occlusion | 屏幕空间环境光遮蔽 | 局部阴影增强立体感。 |
| MSAA | Multi-Sample Anti-Aliasing | 多样本抗锯齿 | 平滑边缘,性能开销大。 |
| FX | Special Effects | 特效(泛指) | 常指粒子、模糊、HDR 等后处理。 |
| LOD | Level of Detail | 模型细节层次 | 根据距离远近切换模型精度。 |
| SDF | Signed Distance Field | 有向距离场 | 字体和形状渲染与体积渲染的核心技术。 |
3. GLSL vs WGSL 命名对照
核心理念:GLSL 代码风格像 C++,自由灵活但有失规范;WGSL 代码风格像 TypeScript,严格明确但略显冗余。
| 概念 | GLSL / OpenGL (WebGL) | WGSL / WebGPU | 核心区别与注意事项 |
|---|---|---|---|
| 入口函数 | void main() { ... } | @vertex / @fragment fn main(...) {...} | GLSL 没有函数声明与定义分离的需要,WGSL 则要求明确的阶段限定符(Stage Attribute)。 |
| 坐标系属性 | gl_Position (内建) | @builtin(position) _pos : vec4<f32> | GLSL 是全局魔法变量,WGSL 是函数参数 / 返回值上的显式标记。 |
| 输入数据 | attribute vec3 aPos; (WebGL 1) / layout(location=0) in vec3 aPos; (WebGL 2) | @location(0) aPos: vec3<f32> | GLSL 通过 layout 或旧式 attribute 绑定,WGSL 统一通过 @location 标记。 |
| 输出数据 | out vec4 FragColor; | @location(0) FragColor: vec4<f32> | WGSL 的 Fragment Shader 输出也必须显式指定 @location。 |
| 颜色输出 | gl_FragColor (内建) | @location(0) fragColor: vec4<f32> | WebGPU 已废弃内建输出变量,强制使用 @location。 |
| Uniform | uniform mat4 uMatrix; | @group(0) @binding(0) var<uniform> uMatrix: mat4x4<f32>; | WGSL 引入了 Group 与 Binding 双层绑定体系,且资源类型必须显式声明内存存储类别。 |
| 采样器 | uniform sampler2D uSampler; | @group(0) @binding(1) var uSampler: sampler; ... | WGSL 将纹理对象与采样器对象拆开。 |
| 声明缓冲区 | buffer B { float data[]; } ssbo; | 使用 var<storage, read> | WGSL 语法完全不同,显式读写权限。 |
| 阶段修饰符 | #ifdef VERTEX / #else (宏) | @vertex / @fragment / @compute | GLSL 靠条件编译,WGSL 有原生 Stage Attribute。 |
| 构造向量 | vec4(a, b, c, d) | vec4<f32>(a, b, c, d) | WGSL 泛型vec必须带类型(T)。 |
GLSL 与 WGSL 对照:让差异一目了然
Vertex 入口函数示例
# version 300 es // GLSL ES 3.0
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aUV;
out vec2 vUV;
uniform mat4 uMVPMatrix;
void main() {
gl_Position = uMVPMatrix * vec4(aPos, 1.0);
vUV = aUV;
}
// WGSL
struct VertexInput {
@location(0) aPos: vec3<f32>,
@location(1) aUV: vec2<f32>,
};
struct VertexOutput {
@builtin(position) clipPosition: vec4<f32>,
@location(0) vUV: vec2<f32>,
};
@group(0) @binding(0)
var<uniform> uMVPMatrix: mat4x4<f32>;
@vertex
fn main(input: VertexInput) -> VertexOutput {
var output: VertexOutput;
output.clipPosition = uMVPMatrix * vec4<f32>(input.aPos, 1.0);
output.vUV = input.aUV;
return output;
}
口诀:WGSL 的“结构体 +
@location”替代了 GLSL 的“全局in/out+layout限定符”,资源绑定加上了“Group + Binding 双重地址”。
常见误区与陷阱
1. 术语混用导致的歧义
- Fragment ≠ Pixel:很多人将 Fragment(片元)等同于 Pixel(像素)。实际上,Fragment 是光栅化后的“候选者”,Pixel 是通过所有深度测试、模板测试、混合后的胜利者。一个 Pixel 可能被多个 Fragment 竞争(Opaque Pass、Alpha Blending 等)。
2. GLSL 与 WGSL 的 location 含义相差巨大
- GLSL 的
layout(location = 0)修饰的是顶点的输入/输出流的总线地址。 - WGSL 的
@location(0)也是数据绑定的位置,但同时引入@group(0) @binding(0)用于 Uniform 和纹理等资源。 - 致命误区:在 WGSL 中,如果你把 Vertex Shader 的
@location和@group @binding搞混,GPU 将无法匹配资源地址,构建时甚至不报错,运行时画风错乱。
3. 混淆 Shader 的“阶段”和“版本”
- GLSL 的
#version 300 es是编译器指令,不代表 Shader 阶段;WGSL 的@vertex、@fragment、@compute才是阶段指示器。有人试图在 GLSL 文件中写@vertex,WGSL 文件中写#version,显然这是跨语言的“不认路”。
4. 忽视 NDC (Normalized Device Coordinates) 的坐标系
- 在 GLSL 中
gl_Position的x, y, z范围必须是[-1, 1];而在 GLSL 的 WebGL 中gl_Position.y向上为正。 - 但在 WGSL/WebGPU 中,NDC 的
y轴默认向下为负(原点在左上角),与 GLSL 的约定有差异。
延伸阅读与自测
权威索引
- Khronos GLSL 规范: OpenGL Shading Language - 官方 GLSL BP (OpenGL ES 3.2 / Vulkan GLSL)。
- WebGPU WGSL 规范: WebGPU Shading Language - 社区实时规范文档,了解
@group,@binding细节。 - WGSL 快速指南: w3.org / WGSL - W3C 推荐标准,缩写对照。
- GPU Gems: Chapter 28 (Rendering Pipeline): NVIDIA GPU Gems - 深入渲染管线硬件基础。
自测题
- 如果你需要在 Vertex Shader 中传递纹理坐标给 Fragment Shader,WGSL 和 GLSL 在数据声明上有何差异? 请写出 WGSL
struct VertexOutput和 GLSLin/out对应代码。 - 为什么 Fragment 不能直接等同于 Pixel? 结合深度测试和透明物体 Alpha 混合说明。
- WGSL 中
@group(0) @binding(3)和@location(3)作用有何不同? 请举例说明分别用在什么场景下。
参考答案
- [略] WGSL 中将贴图坐标作为
VertexOutput字段加@location;GLSL/V 中使用out vec2 vUV;,对端 F 阶段用in vec2 vUV;。核心差异在“结构体显式声明”对比“全局 magic variable”。 - Fragment 是光栅化生成的候选像素。只有它通过了深度测试、模板测试,写入像素时才成为 Pixel。透明物体需 Alpha 混合,Pixel 颜色可能被多次混合。
@group(0) @binding(3)用于 Uniform Buffer、Texture、Sampler,由pipelineLayout和layout定义。@location(3)用于 Vertex Shader 的输入(Vertex Attributes)和 Fragment Shader 的输出。前者描述的是 GPU Memory / Resources 捆绑,后者是数据通道上的标号。