createshader()仅创建空的着色器对象(webglshader),类型为gl.vertex_shader或gl.fragment_shader;它不加载、解析或编译glsl代码,后续需配合shadersource()和compileshader()完成源码注入与编译。

createShader 是什么,它不负责编译着色器代码
createShader 只是创建一个空的着色器对象(WebGLShader),类型由参数 gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER 指定。它不读取字符串、不解析 GLSL、也不检查语法。真正把 GLSL 源码“塞进去”并编译,靠的是 shaderSource + compileShader。
常见错误现象:createShader 返回 null —— 通常是因为 WebGL 上下文未正确初始化,或传入了非法 type(比如写成 "vertex" 字符串);而着色器黑屏/白屏/报错,则几乎全是后续步骤出问题。
- 必须先用
gl.createShader(gl.VERTEX_SHADER)创建顶点着色器对象,再用gl.createShader(gl.FRAGMENT_SHADER)创建片元着色器对象 - type 参数只能是
gl.VERTEX_SHADER或gl.FRAGMENT_SHADER,不能是数字或字符串 - 每个着色器对象只能绑定一次源码;重复调用
shaderSource会覆盖,但不会自动重新编译
怎么把 GLSL 字符串正确加载进着色器对象
用 shaderSource 把字符串传给着色器对象,再立刻调用 compileShader。顺序不能反,且必须在 compileShader 后检查编译状态,否则失败时你完全不知道哪行 GLSL 写错了。
示例片段:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, `attribute vec4 a_position;
void main() {
gl_Position = a_position;
}`);
gl.compileShader(vs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
console.error('顶点着色器编译失败:', gl.getShaderInfoLog(vs));
}
-
shaderSource的第二个参数必须是字符串,不能是 DOM 元素或数组;若从<script type="x-shader/x-vertex"></script>标签读取,记得用.textContent或.innerHTML - GLSL ES 1.0(WebGL 1)中,
main()必须存在,且返回类型/参数必须匹配 shader 类型;片元着色器必须写gl_FragColor(WebGL 2 改为out vec4 fragColor) -
getShaderInfoLog在编译失败时才可能有内容,成功时可能返回空字符串,不要把它当常规日志用
为什么 compileShader 后还不能直接用
编译成功的着色器对象只是“就绪”,不是“可用”。WebGL 要求把顶点和片元着色器都编译好后,再通过 createProgram → attachShader → linkProgram 组合成一个可执行的着色器程序(WebGLProgram)。漏掉链接(linkProgram)或链接失败,useProgram 就不会生效。
- 链接失败的典型原因:顶点着色器输出的变量名与片元着色器输入不一致(如顶点写了
v_color,片元却声明in vec4 color) - 链接阶段还会检查 attribute 和 uniform 是否被实际使用;未使用的 attribute 可能被优化掉,导致
getAttribLocation返回 -1 - 务必检查
getProgramParameter(program, gl.LINK_STATUS),链接失败时getProgramInfoLog才有有效错误提示
容易被忽略的兼容性细节
WebGL 1 和 WebGL 2 对 GLSL 版本、内置变量、精度限定符要求不同。多数人用 WebGL 1,但没显式声明 #version 100,浏览器可能默认按旧规则解析,导致某些驱动上行为不一致。
- 顶点着色器开头建议加
#version 100,片元着色器也加,并在片元中声明精度(如precision mediump float;),否则部分 Android 设备会编译失败 - WebGL 1 不支持
in/out布局修饰符(如layout(location=0)),attribute 必须用bindAttribLocation预设,或依赖链接后的自动分配 -
createShader创建的对象不可复用:不能把同一个 shader 对象既 attach 到 program A 又 attach 到 program B;每次换 program 都要新建 shader 并重编译
最常卡住的地方不是 createShader 本身,而是把编译、链接、使用三个阶段当成一个动作去调试。只要分开验证每一步的返回值和状态,问题基本定位得很快。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










