Any3DAny3D
·Any3D Team

¿Por qué los modelos 3D pesan tanto?

3d-compressiongltfwebglperformance

Tu modelo está engordando en secreto

Exportaste un archivo GLB, 10MB, parece estar bien. Lo abres en el móvil: pantalla blanca, tirones, o incluso un cuelgue directo.

En el ordenador ningún problema, en el móvil explota. No es culpa del código. Es una propiedad poco intuitiva de los modelos 3D: en disco y en memoria de vídeo, el tamaño es completamente distinto.

Una imagen JPG en disco puede ocupar solo 200KB. Pero la GPU no entiende JPG; solo entiende píxeles crudos. Así que, antes de subirla a la memoria de vídeo, la imagen se descomprime por completo. Una textura 2048x2048 consume unos 22MB de memoria de vídeo una vez descomprimida. Si usas 6 texturas (albedo, normal, roughness, metallic, AO, emissive), un solo material cuesta 132MB.

Un móvil puede tener en total solo 2-4GB de memoria de vídeo, y las texturas de un solo modelo consumen el 3-6%. ¿Y si hay 10 modelos en la escena?

Abrámoslo: a dónde van los bytes

Un modelo GLB típico se compone de tres partes principales: datos de vértices, texturas, y metadatos más animaciones.

Toma un modelo PBR real:

ComponenteQué esParte típicaNota
Texturasalbedo, normal, roughness, metallic, AO, etc.70-85%Casi siempre la mayor parte
Datos de vérticesposition, normal, UV, tangent, color10-20%Depende de la complejidad
Datos de animaciónesqueletos, skinning, fotogramas clave0-15%Solo si hay animación
Otrodefiniciones de material, estructura de escena, cámaras< 2%Despreciable

Las texturas ocupan alrededor del 80%. A menudo piensas que lo que hay que optimizar son los vértices, pero lo que realmente ocupa espacio son las texturas.

"Pequeño en disco" no significa "pequeño en memoria de vídeo"

Este es quizá el punto más importante para entender el rendimiento 3D.

PNG y JPG están diseñados para la transferencia por red——pequeños en disco, rápidos de descargar. Pero la GPU no puede usarlos directamente; primero deben descomprimirse por completo en píxeles crudos. La fórmula:

VRAM = ancho * alto * 4 bytes (RGBA) * 1.333 (con mipmaps)

Una textura RGBA 4096x4096:

MétricaValor
Tamaño del archivo PNG~8MB
Tamaño del archivo JPG~1.5MB
Uso de VRAM (con mipmaps)~87MB

Un JPG de 1.5MB se convierte en 87MB en memoria de vídeo.

¿Qué son los mipmaps? La GPU genera una serie de versiones cada vez más pequeñas de una textura, desde el tamaño original hasta 1x1 píxel, cada nivel la mitad del anterior. Esto hace que los objetos lejanos se rendericen más rápido y con mayor nitidez, pero cuesta un 33% más de memoria de vídeo. Casi todas las apps 3D usan mipmaps, así que este sobrecoste es prácticamente estándar.

Así que PNG y JPG son como bolsas de almacenamiento al vacío——comprimidas y pequeñas para el viaje, pero en el destino tienes que expandirlas por completo. La descarga fue más rápida, pero el ahorro de memoria de vídeo es cero.

Qué pasa cuando se agota la memoria de vídeo

No te aparecerá un bonito diálogo de "memoria insuficiente". La realidad es peor:

  • Móvil: pantalla blanca, o el sistema operativo cierra la pestaña directamente
  • Cascos VR: caídas de fotogramas. En VR, un fotograma perdido no es "un poco de lag"——provoca mareo
  • Escritorio: parpadeo de texturas, degradación, renderizado más lento

En Reddit, un desarrollador construyó una galería WebXR y metió 60 imágenes estereoscópicas en una Quest. Al principio funcionaba, luego fue cada vez más inestable hasta colgarse. Pasó días depurando el código antes de darse cuenta de que nunca había pensado seriamente en la VRAM——simplemente seguía metiendo JPGs en la GPU.

Dos caminos para la compresión

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

Compresión de vértices——almacena los datos geométricos (coordenadas de vértices, normales, UV) de forma más compacta. Por ejemplo, cambiar floats de 32 bits por enteros de 16 bits (esto se llama cuantización). Soluciones representativas: Draco, MeshOpt, KHR_mesh_quantization.

Compresión de texturas——mantiene las texturas comprimidas incluso dentro de la memoria de vídeo. La GPU decodifica píxeles individuales al vuelo durante el muestreo, casi sin coste de rendimiento. Solución representativa: KTX2 + Basis Universal.

Compresión de vérticesCompresión de texturas
Qué reduceDatos geométricosTexturas
Efecto típico50-90% más pequeño50-70% más pequeño en disco, 75% menos VRAM
¿Con pérdida?Sí, pérdida de precisiónSí, pérdida de calidad
Ideal paraModelos densos en vérticesCasi cualquier modelo PBR
VerParte 2Partes 3 y 4

Un error común: comprimir los vértices con Draco y ya está. Pero las texturas son el 80% del tamaño del modelo——reduce los vértices a la mitad y el conjunto puede encoger solo un 10%. Tienes que atacar ambos frentes.

Ningún método gana en todas partes

Esta es la tesis central de toda la serie:

Plataformas, dispositivos y usos distintos necesitan estrategias de compresión distintas.

EscenarioCuello de botella principalFoco
Showcase web de escritorioVelocidad de descargaTamaño del archivo
Navegador móvilMemoria de vídeoCompresión de texturas
Casco VRMemoria de vídeo + framerateCompresión de texturas + simplificación de vértices
WeChat Mini ProgramTamaño del paquete + compatibilidadOpciones ligeras (MeshOpt)
Escenas grandesMemoria de vídeo + draw callsCompresión completa + LOD

Cada próximo artículo no dirá solo "usa X y listo". Explicará: dónde brilla X, cuándo se vuelve en tu contra, y cuándo deberías usar Y en su lugar.

Próximos pasos

Este artículo dejó claro el problema. El siguiente es práctico——conoce las tres herramientas de la compresión de vértices: cuantización, MeshOpt y Draco.

Apóyanos