Skip to content

WebGPU getting started for game developers

WebGPU is the successor to WebGL. It's lower-level, more explicit, and designed for modern GPUs. If you're starting a new 3D project in 2026, WebGPU is worth learning.

1) Check browser support

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

As of 2026, WebGPU is available in Chrome, Edge, Firefox, and Safari.

2) Get a device

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

The adapter represents the physical GPU. The device is your interface to it.

3) Configure the canvas

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

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

4) Write shaders in WGSL

WebGPU uses WGSL (WebGPU Shading Language), not 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) Create a shader module

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

6) Create a render pipeline

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

7) Render a frame

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) Buffers in 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) Bind groups for uniforms

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

AspectWebGLWebGPU
API styleOpenGL-like, statefulModern, explicit
ShadersGLSLWGSL
ComputeLimited (extensions)First-class support
Multi-threadingDifficultDesigned for it
Browser supportUniversalMajor browsers (2024+)

When to use WebGPU

  • New projects targeting modern browsers
  • Compute-heavy workloads (physics, AI, procedural gen)
  • When you need fine-grained control over GPU resources