Kris

Pourquoi les modèles 3D sont-ils si lourds ?

Compression 3DglTFWebGLPerformance

Votre modèle grossit en cachette

Vous avez exporté un fichier GLB de 10 Mo. « Ça passe », pensez-vous. Vous l’ouvrez sur votre mobile – écran blanc, ralentissements, voire crash pur et simple.

Sur l’ordinateur, tout va bien. Sur mobile, ça explose. Ce n’est pas la faute de votre code, mais d’une propriété contre‑intuitive des modèles 3D : leur taille sur le disque n’a rien à voir avec celle qu’ils occupent dans la mémoire de la carte graphique (VRAM).

Une image JPG ne pèse que 200 Ko sur le disque. Mais le GPU ne connaît pas le JPG : il ne comprend que les pixels bruts. Avant de l’envoyer en VRAM, l’image est complètement décompressée. Une texture 2048×2048 occupe environ 22 Mo de VRAM. Si vous utilisez 6 textures (albedo, normal, roughness, metallic, AO, emissive), un seul matériau engloutit 132 Mo.

Un mobile dispose typiquement de 2 à 4 Go de VRAM. Un seul modèle de votre scène en prend 3 à 6 %. Et si vous avez 10 modèles ?

Ouvrons le capot : où va tout ce poids ?

Un modèle GLB classique se compose de trois parties principales : les données de sommets, les textures, et les métadonnées / animations.

Prenons un modèle PBR réel :

ComposantContenu détailléPart typiqueRemarque
Texturesalbedo, normal, roughness, metallic, AO, etc.70–85 %Presque toujours le plus gros
Données de sommetsposition, normal, UV, tangente, couleur10–20 %Dépend de la complexité
Données d’animationsquelette, skinning, keyframes0–15 %Seulement si animé
Autresdéfinition des matériaux, structure de scène, caméra< 2 %Négligeable

Les textures représentent environ 80 % du poids. Souvent, on pense qu’il faut optimiser les sommets, mais le vrai coupable, ce sont les textures.

Décomposition des textures PBR d’un modèle 3D

« Petit sur le disque » ≠ « Petit en VRAM »

C’est peut‑être le point le plus important pour comprendre les performances 3D.

Le PNG et le JPG sont conçus pour le transport réseau – petits sur le disque, téléchargement rapide. Mais le GPU ne peut pas les utiliser directement : il doit d’abord les décompresser entièrement en pixels bruts. Calcul :

Occupation VRAM = largeur × hauteur × 4 octets (RGBA) × 1,333 (avec mipmaps)

Une texture RGBA 4096×4096 :

IndicateurValeur
Taille fichier PNG~8 Mo
Taille fichier JPG~1,5 Mo
Occupation VRAM (avec mipmaps)~87 Mo

Un JPG de 1,5 Mo devient 87 Mo en VRAM.

C’est quoi les mipmaps ? Le GPU génère une série de versions de plus en plus petites de la texture, de la taille originale jusqu’à 1×1 pixel, chaque niveau étant la moitié du précédent. Cela permet d’afficher plus vite et plus net les objets lointains, mais ça coûte environ 33 % de VRAM supplémentaire. Presque toutes les applis 3D les utilisent, donc cette surcharge est la norme.

Ainsi, le PNG/JPG est comme un sac de compression de voyage : tout petit à transporter, une fois sur place, il faut tout déplier. Le téléchargement est rapide, mais la VRAM n’est pas économisée pour autant.

Comparaison entre la taille sur le disque et l’explosion en VRAM

Que se passe‑t‑il quand la VRAM manque ?

Pas de jolie boîte de dialogue « Mémoire insuffisante ». C’est bien pire :

  • Sur mobile : écran blanc, ou le système tue carrément l’onglet.
  • Sur casque VR : perte d’images. Dans la VR, une perte d’images n’est pas « un peu lent », ça provoque des nausées.
  • Sur desktop : textures qui scintillent, dégradation, rendu ralenti.

Sur Reddit, un développeur a raconté son expérience avec une galerie WebXR : il chargeait 60 stéréogrammes sur un Quest. Au début, ça marchait, puis de plus en plus instable jusqu’au crash. Il a passé des jours à chercher dans son code, avant de réaliser qu’il n’avait jamais pensé à la VRAM – il envoyait sans cesse des JPG au GPU.

Les deux voies de la compression

La compression des modèles 3D se divise en deux grandes directions :

Compression de sommets – stocker les coordonnées des sommets, normales, UV, etc., de manière plus compacte. Par exemple, remplacer des flottants 32 bits par des entiers 16 bits (ce qu’on appelle la quantification). Solutions représentatives : Draco, MeshOpt, KHR_mesh_quantization.

Compression de textures – faire en sorte que les textures restent compressées dans la VRAM. Le GPU décode un pixel à la volée pendant l’échantillonnage, quasi sans surcoût. Solutions représentatives : KTX2 + Basis Universal.

Compression de sommetsCompression de textures
Ce qu’on réduitDonnées géométriquesTextures
Effet typiqueRéduction de 50 à 90 %Disque : −50 à 70 %, VRAM : −75 %
Avec perte ?Oui, perte de précisionOui, baisse de qualité visuelle
Cas d’usageModèles très denses en sommetsPresque tous les modèles PBR
À voir dansArticle 2Articles 3 et 4

Une erreur courante : compresser les sommets avec Draco et penser que tout va bien. Mais les textures représentent 80 % du volume du modèle ; diviser les sommets par deux ne fera perdre que 10 % du poids total. Il faut s’occuper des deux.

Il n’existe pas de méthode universelle

C’est le message central de toute cette série :

Pour chaque plateforme, chaque appareil, chaque usage, il faut une stratégie de compression différente.

ScénarioGoulot d’étranglement principalPriorité
Affichage Web sur desktopVitesse de téléchargementTaille du fichier
Navigateur mobileVRAMCompression de textures
Casque VRVRAM + framerateCompression de textures + simplification de sommets
Applications mobiles (contraintes de taille de paquet)Taille du paquet + compatibilitéSolution légère (MeshOpt)
Grande scèneVRAM + draw callsCompression complète + LOD

Dans les articles suivants, on ne se contentera pas de dire « Utilisez X, c’est la solution ». On expliquera : à quel scénario X convient‑il, quand peut‑il être contre‑productif, et dans quel cas il faut préférer Y.

Prochaine étape

Cet article a posé le problème. Le suivant passe à l’action – on fait connaissance avec les trois outils de compression de sommets : quantification, MeshOpt et Draco.

Nous soutenir