Kris

Perché i modelli 3D sono così pesanti?

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.

Supportaci