Perché i modelli 3D sono così pesanti?

Il tuo file GLB è solo 10MB, ma sul telefono divora 200MB di VRAM e poi crasha. Vediamo di capire dove sta il problema.

Compressione 3DglTFWebGLPrestazioni

Il tuo modello sta ingrassando di nascosto

Esporti un file GLB, 10MB, sembra ok. Lo apri sul telefono e... schermo bianco, lag, o addirittura crash.

Sul PC va benissimo, sul telefono esplode. Non è colpa del codice: i modelli 3D hanno una caratteristica controintuitiva: non occupano lo stesso spazio su disco e in VRAM.

Una foto JPG su disco può pesare solo 200KB. Ma la GPU non conosce i JPG, conosce solo i pixel grezzi. Quindi prima di essere caricata in VRAM, l'immagine viene completamente decompressa. Una texture 2048x2048, una volta decompressa, occupa circa 22MB di VRAM. Se usi 6 texture (albedo, normal, roughness, metallic, AO, emissive), un singolo materiale ti costa 132MB.

Un telefono ha in totale 2-4GB di VRAM: un solo modello con le sue texture occupa il 3-6%. E se nella scena ci sono 10 modelli?

Smontiamolo: dove va a finire lo spazio

Un tipico modello GLB è composto da tre parti principali: dati dei vertici, texture e metadati/animazioni.

Prendiamo un modello PBR reale:

ComponenteContenuto specificoPercentuale tipicaNote
Texturealbedo, normal, roughness, metallic, AO, ecc.70-85%Quasi sempre il peso maggiore
Verticiposizione, normali, UV, tangenti, colore10-20%Dipende dalla complessità
Animazioniossa, skinning, keyframe0-15%Solo se ci sono animazioni
Altrodefinizione materiali, struttura scena, camera< 2%Trascurabile

Le texture occupano circa l'80%. Spesso pensi di dover ottimizzare i vertici, ma il vero peso sono le texture.

Scomposizione delle texture PBR di un modello 3D

"Poco su disco" non significa "poco in VRAM"

Questo è forse il punto più importante per capire le performance 3D.

PNG e JPG sono progettati per la trasmissione in rete: piccoli su disco, veloci da scaricare. Ma la GPU non può usarli direttamente: devono prima essere decompressi completamente in pixel grezzi. Il calcolo è:

VRAM occupata = larghezza * altezza * 4 byte (RGBA) * 1.333 (con mipmap)

Una texture RGBA 4096x4096:

MetricaValore
Dimensione file PNG~8MB
Dimensione file JPG~1.5MB
VRAM occupata (con mipmap)~87MB

Un JPG da 1.5MB, in VRAM diventa 87MB.

Cosa sono i mipmap? La GPU genera una serie di versioni progressivamente ridotte della texture, dalla dimensione originale fino a 1x1 pixel, ogni livello è la metà del precedente. Questo rende il rendering degli oggetti distanti più veloce e nitido, ma richiede circa il 33% di VRAM in più. Quasi tutte le applicazioni 3D usano i mipmap, quindi questo costo è praticamente standard.

PNG/JPG sono come i sacchetti sottovuoto da viaggio: compressi sono piccoli e facili da trasportare, ma una volta a destinazione devi gonfiarli tutti. Il download è veloce, ma la VRAM non si risparmia affatto.

Confronto tra spazio su disco e occupazione VRAM

Cosa succede quando la VRAM non basta

Non appare un messaggio "memoria insufficiente". La realtà è molto peggiore:

  • Mobile: schermo bianco, oppure il sistema uccide direttamente la scheda del browser
  • Visori VR: frame drop. In VR il lag non è "un po' lento", provoca nausea
  • Desktop: texture che sfarfallano, downgrade grafico, rendering più lento

Su Reddit un developer stava costruendo una galleria WebXR e ha caricato 60 foto stereo su un Quest. All'inizio andava bene, poi sempre più instabile fino al crash. Ha passato giorni a cercare nel codice, per poi scoprire che non aveva mai pensato alla VRAM: continuava a caricare JPG nella GPU.

Le due strade della compressione

La compressione dei modelli 3D si divide in due direzioni principali:

Compressione dei vertici — memorizza i dati geometrici (posizioni, normali, UV) in modo più compatto. Ad esempio, passare da float a 32 bit a interi a 16 bit (si chiama quantizzazione). Soluzioni rappresentative: Draco, MeshOpt, KHR_mesh_quantization.

Compressione delle texture — mantiene le texture compresse anche in VRAM. La GPU decodifica i singoli pixel in tempo reale durante il campionamento, con overhead quasi nullo. Soluzioni rappresentative: KTX2 + Basis Universal.

Compressione verticiCompressione texture
Cosa riduceDati geometriciTexture
Effetto tipico-50-90%Disco -50-70%, VRAM -75%
Con perdita?Sì, precisioneSì, qualità visiva
Caso d'uso idealeModelli con molti verticiQuasi tutti i modelli PBR
ApprofondimentoArticolo 2Articoli 3 e 4

Un errore comune: usare Draco per i vertici e pensare di aver risolto tutto. Ma le texture occupano l'80% del modello: se dimezzi i vertici, il totale cala solo del 10%. Bisogna gestire entrambi i fronti.

Non esiste una soluzione unica per tutti

Questo è il punto centrale dell'intera serie:

Piattaforme diverse, dispositivi diversi, casi d'uso diversi richiedono strategie di compressione diverse.

ScenarioCollo di bottiglia principaleFocus principale
Web desktopVelocità di downloadDimensione file
Browser mobileVRAMCompressione texture
Visori VRVRAM + frame rateCompressione texture + semplificazione vertici
App ibride (es. mini-program)Dimensione pacchetto + compatibilitàSoluzioni leggere (MeshOpt)
Scene di grandi dimensioniVRAM + draw callCompressione completa + LOD

Nei prossimi articoli non diremo solo "usa X e basta": spiegheremo per cosa è adatto X, quando invece è controproducente, e in quali casi conviene usare Y.

Prossimo passo

Questo articolo ha chiarito il problema. Il prossimo si mette al lavoro: conosciamo i tre strumenti della compressione dei vertici: quantizzazione, MeshOpt e Draco.

Strumenti correlati

6
Vedi tutto
Compressione modelli 3D
Da modello 3D a immagine
Visualizzatore di modelli 3D
Compressione vertici modello 3D
STL in immagine
Visualizzatore GLB