跳到主要内容

渲染管线与着色器

一次 draw* 会跑完当前绑在上下文上的整条管线。CPU 侧没有「当前 path」;有的是 program + VAO + 纹理单元 + 一堆全局状态。状态漏绑,失败形态是「画面黑 / 颜色错 / 只有第一帧对」。

1. 阶段

CPU 顶点数组
→ vertex shader(clip space)
→ 图元装配 / 光栅
→ fragment shader(像素颜色)
→ 深度 / 模板 / 混合
→ drawing buffer 或 FBO

WebGL2 是 可变全局状态机useProgrambindVertexArraybindTexture 一直生效到你改掉。热路径里不要「画之前随手 bind 一下」却从不还原——下一趟 draw 会吃到脏状态。

WebGPU 把大部分状态收进 pipeline + bind group,提交时不可变。迁移时不要把 GL 的「全局 gl 对象」思维带过去。

2. 最小 WebGL2 program

export function compileProgram(
gl: WebGL2RenderingContext,
vertSrc: string,
fragSrc: string,
): WebGLProgram {
const vs = compile(gl, gl.VERTEX_SHADER, vertSrc);
const fs = compile(gl, gl.FRAGMENT_SHADER, fragSrc);
const program = gl.createProgram();
if (!program) throw new Error("createProgram failed");
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const log = gl.getProgramInfoLog(program) ?? "link failed";
gl.deleteProgram(program);
throw new Error(log);
}
gl.deleteShader(vs);
gl.deleteShader(fs);
return program;
}

function compile(
gl: WebGL2RenderingContext,
type: number,
src: string,
): WebGLShader {
const shader = gl.createShader(type);
if (!shader) throw new Error("createShader failed");
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader) ?? "compile failed";
gl.deleteShader(shader);
throw new Error(log);
}
return shader;
}

适用:自己的渲染器、后处理 pass。
不适用:把 GLSL 字符串拼进业务组件、每帧 compileShader。编译和 link 是 CPU 尖刺,启动或热更新时做一次。

WebGPU 对应 device.createShaderModule({ code: wgsl }) + createRenderPipeline。pipeline 创建同样是重操作,缓存起来。

3. 清屏不是 fillRect

gl.clear 清的是当前绑定的 framebuffer。你绑了 FBO 却以为在清 canvas,结果屏幕上一帧旧图。绘制前显式:

gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);

4. 失败形态

症状原因
链接成功但全黑attribute 没开、VAO 空、或 VS 写出了 clip w=0
换物体颜色串台上一次 useProgram / uniform 没改干净
第一帧对、之后花误删 shader,或丢失上下文后还在用旧 program
编译失败只在真机#version 300 es 精度、扩展宏、移动端驱动

权威资料

核对日期:2026-08-26