De Blender à la mise en ligne : compression de bout en bout
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 initiale | Valeur |
|---|---|
| Fichier source Blender | ~120 Mo (inclut le high-poly non exporté) |
| Export GLB (float32 + PNG) | ~50 Mo |
| Nombre de sommets | ~180 000 |
| Textures | 6 × 4096×4096 (albedo, normal, roughness, metallic, AO, emissive) |
| Mémoire GPU (6 textures décompressées) | ~520 Mo |
| Objectif | Fichier ≤ 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
NormalsetTangents(les normal maps PBR nécessitent les tangentes) - UV : assurez-vous qu'ils sont exportés (activé par défaut)
- Textures :
AutomaticouJPEG(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 Orphanset 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 :
| Outil | Points forts | Points faibles | Idéal pour |
|---|---|---|---|
| gltf-transform | Polyvalent, gère textures + sommets, API scriptable | Taux de compression extrême inférieur aux outils spécialisés | Outil principal recommandé, la plupart des cas |
| gltfpack | Expert en compression de sommets, support natif MeshOpt | Faible pour la compression de textures | Modèles denses en sommets, contrôle fin MeshOpt |
| toktx | Le plus professionnel pour les textures, paramètres complets | Ne gère que les textures, pas le modèle entier | Réglage fin de textures individuelles |
| gltf-pipeline | Ancien, supporte Draco | Maintenance inactive, peu de fonctionnalités | Anciens projets Draco |
| Outils en ligne (gltf.report) | Zéro installation | Pas adapté à l'automatisation ou aux gros volumes | Tests, 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
| Étape | Taille du fichier | Mémoire GPU | Changement |
|---|---|---|---|
| Référence | 50 Mo | ~520 Mo | — |
| Étape 1 Déduplication | 45 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.
| Étape | Taille du fichier | Mémoire GPU | Changement |
|---|---|---|---|
| Étape 1 | 45 Mo | ~520 Mo | — |
| Étape 2 + MeshOpt | 30 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.
| Étape | Taille du fichier | Mémoire GPU | Changement |
|---|---|---|---|
| Étape 2 | 30 Mo | ~520 Mo | — |
| Étape 3 + KTX2 | 6 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.
| Étape | Taille du fichier | Mémoire GPU | Changement |
|---|---|---|---|
| Étape 3 | 6 Mo | ~70 Mo | — |
| Étape 4 + Simplification 0.5 | 4,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) :
| Étape | Taille du fichier | Mémoire GPU | Réduction cumulée |
|---|---|---|---|
| Référence (float32 + PNG) | 50 Mo | ~520 Mo | — |
| + Déduplication + soudure | 45 Mo | ~520 Mo | -10 % |
| + MeshOpt sommets | 30 Mo | ~520 Mo | -40 % |
| + Textures KTX2 | 6 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
--srgbsur 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-ratiotrop 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
fallbackdeKHR_texture_basisupour 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
| Composant | Proportion | Outil d'optimisation |
|---|---|---|
| Textures | 70-85 % | KTX2 (gain maximal) |
| Données de sommets | 10-20 % | MeshOpt / quantification / Draco |
| Données d'animation | 0-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'usage | Recommandation |
|---|---|
| Zéro dépendance, le plus simple | Quantification pure (KHR_mesh_quantization) |
| Meilleur choix Web équilibré | MeshOpt |
| Taux de compression extrême, décodage acceptable | Draco |
| Mini-programmes / sensibilité au poids du package | Quantification pure / MeshOpt, éviter Draco |
Choix de compression des textures
| Type de texture | Encodage recommandé |
|---|---|
| albedo / emissive (couleur) | KTX2 ETC1S |
| normal / roughness / metallic / AO (données) | KTX2 UASTC |
| Web desktop, priorité à la vitesse de téléchargement | WebP / 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
| Plateforme | Textures | Sommets |
|---|---|---|
| Web desktop | WebP / KTX2 | MeshOpt |
| Web mobile | **KTX |