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 리소스를 세밀하게 제어해야 할 때

관련 글 ​

외부 자료 ​