Skip to content

Primeros pasos con WebGPU para desarrolladores de juegos

WebGPU es el sucesor de WebGL. Es de más bajo nivel, más explícito y está diseñado para las GPU modernas. Si vas a iniciar un nuevo proyecto 3D en 2026, vale la pena aprender WebGPU.

Tutorial de WebGPU: 10 proyectos que abarcan desde la configuración hasta el renderizado 3D con iluminación y animación

1) Comprueba la compatibilidad del navegador

js
if (!navigator.gpu) {
  console.error('WebGPU not supported')
}

En 2026, WebGPU está disponible en Chrome, Edge, Firefox y Safari.

2) Obtén un dispositivo

js
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter.requestDevice()

El adaptador representa la GPU física. El dispositivo es tu interfaz para interactuar con ella.

Ambas llamadas pueden fallar. requestAdapter() devuelve null cuando el sistema no tiene una GPU utilizable y requestDevice() puede rechazar la solicitud, así que compruébalo antes de continuar:

js
const adapter = await navigator.gpu.requestAdapter()
if (!adapter) throw new Error('No suitable GPU adapter found')
const device = await adapter.requestDevice()

Además, el adaptador queda consumido cuando creas un dispositivo a partir de él, así que solicita uno nuevo si necesitas otro dispositivo.

3) Configura el canvas

js
const canvas = document.getElementById('game')
const context = canvas.getContext('webgpu')
const format = navigator.gpu.getPreferredCanvasFormat()

context.configure({
  device,
  format,
  alphaMode: 'premultiplied',
})

4) Escribe shaders en WGSL

WebGPU utiliza WGSL (WebGPU Shading Language), no 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) Crea un módulo de shaders

js
const shaderModule = device.createShaderModule({
  code: wgslSource,
})

6) Crea un pipeline de renderizado

js
const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: {
    module: shaderModule,
    entryPoint: 'vs_main',
  },
  fragment: {
    module: shaderModule,
    entryPoint: 'fs_main',
    targets: [{ format }],
  },
})

7) Renderiza un fotograma

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) Búferes en 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) Grupos de enlace para 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 frente a WebGL

AspectoWebGLWebGPU
Estilo de APISimilar a OpenGL, con estadoModerno, explícito
ShadersGLSLWGSL
CómputoLimitado (extensiones)Compatibilidad de primer nivel
MultihiloDifícilDiseñado para ello
Compatibilidad con navegadoresUniversalTodos los navegadores principales (Chrome, Edge, Safari 26, Firefox)

Cuándo utilizar WebGPU

  • Proyectos nuevos dirigidos a navegadores modernos
  • Cargas de trabajo con uso intensivo de cómputo (física, IA y generación procedural)
  • Cuando necesitas un control preciso de los recursos de la GPU

Contenido relacionado

Recursos externos