Any3DAny3D
·Any3D Team

Piattaforme diverse, destini diversi: una guida alla selezione della compressione

3d-compressiontexture-compressionvertex-compressionoptimizationpipeline

I quattro articoli precedenti trattavano gli strumenti della compressione di vertici e texture. Ma sapere usare gli strumenti è una cosa; quale usare e in quale scenario è un'altra. Questo articolo risponde a questo — e mira a farti decidere appena finito di leggere.

Dopo questo articolo dovresti saper rispondere: su quale piattaforma gira il mio progetto, il collo di bottiglia del primo paint è download o VRAM, e quale schema dovrebbero usare rispettivamente texture e vertici.

Dare l'indirizzo: guidato dallo scenario, non dallo strumento

L'intero articolo ha un principio centrale, quello che la serie continua a sottolineare:

Non esiste uno schema di compressione «migliore» — solo lo schema «più adatto allo scenario».

Tre variabili che guidano la scelta:

  1. Piattaforma/dispositivo: PC desktop, browser mobile, visore VR, Mini Program — capacità radicalmente diverse
  2. Uso: visualizzazione una tantum (pagina prodotto e-commerce) o immersione lunga (gioco VR)
  3. Collo di bottiglia principale: download lento, VRAM insufficiente o decode che blocca il primo paint

Pensa prima al collo di bottiglia, poi torna a scegliere gli strumenti. La matrice sotto fissa questo ragionamento.

Matrice decisionale centrale: piattaforma × schema consigliato

Questa è la tabella più importante dell'articolo. Per piattaforma, dà lo schema consigliato per texture e vertice, con le ragioni.

Piattaforma / scenarioSchema textureSchema verticeCollo di bottigliaRagione chiave
Web desktop (PC browser)KTX2 o WebPMeshOpt / quantizzazioneVelocità di downloadVRAM ampia; focus su file piccoli, caricamento rapido
Web mobile (telefono browser)KTX2 (obbligatorio)MeshOptVRAMLa VRAM del telefono è stretta; le texture devono essere compresse a blocchi
WebXR / visore VRKTX2 (obbligatorio)MeshOpt + LODVRAM + framerateL'esplosione della VRAM crashea; i frame drop danno nausea
WeChat Mini ProgramKTX2 / WebPMeshOpt / quant. puraPacchetto + compat.Dimensione pacchetto limitata; evitare decoder pesanti
Prodotto e-commerceWebP (leggero) / KTX2 (preciso)MeshOptVelocità primo paintEsige apertura istantanea; scambiare dimensione per velocità
Scene grandi / gemello digitaleKTX2 (obbligatorio)MeshOpt + Draco + LODVRAM + draw callMolte texture, modelli grandi; comprimere su tutti i fronti

Alcuni giudizi da ricordare:

  • Ogni volta che la VRAM è il collo di bottiglia, KTX2 è obbligatorio (mobile, VR, scene grandi)
  • Quando il download è il collo di bottiglia e la VRAM è ampia, WebP basta (desktop, e-commerce)
  • Per ambienti sensibili al pacchetto come i Mini Program, preferire MeshOpt a Draco — decoder più piccolo, compatibilità migliore
  • Considera Draco solo per modelli molto grandi; per la stragrande maggioranza dei modelli medio-piccoli MeshOpt è più equilibrato

Formati di texture confrontati su tutte le dimensioni

Sapere «usa KTX2» non basta. Per i formati di texture, dispiegare tutte le dimensioni:

FormatoDim. fileUso VRAMVelocità uploadCompatibilitàQualitàUso
PNGGrandeGrande (dopo decompr.)LentoMolto ampiaSenza perditaValori esatti/alfa necessari o fallback legacy
JPGPiccolissimoGrande (dopo decompr.)LentoMolto ampiaCon perditaColor map, priorità di rete
WebPMolto piccolaGrande (dopo decompr.)LentoAbbastanza ampiaAltaWeb desktop, inseguire velocità di download
AVIFAncora più piccolaGrande (dopo decompr.)LentoProgressivoAltaNuove piattaforme, compressione estrema
KTX2 (ETC1S)PiccolaMinuscolaVeloceTranscode richiestoMedia (colore ok)Color map, mobile/VR
KTX2 (UASTC)MediaPiccolaVeloceTranscode richiestoAltaNormal/data map

Nota le prime tre righe (PNG/JPG/WebP/AVIF) con VRAM «grande» — per quanto piccole su disco, una volta nella VRAM tutte si decomprimono a pixel grezzi. Questo è il limite fondamentale dei formati tradizionali.

Una strategia mista è comune: le color map chiave usano KTX2 per garantire la VRAM; le map secondarie (es. una piccola emissive) usano WebP per comodità. Non devi andare per tutto KTX2; ripartisci in base al collo di bottiglia.

Diagramma di flusso decisionale: scegliere passo dopo passo

La matrice è il risultato; il diagramma di flusso mostra come arrivarci.

Dove gira il tuo progetto?
│
├─ Web desktop (VRAM ampia)
│   └─ Primo paint lento?
│       ├─ Sì → WebP (o AVIF) + MeshOpt  [inseguire velocità di download]
│       └─ No, ma molti modelli → KTX2 + MeshOpt [margine per il futuro]
│
├─ Web mobile / VR / scene grandi (VRAM stretta)
│   └─ Le texture obbligatoriamente KTX2 (colore ETC1S, dati UASTC)
│       └─ Vertici super-densi?
│           ├─ Sì → + Draco [rapporto massimo, tollera decode lento]
│           └─ No → + MeshOpt [equilibrato]
│
└─ Mini Program / runtime ristretto
    └─ Sensibile al pacchetto?
        ├─ Sì → quantizzazione pura o MeshOpt + WebP [decoder nullo/piccolo]
        └─ Ok → MeshOpt + KTX2 [combinazione standard]

Compressione vertici vs texture: dove investire

Domanda frequente: budget limitato, ottimizzare cosa per primo? Guarda la composizione del modello:

Tratto del modelloFocus di investimentoRagione
Personaggio/prodotto PBR (molte map)Compressione textureLe texture sono 80%+; ROI dei vertici basso
Modello CAD/scan (vertici super-densi, poche map)Compressione verticiI vertici sono la parte principale
Personaggio animato (scheletro + skinning)Investi in entrambi, ma vertici oltre Draco in prioritàAnche i dati di animazione pesano; Draco è debole con animazione
Edificio/scena (grande, map medie)Texture + LODLe texture risparmiano VRAM; il LOD risparmia draw call

Una classifica di rendimento approssimativa: texture KTX2 > vertice MeshOpt/quantizzazione > semplificazione geometria (LOD) > vertice Draco. Fai prima quelli a rendimento più alto.

Strategia mista: map chiave KTX2, map secondarie WebP

Non tutte le map meritano di essere compresse in KTX2. Un materiale PBR tipico ha 5-6 map; comprimere tutto in KTX2 è molto engineering e a volte superfluo.

Ripartizione pratica:

  • KTX2 obbligatorio: albedo (grande, colore), normal (sensibile alla precisione), roughness/metallic (influenzano l'illuminazione)
  • WebP/JPG possibile: emissive (di solito piccolo), AO (frequenza medio-bassa), normale di dettaglio (se presente)

Criterio: la map è grande, è un dettaglio ad alta frequenza, viene campionata di frequente? Tutti e tre → KTX2; nessuno → un formato tradizionale è più semplice.

Selezione automatizzata: gltf-transform lo fa in un colpo

Il comando optimize di gltf-transform è il proiettile d'argento per la maggior parte degli scenari — rileva i tipi di texture automaticamente, comprime le texture con la strategia consigliata e opzionalmente tratta i vertici.

# Installare
npm install -g @gltf-transform/cli

# Ottimizzazione standard: texture KTX2 + vertice MeshOpt + dedup
gltf-transform optimize model.glb model-optimized.glb \
  --texture-compress basisu \
  --meshopt

Riferimento dei parametri:

ParametroEffettoPredefinito
--texture-compress basisuComprimere le texture in KTX2 (auto ETC1S/UASTC)Off
--meshoptAttivare la compressione MeshOpt dei verticiOff
--simplifySemplificazione geometria (riduce vertici, con perdita)Off
--weldFondere vertici duplicatiOn
--pruneRimuovere nodi/materiali non usatiOn

Una combinazione di «compressione forte» per il mobile:

gltf-transform optimize model.glb model-mobile.glb \
  --texture-compress basisu \
  --meshopt \
  --simplify --simplify-ratio 0.5 \
  --prune --weld

Una combinazione «morbida» per il desktop (preservare il dettaglio, comprimere solo texture e vertici):

gltf-transform optimize model.glb model-desktop.glb \
  --texture-compress webp \
  --meshopt

Avvolgerlo come script riutilizzabile

Incapsula quanto sopra in uno script che produce una versione per piattaforma:

// compress.mjs — produce versioni compresse diverse per target
import { optimize } from "@gltf-transform/functions";
import { NodeIO } from "@gltf-transform/core";
import { KHRONOS_EXTENSIONS } from "@gltf-transform/extensions";

const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS);

const targets = {
  // Mobile: KTX2 + MeshOpt + semplificazione
  mobile: { texture: "basisu", meshopt: true, simplify: 0.5 },
  // VR: KTX2 + MeshOpt, nessuna semplificazione (visione ravvicinata in VR)
  vr: { texture: "basisu", meshopt: true, simplify: null },
  // Desktop: WebP + MeshOpt, morbido
  desktop: { texture: "webp", meshopt: true, simplify: null },
};

const input = process.argv[2];
const doc = await io.read(input);

for (const [name, cfg] of Object.entries(targets)) {
  const out = doc.clone(); // copia indipendente per target
  await optimize(out, {
    textureCompression: cfg.texture,
    meshCompression: cfg.meshopt ? "meshopt" : null,
    simplify: cfg.simplify != null ? { ratio: cfg.simplify } : null,
  });
  await io.write(`model-${name}.glb`, out);
  console.log(`✓ model-${name}.glb`);
}
node compress.mjs model.glb
# Produce model-mobile.glb / model-vr.glb / model-desktop.glb

A runtime, carica la versione corrispondente per dispositivo (distingui via UA o rilevamento capacità WebGL) per la migliore esperienza di primo paint. Il prossimo articolo lega tutto nel walkthrough end-to-end.

Promemoria in una riga

  • La VRAM è il collo → KTX2, nessuna scelta
  • Il download è il collo, VRAM ampia → WebP/AVIF anche
  • Sensibile alla dimensione del decoder → MeshOpt > quantizzazione pura > Draco
  • Modelli molto grandi → solo allora considera Draco
  • Incerto → esegui gltf-transform optimize in un colpo; se sbagliato, regola

Prossimo passo

Il quadro di selezione è pronto. L'ultimo articolo chiude: partendo da un modello reale, percorrere l'intero flusso di esportazione Blender, compressione texture, compressione vertici e caricamento nel motore, con uno script di automazione completo e un promemoria della serie.

Supportaci