顶点着色器与片元着色器的关系与执行流程解析

240 阅读3分钟

在 GPU 渲染管线中,**顶点着色器(Vertex Shader)片元着色器(Fragment Shader)**是两个最核心的阶段。理解它们的关系和执行顺序,对于掌握 GLSL 或 Three.js/WebGL 编程至关重要。


1. 顶点着色器(Vertex Shader)概述

顶点着色器是 GPU 渲染管线的第一个可编程阶段,主要作用是处理每个顶点的坐标和属性

  • 输入:顶点位置、颜色、法线、UV 坐标等

  • 输出

    • 必须写入 gl_Position,确定顶点在裁剪空间的位置
    • 可通过 out / varying 变量传递给片元着色器

示例(GLSL 3.00 / WebGL2)

out vec3 vColor;       // 传递给片元 shader

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main() {
    vColor = position;  // 顶点属性插值的来源
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

注意:顶点着色器对每个顶点只执行一次,负责计算几何变换和传递属性。


2. 图元组装与光栅化

顶点着色器执行完成后,GPU 会进入图元组装阶段

  • 按渲染模式(如 GL_TRIANGLES)把顶点组合成三角形、线段或点。
  • 三角形在逻辑上已经形成,但尚未映射到屏幕像素。

随后是光栅化阶段(Rasterization)

  • GPU 将三角形投影到屏幕像素网格上
  • 对三角形内部的每个片元,计算顶点属性的插值值(颜色、UV、法线等)
  • 生成的片元成为片元着色器的输入

片元 shader 执行前,三角形已经形成,但只是几何形状,颜色尚未确定。


3. 片元着色器(Fragment Shader)概述

片元着色器在光栅化阶段生成的每个**片元(Fragment)**上执行一次,用于计算最终颜色或深度:

  • 输入:光栅化插值得到的顶点属性
  • 输出:写入 framebuffer 的颜色或深度值

示例(GLSL 3.00 / WebGL2)

precision highp float;

in vec3 vColor;        // 来自顶点 shader 的插值
out vec4 FragColor;    // 输出到 framebuffer

void main() {
    FragColor = vec4(vColor, 1.0); // 输出颜色
}

每个片元 shader 执行一次,每个片元对应屏幕上的一个像素位置。


4. 顶点着色器与片元着色器的关系

特性说明
执行顺序先执行顶点 shader → 图元组装 → 光栅化 → 执行片元 shader
数据传递顶点 shader 的 out / varying 变量会被插值后传入片元 shader 的 in / varying 变量
作用分工顶点 shader:处理几何位置和属性 片元 shader:处理颜色和像素级效果
依赖关系片元 shader 必须依赖顶点 shader 的输出,无法单独计算片元颜色

5. 可视化理解

[顶点数据 Vertex]  -> Vertex Shader (计算 gl_Position, out)
                     |
                     v
            Primitive Assembly (组成三角形)
                     |
                     v
              Rasterization (生成片元)
                     |
                     v
           Fragment Shader (计算每个片元颜色)
                     |
                     v
              Framebuffer (最终显示)
  • 顶点 shader 每个顶点执行一次
  • 三角形在图元组装阶段形成
  • 光栅化阶段生成片元
  • 片元 shader 每个片元执行一次,输出最终颜色

6. 总结

  • 顶点 shader → 片元 shader 是 GPU 渲染管线的核心顺序。
  • 顶点 shader 只处理顶点,片元 shader 才输出颜色。
  • 光栅化阶段负责把顶点属性插值到每个片元。
  • 理解这个关系有助于调试 shader、优化渲染和理解 GPU 内部工作原理。

实践建议

  • 在学习 GLSL 时,可以先写最小 shader(顶点传递 → gl_Position,片元输出纯色),观察顶点属性如何在光栅化后影响片元颜色。
  • 使用 varying / out 变量练习顶点到片元的插值机制。

本文部分内容借助 AI 辅助生成,并由作者整理审核。