基础图形管线(Rendering Pipeline)

5 阅读3分钟

概念介绍

WebGL 的渲染管线是 GPU 把"数据"变成"屏幕上的画面"的完整流程。理解它是学习 WebGL 的基础,因为你写的每一行代码,都是在管线的某个阶段发挥作用。

整个管线分为以下几个阶段:

CPU 准备数据
    ↓
顶点着色器(Vertex Shader)
    ↓
图元装配(Primitive Assembly)
    ↓
光栅化(Rasterization)
    ↓
片元着色器(Fragment Shader)
    ↓
深度测试 / 混合
    ↓
输出到屏幕

各阶段说明

1. CPU 准备数据

在 JavaScript 中准备好顶点坐标、颜色、纹理等数据,通过缓冲区上传到 GPU。

这是唯一由 CPU 完成的阶段,其余阶段全部在 GPU 上并行执行。

2. 顶点着色器(Vertex Shader)

GPU 对每个顶点运行一次顶点着色器,计算出顶点最终在屏幕上的位置,写入 gl_Position

3. 图元装配(Primitive Assembly)

把顶点连接成图元(点、线、三角形)。例如 3 个顶点组成一个三角形。

4. 光栅化(Rasterization)

把三角形等几何图元转换成一个个像素格子(片元) 。这一步由 GPU 自动完成,开发者无需干预。

5. 片元着色器(Fragment Shader)

GPU 对**每个片元(像素)**运行一次片元着色器,决定该像素最终的颜色,写入 gl_FragColor

6. 深度测试 / 混合

  • 深度测试:判断像素是否被其他物体遮挡,决定是否丢弃
  • 混合:处理透明度,将前后像素颜色合并

7. 输出到屏幕

最终结果写入帧缓冲,显示在 Canvas 上。


结合例子说明

画一个红色三角形的完整管线过程:

① CPU 准备 3 个顶点坐标,上传到 GPU 缓冲区

② 顶点着色器被执行 3 次(每个顶点一次)
   → 计算出三个顶点在屏幕上的位置

③ 图元装配:3 个顶点连接成一个三角形

④ 光栅化:三角形内部被分解成数百个像素格

⑤ 片元着色器被执行数百次(每个像素一次)
   → 每次都输出红色

⑥ 红色三角形出现在屏幕上

代码片段

// ① CPU 准备顶点数据
const vertices = new Float32Array([
   0.0,  0.5,   // 顶点1
  -0.5, -0.5,   // 顶点2
   0.5, -0.5,   // 顶点3
]);

// 上传到 GPU
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
/* ② 顶点着色器:处理每个顶点的位置 */
attribute vec2 aPosition;

void main() {
  gl_Position = vec4(aPosition, 0.0, 1.0);
  /* 光栅化由 GPU 自动完成,无需代码 */
}
/* ⑤ 片元着色器:决定每个像素的颜色 */
void main() {
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色
}
// ⑥ 触发绘制,管线开始执行
gl.drawArrays(gl.TRIANGLES, 0, 3);

总结

阶段执行者开发者是否可控关键输出
CPU 准备数据CPU✅ 完全可控顶点缓冲区
顶点着色器GPU✅ 编写 GLSLgl_Position
图元装配GPU⚙️ 部分可控三角形 / 线 / 点
光栅化GPU❌ 自动执行片元列表
片元着色器GPU✅ 编写 GLSLgl_FragColor
深度测试混合GPU⚙️ 可配置最终像素
输出屏幕GPU❌ 自动执行Canvas 画面

渲染管线是 WebGL 的骨架,后续所有概念(着色器、纹理、光照)都是在这个流程的某个阶段上做文章。理解了管线,学其他概念时就知道自己在"哪一步"工作。