Skip to content

面向游戏开发者的 WebGPU 入门指南

WebGPU 是 WebGL 的继任者。它的层级更低、更明确,并且专为现代 GPU 而设计。如果你要在 2026 年启动一个新的 3D 项目,WebGPU 值得学习。

WebGPU 教程:通过 10 个项目,涵盖从环境设置到带光照和动画的 3D 渲染

1) 检查浏览器支持情况

js
if (!navigator.gpu) {
  console.error('WebGPU not supported')
}

截至 2026 年,Chrome、Edge、Firefox 和 Safari 均已支持 WebGPU。

2) 获取设备

js
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter.requestDevice()

适配器代表物理 GPU,设备则是你与其交互的接口。

这两个调用都可能失败。系统没有可用的 GPU 时,requestAdapter() 会返回 null,而 requestDevice() 可能会拒绝请求,因此继续之前需要进行防护检查:

js
const adapter = await navigator.gpu.requestAdapter()
if (!adapter) throw new Error('No suitable GPU adapter found')
const device = await adapter.requestDevice()

从适配器创建设备后,该适配器也会被消耗,因此如果需要另一个设备,请重新请求一个适配器。

3) 配置画布

js
const canvas = document.getElementById('game')
const context = canvas.getContext('webgpu')
const format = navigator.gpu.getPreferredCanvasFormat()

context.configure({
  device,
  format,
  alphaMode: 'premultiplied',
})

4) 使用 WGSL 编写着色器

WebGPU 使用 WGSL(WebGPU 着色语言),而非 GLSL。

wgsl
@vertex
fn vs_main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4f {
  var pos = array<vec2f, 3>(
    vec2f( 0.0,  0.5),
    vec2f(-0.5, -0.5),
    vec2f( 0.5, -0.5),
  );
  return vec4f(pos[idx], 0.0, 1.0);
}

@fragment
fn fs_main() -> @location(0) vec4f {
  return vec4f(1.0, 0.5, 0.2, 1.0); // orange
}

5) 创建着色器模块

js
const shaderModule = device.createShaderModule({
  code: wgslSource,
})

6) 创建渲染管线

js
const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: {
    module: shaderModule,
    entryPoint: 'vs_main',
  },
  fragment: {
    module: shaderModule,
    entryPoint: 'fs_main',
    targets: [{ format }],
  },
})

7) 渲染一帧

js
function render() {
  const commandEncoder = device.createCommandEncoder()
  const textureView = context.getCurrentTexture().createView()

  const renderPass = commandEncoder.beginRenderPass({
    colorAttachments: [{
      view: textureView,
      clearValue: { r: 0, g: 0, b: 0, a: 1 },
      loadOp: 'clear',
      storeOp: 'store',
    }],
  })

  renderPass.setPipeline(pipeline)
  renderPass.draw(3)
  renderPass.end()

  device.queue.submit([commandEncoder.finish()])
  requestAnimationFrame(render)
}
render()

8) WebGPU 中的缓冲区

js
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)

9) 用于统一变量的绑定组

js
const uniformBuffer = device.createBuffer({
  size: 64,
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
})

const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{
    binding: 0,
    resource: { buffer: uniformBuffer },
  }],
})

10) WebGPU 与 WebGL 对比

方面WebGLWebGPU
API 风格类似 OpenGL,有状态现代、明确
着色器GLSLWGSL
计算有限(依赖扩展)一等支持
多线程困难专为多线程而设计
浏览器支持全面支持所有主流浏览器(Chrome、Edge、Safari 26、Firefox)

何时使用 WebGPU

  • 面向现代浏览器的新项目
  • 计算密集型工作负载(物理、AI、程序化生成)
  • 需要精细控制 GPU 资源时

相关内容

外部资源