WebGL - 着色器程序
WebGL - 着色器程序
Section titled “WebGL - 着色器程序”WebGL 利用图形处理器 (GPU) 的强大能力进行渲染。与传统的 CPU 编程不同,你不能直接为每个像素调用 GPU 上的函数。相反,你需要将数据(顶点、纹理)和称为着色器的小程序上传到 GPU。
着色器使用一种类似 C 语言的语言编写,称为 GLSL (OpenGL Shading Language)。具体来说,WebGL 使用 GLSL ES (GLSL for Embedded Systems)。WebGL 1 使用 GLSL ES 1.00,而 WebGL 2 使用 GLSL ES 3.00,后者提供了更多功能和略有不同的语法。
这些着色器程序在 GPU 的核心上并行大规模运行,处理顶点数据并确定像素的颜色。它们定义了 WebGL 渲染管线中可编程的部分。
一个基本的 WebGL 程序需要两种主要类型的着色器:
顶点着色器 (Vertex Shader)
Section titled “顶点着色器 (Vertex Shader)”顶点着色器的主要作用是计算每个顶点的最终位置。它为你发送到 GPU 的每个顶点运行一次。其任务通常包括:
- **顶点变换:**应用模型、视图和投影矩阵,将顶点坐标从模型空间转换到裁剪空间。
- **处理顶点属性:**处理与每个顶点相关的输入数据,例如纹理坐标或法线。
- **将数据传递给片段着色器:**将处理后的数据(如插值颜色或纹理坐标)向下游发送给片段着色器。
在 GLSL ES 1.00 (WebGL 1) 中,输入顶点数据通过 attribute 变量接收。在 GLSL ES 3.00 (WebGL 2) 中,使用 in 变量。
片段着色器 (Fragment Shader) (像素着色器)
Section titled “片段着色器 (Fragment Shader) (像素着色器)”顶点处理并组合成图元(如三角形)后,GPU 会计算屏幕上哪些像素被每个图元覆盖。这个过程称为光栅化。片段着色器(通常称为像素着色器)为图元覆盖的每个潜在像素(片段)运行一次。
它的主要工作是确定每个片段的最终颜色。任务包括:
- **计算颜色:**基于插值的顶点颜色、纹理采样、光照计算等确定像素的颜色。
- **纹理映射:**从纹理(图像)中查找颜色。
- **应用效果:**实现雾或透明度等效果。
最终的输出颜色被分配给一个特殊的内置变量(GLSL ES 1.00 中的 gl_FragColor,或 GLSL ES 3.00 中的用户定义 out 变量)。
用于数据传输的 GLSL 变量
Section titled “用于数据传输的 GLSL 变量”GLSL 提供了特定的变量类型(限定符)来管理数据流,包括 JavaScript 代码和着色器之间的数据,以及顶点着色器和片段着色器之间的数据:
- **属性 (Attributes) (GLSL 1.00 中的
attribute/ GLSL 3.00 中的in):**仅在顶点着色器中使用。接收来自 WebGL 缓冲区 (VBO) 的数据。这些数据随每个顶点而变化(例如,顶点位置、颜色、纹理坐标)。通过gl.vertexAttribPointer等 JavaScript 调用进行链接。 - **统一变量 (Uniforms) (
uniform):**在顶点和片段着色器中都使用。保存对于单个绘制调用来说,所有顶点和片段都保持不变的值(例如,变换矩阵、光源位置、全局颜色)。通过gl.uniformMatrix4fv、gl.uniform3f等 JavaScript 调用设置。 - **可变变量 (Varyings) (GLSL 1.00 中的
varying/ GLSL 3.00 中从 Vertex 着色器out到 Fragment 着色器in):**用于将数据从顶点着色器传递到片段着色器。GPU 会在图元表面上插值(混合)这些值(例如,平滑地混合顶点之间的颜色)。
理解数据如何通过这些变量流动对于编写功能正常的着色器至关重要。
接下来,我们将了解这些概念如何融入整体的 WebGL 图形管线中。