Skip to content

游戏开发者的 WebGPU 入门

WebGPU 是 WebGL 的继任者。它更底层、更显式,专为现代 GPU 设计。如果你在 2026 年要开新的 3D 项目,WebGPU 值得学。

WebGPU 教程:10 个项目,覆盖从环境配置到带光照与动画的 3D 渲染

1)检查浏览器支持

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

截至 2026 年,WebGPU 在 Chrome、Edge、Firefox 和 Safari 上都已可用。

2)拿到 device

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

adapter 代表物理 GPU。device 是你与它交互的接口。

3)配置 canvas

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

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

4)用 WGSL 写 shader

WebGPU 使用 WGSL(WebGPU Shading Language),不是 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); // 橙色
}

5)创建 shader module

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 中的 buffer

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)用于 uniform 的 bind group

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 vs WebGL

方面WebGLWebGPU
API 风格类 OpenGL,状态机现代,显式
ShaderGLSLWGSL
计算(Compute)受限(依赖扩展)一等公民
多线程困难为此设计
浏览器支持普及主流浏览器(2024+)

什么时候用 WebGPU

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

相关阅读

外部资源