# 想在页面里跑一点 GPU 绘制或计算，WebGPU 按 MDN 入门要先过哪些门槛？

**URL:** <https://www.shiqidu.com/t/topic/1989>\
**Category:** 开发调优\
**Tags:** JavaScript, 前端开发, WebGL, 浏览器, 问与答\
**Created:** [2026 年11 月 9 日 02:51 UTC](https://www.shiqidu.com/t/topic/1989 "2026-11-09T02:51:53Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![shiqidu\_editor](https://www.shiqidu.com/user_avatar/www.shiqidu.com/shiqidu_editor/32/528_2.png) [@shiqidu\_editor](https://www.shiqidu.com/u/shiqidu_editor)\
发布日期： [2026 年11 月 9 日 02:51 UTC](https://www.shiqidu.com/t/topic/1989/1 "2026-11-09T02:51:53Z")

</div>

WebGL 画三角形还能凑合，一上通用计算或更现代的管线就显得拧巴。MDN 把 [WebGPU API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) 写成 WebGL 的后继：更贴现代 GPU API，图形和通用计算（GPGPU）都一等公民。想试之前，把「能不能申请到设备」和「安全上下文」摸清，别一上来就抄完整渲染管线。

## 确认一下：不是 Baseline，还要 HTTPS

页首标着 **Limited availability / not Baseline** ——不是「所有常用浏览器都开箱可用」。对照 MDN 兼容数据，Chrome / Edge 一线已有实现，Safari 从 **26** 起有支持记录，Firefox 从 **141** 起是部分实现（平台限制写在兼容说明里，例如 Linux、部分 macOS 配置仍可能不可用）。具体版本看你打开的兼容表，正文不编市场份额。

整页还强调： **仅在安全上下文（HTTPS，本地 `localhost` 一类例外按浏览器规则）可用** 。普通 `http://` 页面上 `navigator.gpu` 往往直接没有，这和「显卡驱不驱动」无关。

## 和 WebGL 差在心智，不在「再学一门 GLSL 方言」

WebGL 更贴近「把东西画到 canvas」。WebGPU 把 **render pipeline** （顶点 + 片元）和 **compute pipeline** （计算着色器）拆开。着色器用 **WGSL** ，不是把旧 GLSL 原样搬过来。MDN 也提醒：底层还有 Adapter（物理 GPU / 驱动抽象）和逻辑 `GPUDevice`（给单个网页隔离用的设备句柄）。多应用共用一块 GPU 时，这层隔离是安全模型的一部分，不是可有可无的包装。

## 最小探测：从 `navigator.gpu` 到 `requestDevice`

文档给的起步形状大致是：

```js
async function init() {
  if (!navigator.gpu) {
    throw new Error("WebGPU not supported.");
  }
  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw new Error("Couldn't request WebGPU adapter.");
  }
  const device = await adapter.requestDevice();
  return device;
}

```

`requestAdapter()` 可带偏好（高性能 / 低功耗等）。省略则用默认适配器。拿不到 adapter 时，常见原因是：浏览器未实现、当前平台未开，或 GPU / 驱动组合不在支持列表里。这时应做功能降级（继续用 Canvas 2D / WebGL，或提示用户换环境），而不是假设「装个扩展就能解锁」。

需要跑在较老图形栈上时，文档还提到 **compatibility mode** （`requestAdapter({ featureLevel: "compatibility" })`），那是受限子集，用来贴近 OpenGL ES 3.1 / Direct3D 11 一类后端。默认仍是 core。可用 `device.features.has("core-features-and-limits")` 判断还在不在 core。

## 真正干活：管线、缓冲、命令队列

探测通过后，才轮到 MDN 后半的结构：

1. 用 WGSL 写着色器，经 `device.createShaderModule` 装进模块。
2. 若要画到页面，取 canvas 的 `"webgpu"` 上下文并 `configure`。
3. 数据放进 `GPUBuffer` / 纹理。渲染或计算各自建 pipeline。
4. `createCommandEncoder` → begin pass → 设 pipeline / 绑定资源 → `draw` 或 `dispatchWorkgroups` → `queue.submit`。

计算管线常要再 `copyBufferToBuffer` + `mapAsync`，才能把结果读回 JS。错误是异步校验的：非法调用会在 GPU 侧传染式标成 invalid，可用 `pushErrorScope` / `popErrorScope` 抓第一处问题。这些细节 MDN 示例页写得很长，入门阶段先保证「有 device、有一条能跑的 pass」即可。

## 渲染 demo 和计算 demo 不必一次上齐

MDN 后半分别给了「画三角形」和「算一数组再读回 JS」两套最小例子。业务若只是后处理滤镜或粒子，先跑通 render pass。若是把矩阵运算丢 GPU，先跑通 compute + staging buffer。两边共用「先有 device」这一步，但 buffer 用途标志（`VERTEX`、`STORAGE`、`MAP_READ` 等）不同，抄错 `usage` 会在校验阶段直接失败。

画布格式别写死成某一种：文档建议用 `navigator.gpu.getPreferredCanvasFormat()`，在 `bgra8unorm` / `rgba8unorm` 里选对当前设备更合适的那个，再交给 `configure`。自己猜格式容易在部分平台上多一次无谓转换。

## 渐进增强，别把能力写成硬门槛

产品侧更稳妥的说法是：有 WebGPU 就走加速路径，没有就退回已有实现。不要把挖矿、破解或绕过浏览器限制写进业务。安全上下文和权限边界按文档来。WGSL 模块、管线描述符都可以按功能拆文件，但首屏加载不加载整段 GPU 代码，仍建议按需。

你们目标机型上 `navigator.gpu` 和 `requestAdapter()` 各自返回什么？有没有必须支持的最低浏览器集合？
