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
| Aspect | WebGL | WebGPU |
|---|---|---|
| API style | OpenGL-like, stateful | Modern, explicit |
| Shaders | GLSL | WGSL |
| Compute | Limited (extensions) | First-class support |
| Multi-threading | Difficult | Designed for it |
| Browser support | Universal | Major 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