Cómo optimizamos el gemelo digital de nuestra oficina: de Revit al navegador (parte 2)
En la primera parte contamos cómo llevamos el modelo BIM de nuestra oficina desde Revit hasta un visor web construido con Three.js. El recorrido era Revit → Blender → GLB → optimización → navegador.
Pero conseguir que el modelo apareciese en pantalla era solo el principio. Después había que lograr que cargase, se pudiese recorrer con fluidez y funcionase también en dispositivos con menos recursos. Para ello tuvimos que mirar más allá del tamaño de los archivos: texturas, memoria gráfica, geometrías, llamadas de dibujo y sombras.
Un GLB pequeño todavía puede ser caro de mostrar
Utilizamos GLB, la versión binaria de glTF, para llevar los modelos al navegador. Comprimir esos archivos reduce la descarga, pero el navegador tiene que descomprimir y preparar su contenido antes de dibujarlo.
Esta diferencia nos dio una de las lecciones más útiles del proyecto: el peso del GLB no equivale a la memoria que consume en la GPU. Una textura de 2048 × 2048 píxeles puede ocupar poco como archivo WebP y necesitar alrededor de 21 MB de memoria gráfica una vez preparada para su uso. Si varios personajes cargan sus propias texturas, ese consumo se acumula rápidamente.
Por eso no bastaba con preguntar «¿cuánto pesa el modelo?». También necesitábamos saber qué ocurría después de descargarlo.
Draco y WebP: menos peso, menos memoria
Los modelos que analizamos utilizan Draco para comprimir las mallas. En el caso de las texturas, el proceso de optimización limita su resolución y las convierte a WebP cuando corresponde.
El límite habitual es de 512 píxeles por lado. En personaSentada.glb se reduce a 256 píxeles, porque ese personaje incluye 21 texturas repartidas entre varios conjuntos. Reducir una textura de 2048 a 512 píxeles por lado baja su consumo estimado de unos 21 MB a 1,4 MB de VRAM.
El resultado se aprecia en personajes concretos. persona2tecleando pasó de 3,05 MB de descarga y unos 107 MB de VRAM a 0,98 MB y unos 7 MB. En otros personajes sentados, el consumo estimado pasó de unos 128 MB a aproximadamente 7–8 MB.
La compresión ayudó a que los archivos llegasen antes. La reducción de resolución de las texturas fue decisiva para que esos archivos no agotasen la memoria al mostrarse.

Menos mallas, menos trabajo por fotograma
Había otro coste que el tamaño del archivo tampoco explicaba bien: las draw calls, las órdenes que el navegador envía a la GPU para dibujar la escena.
El modelo de arquitectura conservaba multitud de elementos procedentes de Revit. Esa estructura era valiosa: permitía reconocer muros, suelos, paneles y familias incluso después de exportarlos. Pero dibujar muchas piezas por separado podía exigir demasiado trabajo en cada fotograma.
Fusionamos geometrías compatibles para reducir ese coste. En el caso de arquitectura, pasamos de 745 a 47 draw calls tras fusionar mallas. En instalaciones, la reducción fue de 439 a 1.
La decisión tenía una condición: optimizar el renderizado sin perder las referencias que necesita la interacción con el modelo. No sirve ganar fluidez si después no podemos identificar un elemento BIM o consultar sus propiedades.
Las sombras: aprovechar mejor la resolución disponible
Las sombras también tuvieron un impacto notable. En nuestro visor, el mapa de sombras utiliza una resolución de 4096 píxeles en escritorio y 2048 en móvil. Aumentar esa cifra tiene un coste alto: un mapa de 4096 × 4096 puede ocupar alrededor de 67 MB de memoria gráfica.
El problema inicial no era solo la resolución. La cámara que genera la sombra cubría una zona mucho mayor que la oficina. Como el edificio ocupa aproximadamente 1,34 × 0,98 unidades en la escena, dentro del encuadre predeterminado solo recibía una pequeña parte de los píxeles disponibles. El resultado eran bordes de sombra escalonados.
Ajustamos el encuadre de esa cámara a los límites reales del modelo. Así, los mismos píxeles se concentran sobre la oficina y la sombra gana detalle sin aumentar el tamaño del mapa.
También evitamos recalcular continuamente una sombra que no cambia. Si los objetos que la proyectan permanecen quietos, dibujar de nuevo su mapa en cada fotograma consume recursos sin mejorar la imagen.
El móvil obligó a revisar toda la escena
En un ordenador potente, una escena puede parecer resuelta y seguir teniendo problemas en móvil. Allí se nota antes la suma de texturas, geometrías, sombras y contextos WebGL.
Por eso el comparador entre arquitectura e instalaciones no monta su segunda escena al abrir el visor. Se crea cuando el usuario activa esa función. En una medición realizada con un iPhone X, retrasar esa carga evitaba alrededor de 57 MB al inicio: la huella pasaba de unos 230 MB a 173 MB.
Al salir del visor también liberamos explícitamente los recursos de la GPU. Cerrar una página no garantiza que Three.js suelte por sí solo todas las geometrías y texturas; si el usuario entra y sale varias veces, lo que parecía un problema de rendimiento puede terminar convirtiéndose en un lienzo negro.
Optimizar un gemelo digital es medir varios costes a la vez
En nuestro caso no hubo un único ajuste que lo resolviera todo. Draco redujo la descarga de las mallas; WebP y los límites de resolución ayudaron con las texturas; la fusión de geometrías redujo las draw calls; y los cambios en las sombras y la carga de escenas evitaron trabajo y consumo innecesarios.
La conclusión es sencilla: un modelo BIM preparado para web necesita medirse tanto como archivo como en funcionamiento. Hay que observar cuánto tarda en llegar, cuánta memoria ocupa una vez cargado y cuánto trabajo exige en cada fotograma. Solo así pudimos convertir el modelo de nuestra oficina en una experiencia que también tuviera sentido desde un móvil.
En la tercera parte veremos qué ocurre cuando ese espacio virtual empieza a recibir información de la oficina real: temperatura, presencia y estado de la puerta.