getContext('webgl') 返回 null 主因是 canvas 状态异常或环境限制;着色器需手动检查编译状态与日志;drawArrays 前须启用程序、顶点属性及正确绑定缓冲区;矩阵须以 Float32Array 传入且乘法顺序不可颠倒。
getContext('webgl') 返回 null 是最常见拦路虎,不是代码写错了,而是环境没配好——先解决这个,再谈渲染。
浏览器返回 null 不代表不支持 WebGL,大概率是 canvas 自身状态异常:
display: none、visibility: hidden 或父容器折叠时,getContext('webgl') 会静默失败0(哪怕 CSS 设了尺寸,但 HTML width/height 属性没写)也会触发失败--enable-webgl --ignore-gpu-blacklist 调试experimental-webgl,它已废弃多年,现代浏览器只认 webgl
GLSL 语法错误不会抛 JS 异常,gl.compileShader() 总是“成功”返回,必须手动查状态和日志:
gl.getShaderParameter(shader, gl.COMPILE_STATUS),返回 false 就说明挂了gl.getShaderInfoLog(shader),否则控制台里什么线索都没有attribute/varying 是 WebGL 1(GLSL ES 1.0)用的;如果用了 in/out 却没启用 WebGL 2,就直接报 syntax error
<script type="x-shader/x-vertex"> 标签里用 textContent 读取清屏成功 ≠ 渲染成功。黑屏往往卡在数据流向 GPU 的中间环节:
立即学习“前端免费学习笔记(深入)”;
gl.drawArrays() 前没调 gl.useProgram(program),GPU 根本不知道该跑哪个着色器gl.enableVertexAttribArray(location) 必须在 gl.vertexAttribPointer() 后调用gl.ARRAY_BUFFER,传索引才用 gl.ELEMENT_ARRAY_BUFFER
gl_Position = ... —— 这是强制要求,不赋值就等于没输出,GPU 直接丢弃该顶点WebGL 不管你怎么想,它只认你传进去的 16 个浮点数:
gl.uniformMatrix4fv() 传的是纯数字数组,不是对象;传 mat4.create() 出来的对象会出错,得用 mat4.toArray() 或直接传 Float32Array
model × view × projection 就会坐标系全乱mat4.lookAt() 第二个参数是「看向的点」,不是方向向量;第三个参数是「上方向」,设成 [0,0,0] 会导致矩阵奇异,结果不可预测new Float32Array(16) 创建新矩阵?GC 压力大且慢,复用一个数组 + mat4.identity(dest) 重置更稳真正卡住人的从来不是某一行代码,而是上下文之间那几处隐性依赖:canvas 状态、着色器编译链、属性启用开关、矩阵乘法顺序——它们不报错,但一漏就白忙活半天。