WebGPU:浏览器为什么能跑 3D、滤镜和部分 AI

WebGPU 让网页能更直接地使用 GPU 做渲染与通用计算。本文从 CPU 与 GPU 的分工讲起,拆解适配器、设备、缓冲区、WGSL 着色器和命令队列,并说明什么时候并行计算真的值得。

WebGPU:浏览器为什么能跑 3D、滤镜和部分 AI

浏览器里的 3D 游戏、照片滤镜、视频特效,甚至一部分端侧 AI 推理,都在做同一件事:把大量相似的小计算同时交给 GPU。以前网页主要通过 WebGL 接触 GPU,WebGPU 则提供了更现代、更明确的图形与通用计算接口。W3C 对它的定义很直接:WebGPU 暴露了在 GPU 上进行渲染和计算的 API。WebGPU 规范

一块图形处理器

GPU 快,不是因为它有一个更快的 CPU

CPU 像一位很聪明的总管,擅长处理复杂、分支很多的任务;GPU 更像一座拥有大量工位的工厂,擅长让很多工位同时执行相似的步骤。

把一张图片变成黑白图,每个像素都可以独立计算:读取红、绿、蓝三个通道,再按同一套公式得到灰度值。CPU 可以一个个像素处理,GPU 则能把成千上万个像素分发给并行执行单元。

但“并行”不等于“所有任务都该上 GPU”。如果任务只有几次字符串拼接,调度 GPU 的准备成本反而可能比计算本身还高。WebGPU 的价值是让开发者能更直接地表达大批量、规则明确的工作。

从 JavaScript 到 GPU,中间发生了什么

一个 WebGPU 程序通常经过这条链路:

  1. 通过 navigator.gpu 请求适配器,了解浏览器能使用的 GPU 能力。
  2. 从适配器申请逻辑设备和命令队列。
  3. 创建缓冲区、纹理、采样器等 GPU 资源。
  4. 编写 WGSL 着色器,描述每个并行线程要做什么。
  5. 把计算或绘制命令编码出来,提交到队列。
  6. 等 GPU 执行完,再把结果显示到画布或读回 CPU。

这里最重要的概念不是“调用一个神奇函数”,而是资源和命令的边界。JavaScript 负责准备数据,着色器负责定义大量相同的计算,队列负责把命令送给 GPU。GPU 不会理解你的业务对象,它只看缓冲区、纹理和指令。

着色器到底在写什么

下面是一个简化的 WGSL 计算着色器。它让每个 GPU 线程把输入数组中的一个数字乘以 2:

@group(0) @binding(0)
var<storage, read> input: array<f32>;

@group(0) @binding(1)
var<storage, read_write> output: array<f32>;

@compute @workgroup_size(64)
fn double_value(@builtin(global_invocation_id) id: vec3<u32>) {
  output[id.x] = input[id.x] * 2.0;
}

global_invocation_id 可以理解成当前线程的编号。线程 0 处理第 0 个元素,线程 1 处理第 1 个元素,彼此不需要等待。图像卷积、矩阵乘法和粒子模拟都可以用类似思想拆成大量小工作。

当然,真正的性能取决于很多细节:数据是否连续、线程之间是否需要同步、显存访问是否规律、工作组大小是否适合硬件,以及 JavaScript 和 GPU 之间是否频繁搬运数据。把数据来回复制几次,可能轻易吃掉并行计算带来的收益。

WebGPU 和 WebGL 的关键区别

WebGL 更接近“浏览器替你管理很多状态”的旧式接口。WebGPU 把设备、资源、绑定和命令编码讲得更清楚,允许浏览器在提交前做更严格的验证,也更贴近现代图形 API 的资源模型。

这带来两面性:

  • 好处是状态更明确,复杂项目更容易组织,通用计算也更自然。
  • 代价是学习曲线更陡,要理解缓冲区、绑定组、管线和着色器。
  • 浏览器不能把底层 GPU 的所有细节原样暴露出来,所以仍然要经过权限、能力和安全验证。
  • 不同设备的 GPU 能力不同,不能默认所有格式、精度和特性都存在。

WebGPU 也不是“在网页里直接运行 CUDA”。它是一套跨平台 Web API,浏览器会把它映射到系统可用的图形后端,同时限制资源访问,避免网页拿到任意设备内存。

什么时候值得用

最适合 WebGPU 的任务有三个特征:数据量大、单个元素的计算相似、结果能在 GPU 上连续使用。比如实时图像处理、粒子特效、3D 场景、矩阵运算和部分机器学习推理。

如果页面只是渲染几十个按钮,WebGPU 是明显的过度设计。若任务需要频繁读取 GPU 中的每一个小结果,或者算法分支极多、数据量很小,CPU 可能更合适。工程上应先测量:上传数据、执行命令、同步等待和读回结果各花了多少时间,而不是只看 GPU 的理论算力。

一份实用的落地清单

  • 把大数组和纹理尽量批量上传,减少频繁的小提交。
  • 让 GPU 上的计算形成连续流水线,避免每一步都读回 CPU。
  • 对设备能力做探测和降级,准备 WebGL 或 CPU 路径。
  • 将 WGSL 着色器当成独立模块测试,验证边界和越界访问。
  • 用浏览器开发者工具观察 GPU 时间,而不是用 JavaScript 函数耗时替代它。

一句话带走

WebGPU 的核心不是“网页终于有了一个更酷的画布”,而是浏览器开始允许你把一大批相似工作打包交给 GPU。真正的难点也从“能不能画出来”变成了“数据如何布局、什么时候同步、怎样让并行真的值得”。

延伸阅读

KEEP READING