HTML中WebGL的着色器程序基本结构讲解

作者:袖梨 2026-06-07
WebGL着色器程序必须包含顶点和片元着色器两个独立部分,分别编译后链接为program;顶点着色器必须输出vec4类型的gl_Position,片元着色器必须声明精度(如precision mediump float),attribute/uniform/varying用途不可混淆。

WebGL着色器程序必须包含顶点着色器和片元着色器两个部分,缺一不可;它们是独立编译、再链接成一个 program 对象的,不是单个文件或函数。

顶点着色器必须输出 gl_Position

这是硬性要求——GPU 渲染管线靠它确定顶点在裁剪空间中的位置。如果漏写或写错(比如拼成 gl_Postion),gl.linkProgram() 会成功,但后续调用 gl.drawArrays() 时完全不渲染,且无明显报错。

  • gl_Position 必须是 vec4 类型,第四个分量(w)通常设为 1.0;若做透视除法,w 不能为 0
  • 常见错误:直接赋值 vec3(如 gl_Position = aPosition;)→ 编译失败,错误信息类似 "cannot convert from 'vec3' to 'vec4'
  • WebGL2 中支持 #version 300 es,此时需用 out vec4 vPosition; + 自定义输出变量,但 gl_Position 仍是强制出口

片元着色器必须声明精度(precision

WebGL1(GLSL ES 1.0)不允许省略浮点精度限定符,否则编译直接失败,错误信息为 "missing precision qualifier"。这和桌面 OpenGL 不同,是嵌入式规范的强制约束。

  • 常用写法:precision mediump float;(推荐默认),highp 在某些移动 GPU 上可能不被支持
  • 如果用了 intuint 运算,还需加 precision mediump int;
  • WebGL2 中仍需精度声明,但允许用 #version 300 es 后改用 out vec4 fragColor; 替代 gl_FragColor

attributeuniformvarying 的用途不能混用

三者作用域和生命周期完全不同,写反会导致数据传不进去、插值失效或链接失败。

立即学习“前端免费学习笔记(深入)”;

  • attribute:仅顶点着色器可读,从 JavaScript 的缓冲区(ARRAY_BUFFER)按顶点逐个传入,比如 aPositionaTexCoord
  • uniform:JS 通过 gl.getUniformLocation() 设置,顶点/片元着色器都可读,且整个绘制批次内保持不变(如投影矩阵 uMVPMatrix
  • varying:顶点着色器写、片元着色器读,GPU 自动对每个片元做线性插值(如把顶点颜色传给片元着色器);WebGL2 中改用 in/out 配对替代

最容易被忽略的是:着色器字符串里的换行和空格不影响逻辑,但 #version 必须是源码第一行(前面不能有任何空白或注释),否则 WebGL 会静默降级到 1.0,导致 layout(location = x) 等语法失效。

相关文章

精彩推荐