游戏开发者的 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
| 方面 | WebGL | WebGPU |
|---|---|---|
| API 风格 | 类 OpenGL,状态机 | 现代,显式 |
| Shader | GLSL | WGSL |
| 计算(Compute) | 受限(依赖扩展) | 一等公民 |
| 多线程 | 困难 | 为此设计 |
| 浏览器支持 | 普及 | 主流浏览器(2024+) |
什么时候用 WebGPU
- 面向现代浏览器的新项目
- 计算密集的工作负载(物理、AI、程序化生成)
- 需要对 GPU 资源做细粒度控制时
相关阅读
- WebGL 基础
- 游戏逻辑的 Web Workers
- 发布一个快速加载的网页游戏
- 2026 年的网页游戏技术栈 —— WebGL vs WebGPU vs Wasm 的决策框架
- COOP/COEP 与 SharedArrayBuffer —— 在 WebGPU 计算中使用 Wasm 线程所需的响应头
外部资源
- WebGPU specification —— W3C 规范
- WGSL specification —— WebGPU 着色器语言规范
- WebGPU Fundamentals —— 深入的系列教程
- Your first WebGPU app —— Google Codelab 实战