Ya tenemos Three.js r186, y esta vez hay bastante que mirar. Gaussian Splatting, una nueva luz de sol, materiales con retroreflectividad y más opciones para trabajar la iluminación. Una de esas versiones que apetece abrir con calma y empezar a probar. A mí lo que más me llama la atención son los shaders y todo lo que se está moviendo alrededor de Gaussian Splatting, WebGPU y TSL.
A mí EEVEE me ha flipado desde hace tiempo. Esa respuesta inmediata al mover una luz o cambiar un material tiene mucho encanto. Pero me faltaba encontrarle una salida práctica fuera de Blender. Three.js está siendo esa pieza: conecta mi trabajo de 3D con el desarrollo web y me hace pensar en escenas que otras personas puedan utilizar. Ya os hablaba de esa ilusión cuando estaba calentando motores para la Three.js Conference.
Así que vamos a repasar las novedades oficiales de Three.js r186 desde ese lado, el del artista que quiere entender qué puede hacer con ellas. Estoy absorbiendo toda esta avalancha de novedades a marchas forzadas. Son muchas y muy buenas, y escribir estas entradas me ayuda a ordenarlas y a quedarme mejor con lo que aporta cada una. Eso sí: hay novedades y hay mejoras de cosas que ya existían. Vamos a distinguirlas.
También quería dejar aquí una mención a mrdoob, creador de Three.js, y a todas las personas que mantienen y hacen crecer el proyecto. La r186 ya está en su repositorio oficial, donde podéis consultar la nota completa de esta versión.
Tabla de contenidos
Antes de empezar: Three.js no es EEVEE fuera de Blender
Cycles es el motor de Blender basado en raytracing, con el que calculamos iluminación para crear imágenes y animaciones. EEVEE es su motor de renderizado en tiempo real, basado principalmente en rasterización y aproximaciones para ofrecer una respuesta rápida. Ambos forman parte de Blender.
Three.js es una biblioteca JavaScript con la que construimos y renderizamos escenas 3D en el navegador. No es un motor que seleccionemos en Blender para exportar un render, ni utiliza EEVEE o reproduce automáticamente su resultado. Lo que trasladamos son recursos 3D; la experiencia web se desarrolla después.
GLB/glTF: el puente para modelos y materiales
Un flujo habitual consiste en preparar el modelo en Blender, exportarlo como GLB o glTF y cargarlo con GLTFLoader. GLB es la variante binaria de glTF. Según la configuración de exportación, permite llevar geometría, texturas, materiales compatibles y animaciones.
Los materiales deben ajustarse a lo que admite glTF: una red de nodos arbitraria de Blender no se convierte por arte de magia. Puede hacer falta hornear texturas y reconstruir efectos. También hay que adaptar iluminación, sombras, entorno y gestión de color. El parecido visual se trabaja; no viene garantizado por el archivo.
Y ahí empieza lo divertido: girar un producto, elegir otro acabado o recorrer una escena desde una web. Esa es la aplicación del tiempo real que me estaba faltando.
Gaussian Splatting entra en el proyecto oficial
Gaussian Splatting representa una escena mediante muchas gaussianas tridimensionales, que podemos imaginar como pequeñas manchas con volumen, color y transparencia. Es una vía especialmente interesante para visualizar capturas de espacios reales. No equivale a una malla convencional con topología lista para editar en Blender.
Para que nos entendamos: esto es como llenar una escena de pequeñas manchas de color y transparencia. Vistas todas juntas desde el ángulo adecuado, forman la imagen de un lugar; si movemos la cámara, podemos recorrerlo en 3D. Por eso resulta tan interesante para capturar y enseñar espacios reales. Pero no es una malla de polígonos que podamos abrir en Blender y editar como un modelo normal.
r186 incorpora GaussianSplat, un renderizador basado en TSL que funciona con WebGPURenderer. También puede utilizarse con su alternativa WebGL, pero no con WebGLRenderer. El proyecto incluye varios cargadores de datos de splats y un complemento para glTF, que hay que registrar expresamente en GLTFLoader. Es una incorporación al proyecto oficial: la técnica y otras soluciones para usarla en la web ya existían.
Aquí hay un campo muy interesante para documentar espacios reales y mostrarlos en una experiencia web. Ojo con confundir los procesos: una captura con splats no es una malla lista para retopología y un GLB corriente de Blender no se convierte en splats al cargarlo. Hay que preparar los datos y cuidar el rendimiento.
Puedes consultar la incorporación oficial y explorar la demo de Gaussian Splatting.
SunLight: vamos con la luz y las sombras
r186 añade SunLight con mapas de sombras en cascada, con soporte en WebGLRenderer y WebGPURenderer. SunLight se distribuye como addon. La idea de las sombras en cascada no nace aquí: Three.js ya tenía soluciones de CSM.
Las cascadas reparten la cobertura de las sombras según la distancia a la cámara: más detalle cerca y cobertura para zonas lejanas. Pensad en una escena arquitectónica que podemos recorrer. La sombra tiene que seguir funcionando mientras nos movemos, y eso exige ajustar cobertura, calidad y coste. Podéis consultar la incorporación de SunLight y las demos oficiales en WebGL y WebGPU.
Retroreflectividad y mejoras en materiales PBR
Retroreflectividad: pensad en un chaleco reflectante
MeshPhysicalMaterial incorpora soporte para retroreflectividad. Piensa en una señal de tráfico o en las bandas de un chaleco: devuelven parte de la luz hacia la dirección de la que llega. No es lo mismo que un espejo ni que un material emisivo.
En visualización de productos, permite representar mejor determinados tejidos y acabados técnicos. Su efecto depende de la relación entre luz, superficie y observador. Que Three.js lo admita no implica que el exportador de Blender lo transfiera automáticamente. Aquí tienes la implementación oficial y la demo de retroreflexión.
Materiales PBR más afinados
PBR significa renderizado basado en principios físicos. Nos permite describir superficies con propiedades como rugosidad y metalicidad, familiares para quienes trabajamos con el Principled BSDF de Blender. Compartir esos conceptos no hace idénticos los resultados de ambos sistemas.
r186 mejora la conservación de energía de la iluminación difusa y sheen, y corrige aspectos de la compensación de dispersión múltiple e iridiscencia. Son ajustes al modelo existente, no el estreno de PBR en Three.js. Consulta el cambio sobre conservación de energía.
SSAO y GTAO: esos contactos que ayudan a leer el modelo
La oclusión ambiental ayuda a sugerir el oscurecimiento en contactos y rincones. SSAO y GTAO son aproximaciones en espacio de pantalla: utilizan información de la imagen renderizada. No calculan por sí mismas todos los rebotes de luz de una escena.
La novedad concreta es SSAONode y depthAwareBlur para el sistema de nodos. SSAO ya existía en Three.js mediante otras implementaciones. GTAONode recibe mejoras en el modelo de distancia, muestreo y optimización, además de una corrección de bandas visibles.
En un producto, una AO bien ajustada ayuda mucho a leer uniones y apoyos. Pasarse también es fácil: empiezan a aparecer manchas oscuras donde queríamos detalle. La demo oficial de AO permite comparar resultados. Aquí está también el cambio que añade SSAONode.
VXGI: un paso más con la iluminación indirecta
r186 incorpora VXGINode, una implementación de iluminación global difusa mediante voxel cone tracing. Representa la escena en un volumen de vóxeles y utiliza ese volumen para estimar iluminación indirecta. Esto va más allá del oscurecimiento de contactos que aporta la AO.
Es especialmente interesante para espacios pequeños o medianos con geometría oclusora estática. Puede responder a cambios de iluminación, pero voxelizar geometría tiene un coste. También puede producir fugas de luz y artefactos, y no soporta todos los tipos de objetos.
Aquí sí estamos ante una técnica avanzada. La implementación necesita compute shaders y buffers de almacenamiento, por lo que no funciona en WebGL 2. Tampoco es path tracing ni nos da automáticamente el resultado de Cycles. Me parece interesante tenerla en el radar, pero habrá que mirar lo que aporta y lo que cuesta en cada escena.
Consulta los detalles y límites oficiales de VXGI y las demos de VXGI y Sponza.
WebGPU y TSL: una evolución que sigue avanzando
WebGPU es una API del navegador para trabajar con la GPU. TSL, Three.js Shading Language, permite expresar operaciones de shaders mediante JavaScript y nodos que Three.js traduce para sus backends. Ninguna de las dos aparece por primera vez en r186.
En r186 se añade, por ejemplo, compileComputeAsync() para preparar de forma asíncrona programas de cómputo, además de operaciones de empaquetado y desempaquetado 4×8 en TSL y correcciones de esa infraestructura. Son cambios más técnicos, pero forman parte de lo que hace posibles estas herramientas visuales. Para mí, los shaders y esta evolución de WebGPU y TSL son de lo más interesante de la versión.
Si venís de los nodos de Blender, esa forma de construir operaciones puede ayudar a orientarse. Los sistemas son diferentes, pero tenemos una referencia desde la que empezar. Y hay que mirar la compatibilidad de cada técnica: VXGI, por ejemplo, necesita funciones que no ofrece WebGL 2. Tenéis más información en la documentación oficial de TSL.
Antes de actualizar: revisa la guía de migración
Las novedades visuales son la parte atractiva, pero actualizar una biblioteca también puede exigir cambios en el proyecto. La guía de migración de r185 a r186 señala, entre otros, estos puntos:
En GTAONode, distanceExponent y distanceFallOff quedan obsoletos y ya no afectan a la AO. Con WebGPURenderer, PCFSoftShadowMap se elimina y se indica utilizar PCFShadowMap, que también produce sombras suaves. La implementación WebGL de LightProbeGrid pasa a llamarse LightProbeGridWebGL.
Además, SimplifyModifier.modify() pasa a ser asíncrono y puede producir una malla simplificada diferente. Conviene revisar el apartado completo, actualizar en una copia de desarrollo y comparar materiales, sombras, carga de modelos y rendimiento antes de llevar el cambio a producción.
Tres configuradores en marcha y muchas ganas de enseñarlos
Ahora mismo quiero seguir avanzando en los proyectos que tengo abiertos. Son tres configuradores de producto para ecommerce, y tengo muchas ganas de mostrarlos ya al público. Pronto los enseñaré.
Ahí es donde todo esto conecta con mi trabajo: un modelo, sus materiales y la posibilidad de que alguien interactúe con el producto en una tienda online. Repasar r186 me ayuda a entender lo que viene y a valorar qué podría aprovechar, sin perder el foco en los proyectos que ya están en marcha.
Vídeo y podcast
Mientras preparo mi propio vídeo, os dejo este avance publicado por la cuenta oficial de Three.js en X. En apenas unos segundos aparecen varias de las ideas que hemos comentado: Gaussian Splatting, escenas 3D y materiales en tiempo real.
Seguimos con Three.js en Zao3D
Si queréis seguir ese recorrido, en Lo que me traje de la primera Three.js Conference os cuento mis primeras impresiones al volver. En mi blog personal también escribí sobre por qué iba a la Three.js Conf de París y qué esperaba encontrar allí: gente que, como yo, trabaja entre el 3D y la web. Este repaso continúa ese camino. Me queda pendiente contar con más calma lo que he visto de Three.js y de la conferencia; hay bastante material que digerir. También iremos hablando de ello en el podcast de Freelance 3D.
Las demos enlazadas son ejemplos oficiales incluidos en r186. La web de ejemplos se actualiza con el proyecto, así que puede mostrar cambios posteriores. Para probarlas, tened en cuenta la compatibilidad del navegador y de la GPU.