WebGL是专为HTML页面实时3D渲染设计的GPU加速接口,本质是OpenGL ES的JavaScript绑定,支持完整渲染管线与深度测试等3D功能;其3D能力独立于HTML/CSS的2D布局模型,依赖canvas作为绘制表面并通过着色器处理z坐标实现真三维光栅化。

WebGL 是浏览器里的 3D 渲染引擎
能。WebGL 不是“能能不能”的问题,而是专为在 HTML 页面中做实时 3D 渲染而设计的接口。它本质上是 OpenGL ES 2.0(后来是 ES 3.0)的 JavaScript 绑定,直接调用 GPU 执行顶点着色器和片元着色器,渲染管线完整,支持深度测试、模板缓冲、帧缓冲对象(FBO)、纹理采样、光照计算等全部基础 3D 功能。
常见误解来自「HTML 是 2D」这个说法——确实, HTML 是结构描述语言,不负责图形绘制;真正承载 WebGL 的是 这种印象通常来自以下真实但易混淆的场景: 立即学习“前端免费学习笔记(深入)”; 下面代码创建一个旋转的彩色立方体,仅依赖原生 WebGL,无任何库: // 顶点着色器(含 z 坐标)
const vs = const program = gl.createProgram();
gl.attachShader(program, gl.createShader(gl.VERTEX_SHADER, vs));
gl.attachShader(program, gl.createShader(gl.FRAGMENT_SHADER, fs));
gl.linkProgram(program);
gl.useProgram(program); const positions = new Float32Array([
// 立方体 8 个顶点(x, y, z)
-1,-1,-1, 1,-1,-1, 1,1,-1, -1,1,-1,
-1,-1, 1, 1,-1, 1, 1,1, 1, -1,1, 1
]);
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW); const aPosition = gl.getAttribLocation(program, 'aPosition');
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0); function render() {
gl.clearColor(0.1, 0.1, 0.2, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 8);
requestAnimationFrame(render);
}
render(); 注意其中 容易被忽略的是:WebGL 的 3D 是“裸金属级”的,没有默认相机、灯光或材质系统;所有矩阵变换( 默认坐标系是二维的,但 元素本身只是 WebGL 的**绘制表面**,不是渲染逻辑的限制者。你往 canvas.getContext('webgl') 里传一个带 z 坐标的顶点数组,GPU 就真会按 3D 方式光栅化。HTML 本身不渲染,Canvas + WebGL 才构成 3D 渲染链
元素。关键点在于:
定义的是像素画布尺寸,不是逻辑坐标范围;gl.viewport() 才决定实际渲染区域WebGLRenderingContext)完全脱离 DOM 布局模型,gl.clearColor()、gl.drawArrays() 等调用不触发重排重绘
放在
为什么有人觉得“HTML 只能 2D”
canvas.getContext('2d') 时,所有绘图 API(fillRect、drawImage)确实是纯 2D 的,没有 z 轴概念transform: translateZ() 或 perspective 只影响元素盒模型的视觉层叠与透视变形,并不生成真正的 3D 几何体或深度缓冲Mesh 当成 HTML 元素——其实它只是 WebGL 渲染指令的封装,最终仍落在一个 上three.js 的 CanvasRenderer),加剧了“HTML=2D”的错觉一个最小可验证的 WebGL 3D 渲染片段
const canvas = document.getElementById('gl-canvas');
const gl = canvas.getContext('webgl');
if (!gl) throw new Error('WebGL not supported');
attribute vec3 aPosition; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); };
const fs = precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0); };vec4(aPosition, 1.0) 明确携带 z 分量,gl.DEPTH_BUFFER_BIT 启用深度测试——这就是标准 3D 渲染流程。只要浏览器支持 WebGL,这段代码就在屏幕上跑出真正的三维空间。uModelViewMatrix、uProjectionMatrix)都得自己算或用数学库补全。这也是为什么多数项目直接上 Three.js ——它不是替代 WebGL,而是把那些必须写的几十行矩阵逻辑封装掉了。











