Featured image of post 从 WebGL 过渡到 WebGPU 以获得更快的图形速度Featured image of post 从 WebGL 过渡到 WebGPU 以获得更快的图形速度

从 WebGL 过渡到 WebGPU 以获得更快的图形速度

讨论由 WebGPU 支持的现代画布渲染管道,改进旧版 WebGL 的处理能力。

从 WebGL 过渡到 WebGPU 以获得更快的图形速度

十多年来,WebGL 一直是浏览器中硬件加速 3D 图形的唯一标准。它基于 OpenGL ES 构建,公开了一个在其时代运行良好的状态机 API,但会带来大量 CPU 开销,并且缺乏对现代 GPU 功能的直接访问。输入 WebGPU — 专为现代 GPU 架构全新设计的下一代图形和计算 API。

WebGPU 不仅仅是“WebGL 3.0”。它是一个低级的显式 API,使开发人员能够对 GPU 资源、着色器编译和命令调度进行细粒度控制。其设计反映了 Vulkan、Metal 和 DirectX 12,使其功能强大且可跨所有主要平台移植。


关键概念:适配器、设备、队列和着色器

WebGPU 引入了四个基本对象来取代 WebGL 的隐式状态机:

概念目的
适配器表示物理 GPU(集成或离散)。枚举适配器以选择最佳硬件。
设备适配器的逻辑句柄。所有 GPU 资源(缓冲区、纹理、管道)都是从设备创建的。
队列将编码命令提交给 GPU。 WebGPU 使用单个队列来处理图形和计算工作。
着色器WGSL(WebGPU 着色语言)编写,在管道创建时编译。
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const queue = device.queue;

这种显式模型消除了隐藏的驱动程序启发法,从而提供可预测的性能和更低的开销。


WGSL:WebGPU 着色语言

WGSL 是一种现代着色器语言,具有类似 Rust 的语法,专为安全高效的 GPU 编程而设计。与 GLSL(由 WebGL 使用)不同,WGSL 强制执行严格的类型、显式内存布局和内置安全检查。

@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4f {
    let positions = array(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
    return vec4f(positions[in_vertex_index], 0.0, 1.0);
}

@fragment
fn fs_main() -> @location(0) vec4f {
    return vec4f(1.0, 0.0, 0.0, 1.0);
}

WGSL 直接编译为 GPU 的中间表示(Vulkan 上的 SPIR-V、Apple 上的 Metal IR),从而消除了运行时着色器编译开销。


计算着色器:超越图形

WebGPU 最具变革性的功能之一是原生计算着色器支持。与纯粹面向图形的WebGL不同,WebGPU可以直接在浏览器中执行通用GPU(GPGPU)计算。

计算着色器启用:

  • 物理模拟 — 粒子系统、布料模拟
  • 图像处理 — 实时滤镜、颜色分级
  • 机器学习推理 — 通过 ONNX 运行时执行小型模型
  • 数据解析 — JSON/CSV 并行处理
@compute @workgroup_size(64)
fn cs_main(@builtin(global_invocation_id) id: vec3u) {
    let idx = id.x;
    output_buffer[idx] = input_buffer[idx] * 2.0;
}

这为以前需要本机应用程序的基于浏览器的科学计算打开了大门。


渲染管线:显式且高效

WebGPU 的渲染管道遵循现代绑定组模型。所有资源(缓冲区、纹理、采样器)都收集到不可变的绑定组中,并且管道使用固定配置进行编译。

const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: {
    module: shaderModule,
    entryPoint: 'vs_main',
    buffers: [vertexBufferLayout]
  },
  fragment: {
    module: shaderModule,
    entryPoint: 'fs_main',
    targets: [{ format: 'bgra8unorm' }]
  },
  primitive: { topology: 'triangle-list' }
});

这消除了困扰 WebGL 的昂贵的状态更改,在这种情况下,切换着色器或缓冲区布局会导致驱动程序重新编译。


相对于 WebGL 的性能优势

基准测试一致显示,在绘制调用较多的场景中,WebGPU 的性能优于 WebGL 2-5×。主要改进包括:

  • 降低 CPU 开销 — 显式资源管理减少了驱动程序工作
  • 降低绘图调用成本 - 现代管道模型批处理效率更高
  • 异步计算 - 重叠计算和图形工作负载
  • 无需着色器重新编译 - 预编译的 WGSL 消除了 JIT 停顿
  • 内存控制 — 显式缓冲区映射和对齐

对于具有 10,000 多个绘制调用的场景,WebGPU 保持稳定的帧速率,而 WebGL 会下降到个位数。


浏览器和库支持

截至 2026 年,WebGPU 在 ChromeEdgeFirefoxSafari 中保持稳定(通过 WebGPU 实验标志)。所有主要 3D 库都已采用或正在迁移到 WebGPU:

  • Three.js — 通过 WebGPURenderer 的 WebGPU 渲染器(来自 r160+)
  • Babylon.js — WebGPU 作为 v7.0+ 中的默认后端
  • PlayCanvas — WebGPU 实验渲染器
  • wgpu-native — 本机应用程序的 Rust 实现
// Three.js WebGPU example
import { WebGPURenderer } from 'three/examples/jsm/renderers/webgpu/WebGPURenderer.js';
const renderer = new WebGPURenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

WebGL 的迁移策略

对于现有的 WebGL 代码库,建议逐步迁移:

  1. 分析渲染 — 识别 WebGL 瓶颈
  2. 采用库 — Three.js 或 Babylon.js 抽象 API 更改
  3. 原型计算通道 — 为繁重的模拟工作添加 WebGPU 计算
  4. 使用回退 — 功能检测 WebGPU,在不支持的设备上回退到 WebGL
if (typeof navigator.gpu !== 'undefined') {
  // Use WebGPU renderer
} else {
  // Fall back to WebGL
}

## 结论

WebGPU 代表了浏览器图形的范式转变。其低级、明确的设计可提供本机级性能,同时保持跨设备的便携性。对于构建 3D 体验、数据可视化或基于浏览器的计算应用程序的开发人员来说,迁移到 WebGPU 不仅仅关乎速度,还关乎访问现代 GPU 的全部功能。

从 WebGL 的过渡正在顺利进行,库支持已经成熟,浏览器覆盖范围也接近普遍。现在是时候为您的下一个图形密集型 Web 项目采用 WebGPU 了。