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」这个说法——确实,
默认坐标系是二维的,但 元素本身只是 WebGL 的 ** 绘制表面 **,不是渲染逻辑的限制者。你往 canvas.getContext('webgl') 里传一个带 z 坐标的顶点数组,GPU 就真会按 3D 方式光栅化。
HTML 本身不渲染,Canvas + WebGL 才构成 3D 渲染链
HTML 是结构描述语言,不负责图形绘制;真正承载 WebGL 的是 元素。关键点在于:
-
定义的是像素画布尺寸,不是逻辑坐标范围;gl.viewport()才决定实际渲染区域 - WebGL 上下文(
WebGLRenderingContext)完全脱离 DOM 布局模型,gl.clearColor()、gl.drawArrays()等调用不触发重排 重绘 - 你可以把
放在里用 CSS 3D 变换旋转,但这和 WebGL 内部的 3D 渲染无关——那是两个独立的 3D 层:CSS 变换作用于 canvas 元素整体,WebGL 在 canvas 内部绘制 3D 场景为什么 有人觉得“HTML 只能 2D”
这种印象通常来自以下真实但易混淆的场景:
立即学习 “ 前端免费学习笔记(深入)”;
- 用
canvas.getContext('2d')时,所有绘图 API(fillRect、drawImage)确实是纯 2D 的,没有 z 轴概念 - CSS 的
transform: translateZ()或perspective只影响元素盒模型的视觉层叠与透视变形,并不生成真正的 3D 几何体或深度缓冲 - 初学者常误把 Three.js 的
Mesh当成 HTML 元素——其实它只是 WebGL 渲染指令的封装,最终仍落在一个上 - 部分低端设备或旧浏览器禁用 WebGL,回退到 2D canvas 模拟(如某些老版
three.js的CanvasRenderer),加剧了“HTML=2D”的错觉
一个最小可验证的 WebGL 3D 渲染片段
下面代码创建一个旋转的彩色立方体,仅依赖原生 WebGL,无任何库:
const canvas = document.getElementById('gl-canvas'); const gl = canvas.getContext('webgl'); if (!gl) throw new Error('WebGL not supported');// 顶点着色器(含 z 坐标)const vs =
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); };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();
注意其中
vec4(aPosition, 1.0)明确携带 z 分量,gl.DEPTH_BUFFER_BIT启用深度测试——这就是标准 3D 渲染流程。只要浏览器支持 WebGL,这段代码就在屏幕上跑出真正的三维空间。容易被忽略的是:WebGL 的 3D 是“裸金属级”的,没有默认相机、灯光或材质系统;所有矩阵变换(
uModelViewMatrix、uProjectionMatrix)都得自己算或用数学库补全。这也是为什么多数项目直接上 Three.js ——它不是替代 WebGL,而是把那些必须写的几十行矩阵逻辑封装掉了。 - 用































