Wave Function Collapse + WebGPU: el algoritmo que genera mundos medievales procedurales en tu navegador

Share

Un desarrollador construyó un generador de mundos medievales que funciona completamente en tu navegador, sin servidor, sin instalación. El mapa hexagonal que genera — con ríos, acantilados, aldeas, bosques y costas — se produce desde cero en cada ejecución usando Wave Function Collapse combinado con WebGPU y shaders en tiempo real. El resultado es técnicamente impresionante. El proceso detrás es aún más interesante.

Felix Turner publicó el proyecto combinando tres tecnologías: el algoritmo Wave Function Collapse de Maxim Gumin, Three.js con su nuevo WebGPU renderer, y TSL (Typed Shader Language) para efectos de agua realistas. La combinación produce algo que hace diez años habría requerido un motor de videojuegos de escritorio. Hoy corre en Chrome.

¿Qué es Wave Function Collapse? (y por qué el nombre no es exagerado)

Wave Function Collapse (WFC) es un algoritmo de generación procedural de contenido creado por Maxim Gumin y publicado en GitHub. El nombre viene de la física cuántica y no es solo marketing — describe con precisión lo que hace el algoritmo.

En mecánica cuántica, una partícula existe en superposición de estados hasta que es observada, momento en el que “colapsa” a un estado concreto. En WFC, cada celda del mapa existe en superposición de todos los tipos de tile posibles (agua, bosque, llanura, acantilado) hasta que el algoritmo la “observa” y la colapsa a un tipo concreto — propagando restricciones al resto del grid para garantizar coherencia visual.

El ciclo es de tres pasos:

  1. Inicialización: Cada celda parte con todos los tiles posibles, ponderados por frecuencia de aparición en el mapa de muestra.
  2. Observación: El algoritmo selecciona la celda con menor entropía (menos opciones viables) y la colapsa probabilísticamente a un tile concreto.
  3. Propagación: Se eliminan de las celdas vecinas todos los tiles incompatibles con la elección recién realizada. Este paso puede cascadear por todo el grid.

El resultado: un mapa que cumple todas las reglas de adyacencia — nunca aparece agua al lado de montaña sin transición, nunca hay un camino que termine en medio del océano — con variedad genuina en cada generación.

El reto hexagonal: de 4 vecinos a 6, y todo se complica

Los tutoriales de WFC típicamente trabajan con grids cuadrados: cada celda tiene 4 vecinos. Turner eligió hexágonos, lo que eleva el conteo a 6 vecinos por celda. Parece un detalle menor. No lo es.

Con 6 direcciones y 30 tipos de tile distintos — cada uno con reglas de compatibilidad para cada dirección — el espacio de estados crece exponencialmente. Turner construyó reglas de adyacencia para ríos, caminos, acantilados, planicies, costas y aldeas medievales. El desafío no es solo técnico: diseñar reglas lo suficientemente estrictas para generar mapas coherentes pero lo bastante flexibles para producir variedad real requiere trabajo de diseño tan cuidadoso como el de ingeniería.

La solución fue modularizar: dividir los tipos de borde en categorías reutilizables en lugar de gestionar todas las restricciones en una matriz monolítica. Esto permite escalar a nuevos tipos de tile sin reescribir la lógica central.

El problema de los callejones sin salida (y cómo resolverlos)

WFC tiene un talón de Aquiles conocido: puede llegar a contradicciones. Una celda sin ningún tile compatible con todas sus vecinas. En implementaciones simples, la única solución es reiniciar el mapa completo desde cero.

Turner implementó un sistema de backtracking avanzado que registra el historial de decisiones y permite retroceder solo hasta el punto de la contradicción, sin reiniciar todo. Según la implementación original de Gumin, las contradicciones ocurren en menos del 1% de las generaciones típicas — pero con grids grandes y tiles complejos la frecuencia puede aumentar.

Las optimizaciones que mantienen la generación en tiempos aceptables:

  • Colas de prioridad: O(log N) por actualización en la selección de mínima entropía, en lugar de O(N).
  • Procesamiento secuencial: Reduce la varianza en la propagación comparado con selección puramente aleatoria.
  • Pesos calibrados: Para tiles frecuentes que evitan “callejones sin salida” de baja probabilidad.

De plano a 3D: elevación, árboles y Perlin noise

Una vez generado el mapa 2D, Turner inyectó altura: agua en cota 0, llanuras en alturas intermedias, acantilados y montañas en los valores más altos. La coherencia es obligatoria — los bordes entre diferentes alturas deben respetar las reglas de adyacencia del WFC. Un acantilado no puede aparecer al lado de una llanura sin transición adecuada.

Para vegetación y edificios usó un enfoque diferente: ruido Perlin multicapa. Para cada tile colapsado (bosque, llanura), se muestrea el valor del ruido Perlin en las coordenadas hexagonales. Si supera un umbral, se instancia un árbol o edificio con variaciones de escala y rotación para evitar patrones repetitivos. Las restricciones del WFC actúan como máscara: nunca aparecen árboles sobre agua ni edificios en acantilados. La combinación WFC + Perlin produce el “caos controlado” que hace que un mapa procedural se sienta explorado en lugar de fabricado.

WebGPU y TSL: shaders en el navegador sin WebGL

Aquí entra la parte técnica más relevante para quien trabaja con gráficos web. Turner usó el WebGPU renderer de Three.js — la API de gráficos de próxima generación que reemplaza a WebGL con menor overhead y acceso más directo a la GPU — junto con TSL (Typed Shader Language), un sistema de shaders tipados que permite escribir efectos de vértice y fragmento directamente en JavaScript/TypeScript.

Los efectos de agua incluyen:

  • Desplazamiento de vértices con ondas de Gerstner para simular movimiento realista de superficie
  • Efectos de espuma basados en profundidad y efecto Fresnel, animados mediante uniformes de tiempo
  • Cálculo de normales procedurales desde ruido para refracción y reflexión plausibles

Todo esto corriendo en el navegador, sin servidor, aprovechando WebGPU para ejecutar shaders con overhead significativamente menor que WebGL. Para quien desarrolla visualizaciones o simulaciones web, este proyecto es un ejemplo práctico de lo que WebGPU + Three.js permiten hoy en producción.

Por qué importa

WFC no es nuevo — el repositorio original de Gumin tiene años. Lo que hace valioso el proyecto de Turner es la combinación específica: WFC hexagonal con reglas complejas, generación de altura 3D, Perlin noise para detalles orgánicos, y WebGPU para renderizado en tiempo real en el navegador. Es una demostración de que la frontera entre “puede correr en el browser” y “requiere motor de escritorio” se ha movido significativamente.

Para equipos de desarrollo de videojuegos indie, simulaciones o herramientas de visualización interactiva, este stack — WFC + Three.js WebGPU + TSL — representa un camino viable para generación procedural de alta calidad sin salir del ecosistema web. La barrera de entrada bajó. El límite creativo también.

Si quieres profundizar más en la generación procedural, ya cubrimos LibreSprite para pixel art generativo y Neural Boids para comportamiento emergente con aprendizaje por imitación. WFC es otra pieza del mismo ecosistema de herramientas que están cambiando cómo se genera contenido procedural.


Fuentes

Leer más

Otras noticias