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

WebGL 画三角形还能凑合,一上通用计算或更现代的管线就显得拧巴。MDN 把 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

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

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() 各自返回什么?有没有必须支持的最低浏览器集合?