webgpu
写在前面
WebGPU 是 W3C 制定的下一代浏览器图形与计算 API,对标 Vulkan、Metal 与 DirectX 12。它通过命令缓冲区、显式资源管理与原生计算着色器(Compute Shader)支持,绕开了 WebGL 的全局状态机瓶颈,能更充分地压榨现代 GPU 的并行算力,是 Web 端迈向高性能渲染与 GPGPU 的关键技术。
一句话理解:WebGPU = 「Web 版的现代原生 GPU API」,不是 WebGL 的小升级,而是一次架构层面的代际跃迁。
核心特性
一、更现代的 GPU 抽象
- API 底座:由 W3C 联合 Apple、Google、Mozilla、Microsoft 共同设计,目标是成为统一跨平台的 Web 图形标准。
- 底层映射:Chrome 基于 Dawn(封装 Vulkan/Metal/DX12),Firefox 基于 wgpu(同样封装底层原生 API)。
- API 风格:从 WebGL 的「单例全局状态机」演进为「显式设备 + 命令队列」,更接近原生图形 API 的思维方式。
二、显式资源管理
- 通过
GPUDevice(逻辑设备)申请显存资源(Buffer、Texture、Sampler)。 - 通过
GPUCommandEncoder录制命令缓冲区,最后一次性提交到GPUQueue,由驱动调度执行。 - 资源生命周期由开发者精确控制,避免了 WebGL 时代「黑盒状态」带来的内存泄漏与不可预期行为。
三、新的着色器语言:WGSL
- 全称 WebGPU Shading Language,Rust 风格的强类型语法。
- 通过
@location、@builtin、@group/@binding等注解描述顶点属性、内建变量与资源绑定。 - 编译期可校验、可分析,错误信息比 GLSL 友好得多。
四、原生计算着色器(Compute Shader)
- WebGL 想做 GPGPU 只能借助「渲染到纹理」的旁路技巧,性能与功能都受限。
- WebGPU 提供一等公民的计算管线,可直接在 GPU 上做并行数值计算、图像处理、机器学习推理等任务。
五、更高的性能上限
- 减少驱动层验证开销,CPU 侧提交命令的「验证-翻译」成本显著降低。
- 支持现代特性:实例化渲染、间接绘制(Indirect Draw)、多线程指令构造等。
- 实测中复杂场景下往往能拿到 2~3 倍于 WebGL 的帧率(具体收益视场景而定)。
与 WebGL 的核心差异
| 维度 | WebGL | WebGPU |
|---|---|---|
| API 底座 | OpenGL ES | Vulkan / Metal / DX12 |
| 状态管理 | 全局状态机 | 命令缓冲区(显式) |
| 着色器 | GLSL(C 风格) | WGSL(Rust 风格,强类型) |
| 并行能力 | 单线程提交 | 多线程、计算着色器 |
| 资源控制 | 隐式、由驱动管理 | 显式、由开发者管理 |
| 浏览器支持 | 全面(IE11+ 时代就有) | 较新(Chrome 113+、Edge 113+、Safari 17+) |
| 性能上限 | 60~70% GPU 利用率 | 80~90% GPU 利用率 |
想看更完整的代码级对比(GLSL vs WGSL、Three.js vs 原生 API、Uniform 绑定差异等),可阅读 WebGPU 与 WebGL 对比详解。
快速上手:一个最小三角形
// 1. 拿到适配器与设备
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter!.requestDevice();
// 2. 拿到 canvas 上下文并配置
const canvas = document.querySelector("canvas")!;
const context = canvas.getContext("webgpu")!;
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format });
// 3. 编写 WGSL 着色器
const shaderModule = device.createShaderModule({
code: `
@vertex
fn vs(@location(0) position: vec2<f32>) -> @builtin(position) vec4<f32> {
return vec4<f32>(position, 0.0, 1.0);
}
@fragment
fn fs() -> @location(0) vec4<f32> {
return vec4<f32>(0.2, 0.7, 1.0, 1.0);
}
`,
});
// 4. 构建顶点缓冲 + 渲染管线
const vertices = new Float32Array([-0.5, -0.5, 0.5, -0.5, 0.0, 0.5]);
const vertexBuffer = device.createBuffer({
size: vertices.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vertexBuffer, 0, vertices);
const pipeline = device.createRenderPipeline({
layout: "auto",
vertex: {
module: shaderModule,
entryPoint: "vs",
buffers: [
{
arrayStride: 8,
attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }],
},
],
},
fragment: {
module: shaderModule,
entryPoint: "fs",
targets: [{ format }],
},
primitive: { topology: "triangle-list" },
});
// 5. 提交一帧
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: [
{
view: context.getCurrentTexture().createView(),
loadOp: "clear",
storeOp: "store",
clearValue: { r: 0.13, g: 0.16, b: 0.19, a: 1.0 },
},
],
});
pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);
pass.draw(3);
pass.end();
device.queue.submit([encoder.finish()]);
可以看到:WebGPU 没有 gl.drawArrays,取而代之的是「命令录制 → 提交」两阶段流程,这是它最核心的心智模型变化。
适用场景与避坑
适合 WebGPU 的场景:
- 大规模数据可视化(地图、海量点位、粒子系统)
- Web 端 ML 推理(ONNX Runtime Web / Transformers.js 的后端)
- 复杂 3D 编辑器、游戏(Three.js
WebGPURenderer、Babylon.js Native) - 任何被 WebGL 状态机 / GPGPU 旁路限制「卡到瓶颈」的项目
当前阶段的注意点:
- 浏览器兼容:仍需为 Safari < 17、微信内置浏览器等环境提供 WebGL 降级方案。
- 学习曲线:相比 Three.js 封装下的 WebGL,原生 WebGPU 概念更多(Pipeline、BindGroup、CommandEncoder…)。
- 调试工具:Chrome DevTools 的 WebGPU Inspector 仍在演进,线上问题排查比 WebGL 略繁琐。
学习路径建议
- 理解图形管线基础:顶点 → 装配 → 光栅化 → 片段 → 输出(推荐先看 WebGL 教程目录)。
- 对照 WebGL 学习:在 WebGPU vs WebGL 对比详解 中按代码逐节对照,迁移心智模型。
- 从 Three.js 入手:直接使用
three/addons/webgpu/WebGPURenderer.js,用熟悉的 API 享受底层性能。 - 深入原生 API:尝试用原生 WebGPU 重写一个小 Demo,把命令缓冲区、绑定组、计算管线「玩明白」。
知识延伸导航
- WebGPU vs WebGL 对比详解:架构、代码、性能、迁移策略全维度对比
- Three.js WebGPU 渲染器:用熟悉的 Three.js 语法快速体验 WebGPU
- W3C WebGPU 规范:最权威的标准定义
- WGSL 规范:着色器语言参考