Kris

De Blender à la mise en ligne : compression de bout en bout

Compression 3DPipelineCompression de textureCompression de sommetsglTF

La série a couvert les outils, les principes et les choix possibles. Pour ce dernier article, nous allons tout assembler en un pipeline fonctionnel : à partir d'un modèle Blender réaliste, nous compressons étape par étape, en notant à chaque fois la taille du fichier, la mémoire GPU et le temps de chargement. Objectif final : voir si notre gros bébé de 50 Mo peut devenir un modèle de 5 Mo qui s'ouvre instantanément sur mobile.

Ceci s'adresse à celles et ceux qui ont lu les 5 premiers articles et qui sont prêts à passer à la pratique. Pas de nouveaux concepts ici, seulement des procédures, des commandes et des scripts prêts à l'emploi.

Point de départ : un modèle PBR réaliste

Prenons un modèle typique de vitrine e-commerce : un produit haute précision avec ses textures PBR complètes.

Métrique initialeValeur
Fichier source Blender~120 Mo (inclut le high-poly non exporté)
Export GLB (float32 + PNG)~50 Mo
Nombre de sommets~180 000
Textures6 × 4096×4096 (albedo, normal, roughness, metallic, AO, emissive)
Mémoire GPU (6 textures décompressées)~520 Mo
ObjectifFichier ≤ 5 Mo, mémoire GPU maîtrisée, chargement instantané sur mobile

Un fichier de 50 Mo et 520 Mo de mémoire GPU : ce modèle ferait planter n'importe quel mobile. On y va étape par étape.

Étape 0 : exporter correctement depuis Blender

Le premier obstacle, c'est l'export. Beaucoup de gens perdent déjà du sang ici.

Réglages clés pour l'export glTF depuis Blender :

  • Format : glTF Binary (.glb) (fichier unique, facile à transférer)
  • Géométrie : cochez Normals et Tangents (les normal maps PBR nécessitent les tangentes)
  • UV : assurez-vous qu'ils sont exportés (activé par défaut)
  • Textures : Automatic ou JPEG (le format ici n'a pas d'importance, on recompressera plus tard, mais il faut qu'elles soient exportées)
  • Compression : ne cochez pas la compression Mesh intégrée de Blender, nous utiliserons des outils plus professionnels
  • Transformations : +Y Up (standard glTF)
  • Données : ne cochez que le nécessaire (si vous n'avez pas besoin d'animations, caméras ou lumières, ne les exportez pas pour réduire la taille)

Le model.glb exporté : 50 Mo, 6 textures PNG, sommets en float32. C'est notre référence.

Premier piège classique ici : Blender exporte par défaut les meshes inutilisés et les objets auxiliaires cachés. Avant l'export, faites File > Clean Up > Purge Orphans et ne sélectionnez que les objets à exporter dans l'outliner.

Vue d'ensemble du pipeline de bout en bout

Visualisons l'ensemble du pipeline pour avoir une vue d'ensemble :

Fichier source Blender
   │  Export .glb (float32 + PNG)            50 Mo
   ▼
[1] Déduplication + soudure des sommets (gltf-transform)   ~45 Mo
   │
[2] Compression des sommets : MeshOpt (gltfpack / gltf-transform) ~30 Mo
   │
[3] Compression des textures : PNG → KTX2 (ETC1S/UASTC)     ~6 Mo
   │
[4] (Optionnel) Simplification géométrique LOD (simplify)   ~4-5 Mo
   ▼
model-final.glb final                          ~5 Mo
   │
Chargement moteur (Three.js / Babylon.js) → transcodage runtime → mise en ligne

Les chiffres de chaque étape seront suivis en temps réel dans les tableaux ci-dessous.

La boîte à outils : que choisir ?

Plusieurs outils de compression existent. Comparons-les pour éviter les erreurs de choix :

OutilPoints fortsPoints faiblesIdéal pour
gltf-transformPolyvalent, gère textures + sommets, API scriptableTaux de compression extrême inférieur aux outils spécialisésOutil principal recommandé, la plupart des cas
gltfpackExpert en compression de sommets, support natif MeshOptFaible pour la compression de texturesModèles denses en sommets, contrôle fin MeshOpt
toktxLe plus professionnel pour les textures, paramètres completsNe gère que les textures, pas le modèle entierRéglage fin de textures individuelles
gltf-pipelineAncien, supporte DracoMaintenance inactive, peu de fonctionnalitésAnciens projets Draco
Outils en ligne (gltf.report)Zéro installationPas adapté à l'automatisation ou aux gros volumesTests, tâches ponctuelles

Recommandation principale : utilisez gltf-transform pour tout le pipeline, complétez avec gltfpack pour les sommets et toktx pour les textures individuelles si nécessaire. Toutes les étapes ci-dessous sont basées sur gltf-transform.

Étape 1 : Déduplication + soudure

Les modèles contiennent souvent des sommets en double, des nœuds et matériaux inutilisés. Nettoyons d'abord.

gltf-transform optimize model.glb step1.glb --weld --prune
ÉtapeTaille du fichierMémoire GPUChangement
Référence50 Mo~520 Mo
Étape 1 Déduplication45 Mo~520 Mo-5 Mo (la mémoire GPU ne change pas, les textures sont toujours là)

La mémoire GPU ne bouge presque pas, c'est attendu — la déduplication économise principalement sur les sommets et la structure, les textures sont le gros morceau de la mémoire GPU.

Étape 2 : Compression des sommets avec MeshOpt

gltf-transform optimize step1.glb step2.glb --meshopt --weld --prune

--meshopt quantifie les sommets en 16 bits et les encode sans perte avec MeshOpt, en ajoutant automatiquement l'extension EXT_meshopt_compression.

ÉtapeTaille du fichierMémoire GPUChangement
Étape 145 Mo~520 Mo
Étape 2 + MeshOpt30 Mo~520 Mo-15 Mo (partie sommets)

La mémoire GPU reste à ~520 Mo ? Oui — car les sommets ne représentent qu'une petite partie de la mémoire GPU (10-20 %). Réduire les sommets a un impact limité sur la mémoire GPU. Le vrai monstre, ce sont les textures. On s'en occupe à l'étape suivante.

Étape 3 : Compression des textures PNG → KTX2

C'est l'étape au meilleur rapport qualité-prix.

gltf-transform optimize step2.glb step3.glb \
  --texture-compress basisu \
  --meshopt --weld --prune

--texture-compress basisu détermine automatiquement le type de chaque texture : les textures de couleur (albedo, emissive) en ETC1S, les textures de données (normal, roughness, metallic, AO) en UASTC.

ÉtapeTaille du fichierMémoire GPUChangement
Étape 230 Mo~520 Mo
Étape 3 + KTX26 Mo~70 Mo-24 Mo fichier / -450 Mo mémoire GPU

Cette étape est le tournant du pipeline :

  • Le fichier passe de 30 Mo à 6 Mo
  • La mémoire GPU passe de 520 Mo à environ 70 Mo — car les 6 textures 4096 passent de « pixels bruts décompressés » à « compression par blocs », chaque texture passant de ~87 Mo à ~11-14 Mo

La mémoire GPU est réduite d'un ordre de grandeur, c'est ce qui rend le mobile possible.

Étape 4 : (Optionnel) Simplification géométrique

Si vous voulez aller encore plus loin et que le cas d'usage le permet, vous pouvez ajouter une simplification géométrique.

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

--simplify-ratio 0.5 signifie conserver environ 50 % des sommets.

ÉtapeTaille du fichierMémoire GPUChangement
Étape 36 Mo~70 Mo
Étape 4 + Simplification 0.54,5 Mo~70 Mo-1,5 Mo (mémoire GPU quasi inchangée)

La simplification réduit principalement la taille du fichier, avec un impact limité sur la mémoire GPU. Le compromis : les détails du modèle diminuent — perceptible en vision rapprochée. Pour les pages produits e-commerce, on évite généralement de trop simplifier ; pour l'architecture ou les grandes scènes, c'est très pertinent.

Tableau de suivi des résultats

Vue d'ensemble des quatre étapes (basée sur l'échantillon ci-dessus, chiffres donnés à titre indicatif) :

ÉtapeTaille du fichierMémoire GPURéduction cumulée
Référence (float32 + PNG)50 Mo~520 Mo
+ Déduplication + soudure45 Mo~520 Mo-10 %
+ MeshOpt sommets30 Mo~520 Mo-40 %
+ Textures KTX26 Mo~70 Mo-88 % fichier / -87 % mémoire GPU
+ Simplification géométrique (0.5)4,5 Mo~70 Mo-91 % fichier

Conclusion : la compression des textures apporte l'essentiel des gains en taille et en mémoire GPU. La compression des sommets est un bonus, la compression des textures est indispensable. Cela confirme parfaitement le premier article — les textures représentent 80 % du volume, c'est là que l'optimisation rapporte le plus.

Version commande unique : la compression en un clic

Si vous ne voulez pas suivre les étapes une par une, voici la commande tout-en-un :

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

Cette commande unique = déduplication + soudure + sommets MeshOpt + textures KTX2 + simplification géométrique. Elle suffit pour 90 % des cas. Les étapes séparées servent surtout à comprendre et à régler les paramètres.

Pas envie de configurer un environnement ? Utilisez la compression en ligne Any3D

Les commandes et scripts gltf-transform ci-dessus nécessitent d'installer Node, de configurer la chaîne d'outils et de mémoriser des paramètres. L'outil de compression en ligne d'Any3D élimine tout cela :

  • Pas de téléchargement de script, pas d'installation d'environnement — ouvrez la page web et c'est prêt
  • Le modèle ne quitte pas votre appareil — tout est traité localement dans le navigateur
  • Configuration visuelle — textures KTX2, sommets MeshOpt, simplification géométrique : réglez avec des curseurs et prévisualisez en temps réel
  • Export multi-versions en un clic — exportez les résultats compressés par plateforme (mobile / desktop / VR)

Sélectionnez un GLB, choisissez la plateforme cible, cliquez, et récupérez le modèle compressé. Les fondations sont les mêmes que la ligne de commande (gltf-transform), mais sans barrière à l'entrée et sans toucher au terminal.

FAQ : les pièges courants

Le modèle devient noir / les textures ne s'affichent pas après compression

  • Dans 99 % des cas, c'est l'espace colorimétrique : la texture de couleur n'a pas de sRGB. Dans Three.js : texture.colorSpace = THREE.SRGBColorSpace.
  • Avec toktx, oublier --srgb sur les textures de couleur.

L'éclairage est incorrect après compression de la normal map

  • La normal map a été encodée en ETC1S, passez en UASTC.
  • La normal map est au format DirectX (canal vert vers le bas), mais le moteur attend du OpenGL : il faut inverser le canal G.

Le chargement sur mobile bloque à l'écran d'accueil

  • Vérifiez si le décodeur Draco wasm est chargé (requête supplémentaire). Sur mobile, privilégiez MeshOpt.
  • Le chemin du transcodeur KTX2 est mal configuré, l'échec de transcodage retombe sur une décompression CPU.

Le fichier est plus gros après compression

  • Textures trop petites (< 128 px) : la compression KTX2 n'est pas rentable, la compression par blocs a un coût fixe.
  • Le modèle a déjà été compressé : recompresser n'apporte rien (voire dégrade).

Le modèle se déforme après simplification

  • --simplify-ratio trop bas, remontez à 0,7-0,8.
  • La simplification fonctionne bien sur les surfaces dures (mécanique, architecture), mais mal sur les surfaces organiques (personnages).

Les textures KTX2 ne chargent pas sur certains navigateurs

  • Anciennes versions de Safari / anciens WebView non supportés. Préparez un fallback PNG/WebP, ou utilisez le champ fallback de KHR_texture_basisu pour fournir une texture de secours.

Aide-mémoire de la série

Tout l'essentiel des 6 articles condensé en un tableau. À conserver précieusement.

Composition du volume

ComposantProportionOutil d'optimisation
Textures70-85 %KTX2 (gain maximal)
Données de sommets10-20 %MeshOpt / quantification / Draco
Données d'animation0-15 %Réduction des keyframes / compression
Autres< 2 %Déduplication

Formule mémoire GPU

Mémoire GPU format traditionnel = largeur * hauteur * 4 octets * 1,333 (avec mipmaps)
Mémoire GPU compression par blocs KTX2 ≈ formule ci-dessus / 4 (ETC1S) ou / 2 (UASTC)

Choix de compression des sommets

Cas d'usageRecommandation
Zéro dépendance, le plus simpleQuantification pure (KHR_mesh_quantization)
Meilleur choix Web équilibréMeshOpt
Taux de compression extrême, décodage acceptableDraco
Mini-programmes / sensibilité au poids du packageQuantification pure / MeshOpt, éviter Draco

Choix de compression des textures

Type de textureEncodage recommandé
albedo / emissive (couleur)KTX2 ETC1S
normal / roughness / metallic / AO (données)KTX2 UASTC
Web desktop, priorité à la vitesse de téléchargementWebP / AVIF
Petites textures (< 128 px)Conserver en PNG, ne pas compresser en KTX2

Commande unique

# Optimisation complète (textures + sommets + simplification)
gltf-transform optimize model.glb model-final.glb \
  --texture-compress basisu --meshopt \
  --simplify --simplify-ratio 0.5 --weld --prune

Aide-mémoire par plateforme

PlateformeTexturesSommets
Web desktopWebP / KTX2MeshOpt
Web mobile**KTX
Nous soutenir