Fundamentos de WebGL para desarrolladores de juegos
WebGL te da acceso directo a la GPU desde el navegador. Es la base de los juegos web 3D (y de los juegos 2D de alto rendimiento). Este tutorial cubre los conceptos esenciales.
1) Obtener un contexto WebGL
const canvas = document.getElementById('game')
const gl = canvas.getContext('webgl2') || canvas.getContext('webgl')
if (!gl) {
// Fallback or error message
console.error('WebGL not supported')
}Prefiere webgl2 cuando esté disponible: es ampliamente compatible y ofrece mejores prestaciones.
2) El pipeline de renderizado (simplificado)
- El shader de vértices se ejecuta una vez por vértice. Posiciona la geometría.
- El shader de fragmentos se ejecuta una vez por píxel. Colorea el resultado.
- Los búferes almacenan datos (posiciones, coordenadas UV y colores).
- Las texturas son imágenes que los shaders muestrean.
3) Un par mínimo de shaders
Shader de vértices:
#version 300 es
in vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}Shader de fragmentos:
#version 300 es
precision mediump float;
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.5, 0.2, 1.0); // orange
}4) Compilar y enlazar shaders
function createShader(gl, type, source) {
const shader = gl.createShader(type)
gl.shaderSource(shader, source)
gl.compileShader(shader)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader))
gl.deleteShader(shader)
return null
}
return shader
}
function createProgram(gl, vs, fs) {
const program = gl.createProgram()
gl.attachShader(program, vs)
gl.attachShader(program, fs)
gl.linkProgram(program)
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error(gl.getProgramInfoLog(program))
return null
}
return program
}5) Crear búferes
const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5,
])
const buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)6) Conectar los búferes con los shaders
const positionLoc = gl.getAttribLocation(program, 'a_position')
gl.enableVertexAttribArray(positionLoc)
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0)7) El bucle del juego
function render() {
gl.viewport(0, 0, canvas.width, canvas.height)
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.useProgram(program)
gl.drawArrays(gl.TRIANGLES, 0, 3)
requestAnimationFrame(render)
}
render()8) Cargar texturas
function loadTexture(gl, url) {
const texture = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, texture)
// Placeholder pixel until image loads
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([255, 0, 255, 255]))
const img = new Image()
img.onload = () => {
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img)
gl.generateMipmap(gl.TEXTURE_2D)
}
img.src = url
return texture
}9) Errores habituales
- Las texturas con dimensiones que son potencias de dos no son estrictamente necesarias en WebGL 2, pero los mipmaps funcionan mejor con ellas.
- Pérdida del contexto: gestiona los eventos
webglcontextlost; los navegadores móviles liberan contextos cuando hay presión sobre la memoria. - Las texturas de coma flotante requieren comprobar la extensión (
EXT_color_buffer_float).
10) Cuándo usar una biblioteca
WebGL puro requiere mucho código. Para la mayoría de los juegos, considera:
- Three.js — 3D con todas las funciones
- PixiJS — renderizado 2D rápido
- PlayCanvas — motor de juegos con editor
Usa WebGL puro cuando necesites:
- control máximo
- un renderizador personalizado
- aprender cómo funcionan realmente las cosas
Una nota para 2026: WebGPU ya viene activado de forma predeterminada en todos los navegadores principales (Chrome y Edge desde la versión 113, Firefox 141 en Windows y 145 en macOS, y Safari en iOS 26, iPadOS 26 y macOS Tahoe 26). Los fundamentos explicados aquí siguen siendo aplicables, ya que bibliotecas como Three.js ejecutan su renderizador WebGPU con WebGL 2 como alternativa automática, por lo que WebGL 2 continúa siendo la base más fiable. Si hoy vas a crear un renderizador nuevo desde cero, lee el tutorial de WebGPU junto con este antes de comprometerte con una API.
Contenido relacionado
- WebGPU para juegos
- Bucle de juego con Canvas 2D
- Publica un juego web que cargue rápido
- Stack tecnológico para juegos web en 2026 — cuándo elegir WebGL, WebGPU o Wasm
- Bibliotecas de física para juegos — motores de física que renderizan mediante WebGL
- Comparativa de motores de juegos web — Three.js, PixiJS, PlayCanvas y otros
Recursos externos
- MDN: API de WebGL — referencia completa de la API
- Fundamentos de WebGL2 — serie de tutoriales detallados sobre WebGL2
- El libro de los shaders — guía interactiva sobre shaders de fragmentos GLSL
- Documentación de Three.js — el framework WebGL más popular