Babylon, PlayCanvas y escribir el tuyo: cuándo Three.js no es la respuesta
Una comparación honesta de las alternativas reales a Three.js según el tipo de proyecto, y en qué casos concretos compensa escribir un renderer propio sobre WebGL o WebGPU.
Elegir biblioteca no es elegir bando. Las opciones serias del 3D en la web resuelven el mismo problema con filosofías distintas, y cada filosofía tiene un tipo de proyecto donde brilla y otro donde estorba. Este track enseña Three.js, pero enseñarlo sin situarlo sería enseñarte a usar una herramienta sin saber para qué está afilada.
- Comparar Three.js, Babylon.js y PlayCanvas por filosofía de diseño, no por lista de características.
- Identificar el tipo de proyecto que encaja con cada una.
- Enumerar las condiciones concretas bajo las que compensa escribir un renderer propio.
- Estimar el coste real de esa decisión en trabajo que hoy no tienes que hacer.
Tres filosofías de biblioteca
Three.js es una biblioteca de renderizado con un núcleo pequeño y un ecosistema enorme. Su decisión fundacional es no imponer arquitectura: te da el grafo de escena, los materiales, el renderer y poco más; el resto lo montas tú o lo traes de fuera. Eso explica sus dos caras. Por un lado, es la opción más flexible para experiencias visuales a medida, sitios con 3D, visualización de datos, arte generativo y cualquier cosa donde el diseño manda; y tiene, con diferencia, el mayor volumen de ejemplos, tutoriales y bibliotecas de terceros. Por otro, un juego mediano necesita que tú aportes el sistema de entidades, el de estados, el de audio y la gestión de assets, porque la biblioteca no opina sobre ninguno.
Babylon.js es un motor con baterías incluidas y una cultura de tipado fuerte. Está escrito en TypeScript, trae física integrada con varios backends, sistema de animación completo, GUI en 3D, inspector de escena, soporte de audio y un editor. Su documentación es de las mejores del sector y su compromiso con la retrocompatibilidad es notable. Encaja de forma natural en producto de empresa, configuradores, simuladores, formación y juegos de complejidad media, donde tener respuestas por defecto para veinte problemas vale más que la flexibilidad de resolverlos a mano.
PlayCanvas es un motor con editor colaborativo en la nube y foco en el rendimiento en móvil. Su núcleo es de código abierto, y alrededor hay una plataforma con editor visual, control de versiones de assets y publicación. Su arquitectura es de entidades y componentes, más cercana a lo que espera alguien que viene de Unity. Encaja cuando hay artistas y diseñadores en el equipo tocando la escena a la vez que los programadores, y cuando el objetivo son anuncios jugables, juegos de navegador o experiencias que deben ir finas en teléfonos modestos.
| Criterio | Three.js | Babylon.js | PlayCanvas |
|---|---|---|---|
| Filosofía | Biblioteca mínima | Motor completo | Motor con plataforma |
| Arquitectura impuesta | Ninguna | Ligera | Entidad y componente |
| Editor visual | No, en el núcleo | Sí | Sí, colaborativo |
| Física | Externa | Integrada | Integrada |
| Punto fuerte | Flexibilidad y ecosistema | Cobertura y documentación | Flujo de equipo y móvil |
| Punto débil | Todo lo que no es render | Peso y opinión | Menor ecosistema externo |
La comparación no tiene ganador porque la pregunta no es «cuál es mejor» sino «qué parte de mi problema quiero que alguien haya resuelto ya». Si tu proyecto es 80 % render a medida y 20 % lógica, la falta de opinión de Three.js es una ventaja. Si es 40 % render y 60 % sistemas de juego, esa misma falta de opinión es trabajo que vas a pagar tú.
La conversación sobre migrar de biblioteca casi siempre se plantea en términos de superficie de API, y es la parte fácil: renombrar clases y ajustar convenciones lleva días. Lo que no se contabiliza es el conocimiento tácito acumulado, que es lo caro. Saber que un artefacto de sombra concreto se arregla tocando dos parámetros y no tres; conocer de memoria qué combinación de material y textura dispara una recompilación de shader; tener en la cabeza el mapa de qué es lento en esa implementación concreta; reconocer un mensaje de error de hace dos años. Ese saber no está escrito en ninguna documentación, tarda un año en formarse y no se transfiere entre motores. Por eso la decisión correcta casi nunca es la que optimiza las características sobre el papel: es la que optimiza el ritmo al que tu equipo aprende a depurar. Y por eso un equipo mediocre con una herramienta que domina supera sistemáticamente a un equipo bueno estrenando herramienta, durante bastante más tiempo del que nadie estima al planificar la migración.
Escribir el tuyo: cuándo tiene sentido y cuándo es vanidad
Escribir un renderer propio sobre WebGL2 o WebGPU es una decisión legítima, pero solo bajo condiciones concretas. La pregunta correcta no es «¿podría?», sino «¿qué me da la biblioteca que no necesito, y qué necesito que no me da?».
Compensa cuando el presupuesto de bytes es el requisito principal. Un anuncio jugable con límite de 200 kilobytes, o una demo en la que el tamaño es la gracia, no puede permitirse un motor general. Un renderer específico que dibuje exactamente lo que dibujas puede caber en unos pocos kilobytes, porque no incluye lo que no usas.
Compensa cuando tu técnica de render no es de triángulos. Raymarching puro, splatting gaussiano, trazado de rayos por cómputo, visualización volumétrica: si toda tu escena es un cuadrilátero a pantalla completa con un shader, el grafo de escena, el sistema de materiales y el ordenador de transparencias no te aportan nada y sí te imponen convenciones.
Compensa cuando necesitas control absoluto sobre el orden y el estado, por ejemplo un pipeline con render diferido a medida, mallas de sombra en cascada muy específicas o una gestión de memoria con presupuesto fijo. Se puede forzar a Three.js a casi todo, pero llega un punto en que peleas contra la biblioteca más de lo que te apoyas en ella.
Y no compensa —aunque suene tentador— cuando el motivo es rendimiento genérico. Three.js no es lento por ser Three.js: es lento cuando emites tres mil órdenes de dibujo, y eso mismo lo será tu renderer. La diferencia de rendimiento entre una biblioteca madura y una implementación propia razonable es pequeña comparada con la diferencia entre una escena bien y mal organizada.
Antes de decidir, conviene mirar la lista de lo que tendrías que escribir tú y que hoy no ves porque ya está hecho:
// Lo que hay que resolver en cualquier renderer, por trivial que parezca.
const responsabilidades = [
'creacion y actualizacion de buffers de vertices e indices',
'carga de texturas con espacios de color, mipmaps y filtrado',
'compilacion, enlazado y cache de programas por permutacion',
'cache de estado para evitar cambios redundantes',
'jerarquia de transformaciones y actualizacion de matrices',
'matrices de proyeccion y descarte por frustum',
'ordenacion de opacos y de transparentes',
'sombras con sus mapas, sesgos y filtrado',
'iluminacion basada en imagen con su prefiltrado',
'gestion de color de entrada y de salida',
'redimensionado, pixel ratio y perdida de contexto',
'liberacion explicita de recursos de GPU',
];
console.log(`Tareas que asume una biblioteca madura: ${responsabilidades.length}`);
Ninguna de esas doce líneas es intelectualmente difícil. Todas juntas son entre seis meses y dos años de trabajo hasta alcanzar la robustez que hoy das por supuesta, y buena parte de ese tiempo se va en casos límite de dispositivos que no tienes. Ese es el número que hay que poner sobre la mesa en la reunión donde alguien propone escribir un motor.
La decisión en tres preguntas
¿Cuánto de tu problema es render y cuánto es sistema? Si la respuesta se inclina claramente hacia sistemas de juego, mira Babylon o PlayCanvas antes de montar la mitad de un motor encima de Three.js.
¿Quién toca la escena? Si hay perfiles no programadores editando contenido a diario, un editor visual con control de versiones vale más que cualquier característica técnica. Si la escena la define código, el editor sobra.
¿Cuál es tu restricción dura? Tamaño del bundle, cobertura de dispositivos antiguos, plazo de entrega, o una técnica de render que no es estándar. La restricción dura decide; el resto es preferencia.
Este track continúa con Three.js, y lo hace por una razón defendible: es la biblioteca donde los fundamentos que vas a aprender —pipeline, matrices, espacios, shaders— quedan más a la vista. Lo que aprendas aquí se traduce a cualquiera de las otras, porque debajo de todas está la misma GPU y el mismo pipeline gráfico.