게임 개발자를 위한 WebGPU 시작하기
WebGPU는 WebGL의 후속 기술입니다. 더 저수준이고 더 명시적이며, 최신 GPU에 맞게 설계됐습니다. 2026년에 새 3D 프로젝트를 시작한다면 WebGPU를 배워둘 만합니다.
WebGPU 튜토리얼: 환경 설정부터 조명과 애니메이션이 들어간 3D 렌더링까지 다루는 10개 프로젝트
1) 브라우저 지원 확인하기
js
if (!navigator.gpu) {
console.error('WebGPU not supported')
}2026년 현재 WebGPU는 Chrome, Edge, Firefox, Safari에서 모두 사용할 수 있습니다.
2) 디바이스 얻기
js
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter.requestDevice()adapter는 물리 GPU를 나타냅니다. device는 그 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()또한 adapter는 device를 한 번 만들면 소비되므로, device가 하나 더 필요하면 새 adapter를 요청하세요.
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는 GLSL이 아니라 WGSL(WebGPU Shading Language)을 사용합니다.
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) 셰이더 모듈 만들기
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 vs WebGL
| 항목 | WebGL | WebGPU |
|---|---|---|
| API 스타일 | OpenGL 스타일, 상태 기반 | 최신, 명시적 |
| 셰이더 | GLSL | WGSL |
| 컴퓨트 | 제한적 (확장 의존) | 기본 지원 |
| 멀티스레딩 | 어려움 | 멀티스레딩을 염두에 두고 설계 |
| 브라우저 지원 | 보편적 | 모든 주요 브라우저 (Chrome, Edge, Safari 26, Firefox) |
WebGPU를 언제 써야 할까
- 최신 브라우저를 대상으로 하는 새 프로젝트
- 연산이 많은 작업 (물리, AI, 절차적 생성)
- GPU 리소스를 세밀하게 제어해야 할 때
관련 글
- WebGL 기초
- 게임 로직을 위한 Web Workers
- 빠르게 로드되는 웹 게임 출시하기
- 2026년 웹 게임 기술 스택 — WebGL vs WebGPU vs Wasm 의사결정 프레임워크
- COOP/COEP와 SharedArrayBuffer — WebGPU 컴퓨트와 함께 Wasm 스레딩을 쓰는 데 필요한 헤더
외부 자료
- WebGPU specification — W3C 명세
- WGSL specification — WebGPU Shading Language 명세
- WebGPU Fundamentals — 깊이 있는 튜토리얼 시리즈
- Your first WebGPU app — Google Codelab 실습