Kris

¿Por qué los modelos 3D pesan tanto?

Compresión 3DglTFWebGLRendimiento

Tu modelo está engordando en secreto

Exportas un archivo GLB, 10 MB, parece aceptable. Lo subes al móvil, lo abres: pantalla en blanco, tirones, o se cierra directamente.

En el ordenador va bien, pero en el móvil explota. No es culpa del código, sino de una característica poco intuitiva de los modelos 3D: el tamaño en disco y en la VRAM no tienen nada que ver.

Una imagen JPG puede ocupar solo 200 KB en disco. Pero la GPU no entiende de JPG, solo conoce píxeles en bruto. Así que antes de subirla a la VRAM, la imagen se descomprime por completo. Una textura de 2048x2048, descomprimida, ocupa aproximadamente 22 MB de VRAM. Si usas 6 texturas (albedo, normal, roughness, metallic, AO, emissive), solo un material se lleva 132 MB.

Un móvil suele tener entre 2 y 4 GB de VRAM. Con una textura ya te comes el 3-6%. ¿Y si hay 10 modelos en la escena?

Desglosemos: ¿dónde se va el tamaño?

Un modelo GLB típico se compone de tres partes principales: datos de vértices, texturas (mapas) y metadatos/animaciones.

Tomemos un modelo PBR real:

ComponenteContenido específicoPorcentaje típicoObservaciones
Mapas de texturaalbedo, normal, roughness, metallic, AO, etc.70-85%Casi siempre el mayor consumidor
Datos de vérticeposición, normal, UV, tangente, color10-20%Depende de la complejidad del modelo
Datos de animaciónhuesos, skinning, keyframes0-15%Solo si hay animación
Otrosdefinición de material, estructura de escena, cámara< 2%Despreciable

Las texturas suponen alrededor del 80%. Muchas veces crees que hay que optimizar los vértices, pero el verdadero lastre son las texturas.

Desglose de mapas de textura PBR en modelo 3D

"Tamaño en disco" ≠ "Tamaño en VRAM"

Quizás sea el punto más importante para entender el rendimiento 3D.

PNG y JPG están diseñados para la transmisión por red: ocupan poco en disco y se descargan rápido. Pero la GPU no puede usarlos directamente; primero hay que descomprimirlos por completo a píxeles en bruto. La fórmula:

Ocupación de VRAM = ancho * alto * 4 bytes (RGBA) * 1.333 (con mipmaps)

Una textura RGBA de 4096x4096:

IndicadorValor
Tamaño del archivo PNG~8 MB
Tamaño del archivo JPG~1.5 MB
Ocupación en VRAM (con mipmaps)~87 MB

1.5 MB de JPG se convierten en 87 MB de VRAM.

¿Qué son los mipmaps? La GPU genera versiones progresivamente reducidas de la textura, desde el tamaño original hasta 1x1 píxel, cada una la mitad de la anterior. Esto permite renderizar objetos lejanos más rápido y con mejor calidad, pero ocupa aproximadamente un 33% más de VRAM. Casi todas las aplicaciones 3D usan mipmaps, así que este gasto es estándar.

Así que PNG/JPG son como bolsas de compresión de viaje: pequeñas y cómodas de llevar, pero al llegar al destino hay que desplegarlas por completo. La descarga es rápida, pero la VRAM no se ahorra ni un byte.

Comparación de tamaño en disco frente a ocupación en VRAM de la GPU

¿Qué pasa cuando no hay suficiente VRAM?

No aparece un mensaje "memoria de video insuficiente". La realidad es peor:

  • Móviles: pantalla en blanco, o el sistema mata directamente la pestaña.
  • Gafas de VR: pérdida de fotogramas. En VR no es "va un poco lento", sino que provoca mareos.
  • Escritorio: texturas parpadeantes, degradación, renderizado más lento.

En Reddit, un desarrollador que hacía una galería WebXR para Quest metió 60 imágenes estereoscópicas. Al principio funcionaba, luego se volvió cada vez más inestable hasta colapsar. Pasó días revisando el código, y al final se dio cuenta de que nunca había pensado seriamente en la VRAM: solo estaba metiendo JPG en la GPU.

Los dos caminos de la compresión

La compresión de modelos 3D se divide principalmente en dos direcciones:

Compresión de vértices – almacenar coordenadas, normales, UV y otros datos geométricos de forma más compacta. Por ejemplo, cambiar números flotantes de 32 bits por enteros de 16 bits (lo que se llama cuantización). Representantes: Draco, MeshOpt, KHR_mesh_quantization.

Compresión de texturas – hacer que los mapas se mantengan comprimidos incluso en la VRAM. La GPU descomprime píxeles individuales en tiempo real durante el muestreo, sin apenas penalización de rendimiento. Representantes: KTX2 + Basis Universal.

Compresión de vérticesCompresión de texturas
¿Qué reduce?Datos geométricosMapas de textura
Efecto típicoReducción del 50-90%Disco: 50-70%, VRAM: 75%
¿Con pérdidas?Sí, pérdida de precisiónSí, pérdida de calidad visual
Escenario adecuadoModelos con muchos vérticesCasi todos los modelos PBR
Más detallesArtículo 2Artículos 3 y 4

Un error común: usar Draco para comprimir vértices y creer que está todo solucionado. Pero las texturas suponen el 80% del volumen del modelo. Si reduces los vértices a la mitad, el conjunto puede adelgazar solo un 10%. Hay que ocuparse de ambos frentes.

No hay un método que sirva para todo

Esta es la idea central de toda la serie:

Diferentes plataformas, diferentes dispositivos, diferentes formas de uso requieren diferentes estrategias de compresión.

EscenarioPrimer cuello de botellaFoco principal
Web en escritorioVelocidad de descargaTamaño del archivo
Navegador móvilVRAMCompresión de texturas
Gafas de VRVRAM + tasa de fotogramasCompresión de texturas + simplificación de vértices
Aplicaciones web ligerasTamaño del paquete + compatibilidadSoluciones ligeras (MeshOpt)
Escenas grandesVRAM + draw callsCompresión total + LOD

En los próximos artículos no diremos simplemente "usa X y listo". Explicaremos para qué escenarios es adecuado X, cuándo puede ser contraproducente y qué alternativa usar en cada caso.

Próximo paso

Este artículo ha aclarado el problema. En el siguiente, manos a la obra: conoceremos las tres herramientas de compresión de vértices: cuantización, MeshOpt y Draco.

Apóyanos