Skip to content

게임 개발자를 위한 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

항목WebGLWebGPU
API 스타일OpenGL 스타일, 상태 기반최신, 명시적
셰이더GLSLWGSL
컴퓨트제한적 (확장 의존)기본 지원
멀티스레딩어려움멀티스레딩을 염두에 두고 설계
브라우저 지원보편적모든 주요 브라우저 (Chrome, Edge, Safari 26, Firefox)

WebGPU를 언제 써야 할까

  • 최신 브라우저를 대상으로 하는 새 프로젝트
  • 연산이 많은 작업 (물리, AI, 절차적 생성)
  • GPU 리소스를 세밀하게 제어해야 할 때

관련 글

외부 자료