Guide pour débutants
Ce qui arrive à une texture dans le GPU
Un PNG de 300 Ko peut discrètement occuper 5 Mo de mémoire graphique. Ce guide explique pourquoi, comment les GPU réduisent les textures grâce à la compression par blocs et comment choisir un format. Chaque idée s'accompagne d'une démo à essayer.
Chapitre 1
La taille du fichier n'est pas la taille en mémoire
PNG et JPEG servent à stocker et à transmettre des images. Avant que le GPU puisse afficher une texture, l'image est décompressée en texels bruts, généralement 4 octets chacun.
Le GPU échantillonne ces texels des millions de fois par image : ils doivent donc être prêts à être lus. L'occupation mémoire dépend uniquement de la résolution et du format de pixel, pas de la qualité de compression du fichier. Les mipmaps, ces copies réduites utilisées pour les surfaces lointaines, ajoutent environ un tiers.
- RGBA832 bits par texel213 MiBRéférence21,3 MiB par texture
- BC7 · ASTC 4×48 bits par texel53,3 MiB4× plus petit5,3 MiB par texture
- BC1 · ETC2 RGB4 bits par texel26,7 MiB8× plus petit2,7 MiB par texture
- ASTC 6×63,56 bits par texel23,8 MiB9× plus petit2,4 MiB par texture
- ASTC 8×82 bits par texel13,3 MiB16× plus petit1,3 MiB par texture
- ASTC 12×120,89 bits par texel6 MiB35,7× plus petit612 KiB par texture
Les formats par blocs sont arrondis à des blocs entiers à chaque niveau de mip : les valeurs correspondent à ce que le GPU alloue réellement.
Chapitre 2
Pourquoi le GPU ne peut pas garder des PNG
Quand un shader échantillonne une texture, il peut demander n'importe quel texel, dans n'importe quel ordre. Le matériel doit le trouver immédiatement.
PNG et JPEG utilisent un codage à longueur variable : pour atteindre un pixel au milieu, il faut d'abord tout décoder avant lui. Les formats GPU ont un débit fixe : chaque bloc 4×4 occupe exactement le même nombre d'octets, si bien que l'adresse de n'importe quel texel s'obtient par une simple multiplication. La texture reste compressée en mémoire et l'unité de texture décode les blocs à la lecture.
Utilisez les flèches du clavier pour déplacer la sélection.
- Texel sélectionné
- x 13, y 18
- Son bloc
- colonne 3, ligne 4
- Adresse en BC1
- (4 × 8 + 3) × 8 octets = octet 280
Les 64 blocs tels qu'ils sont en mémoire
Le même texel dans un PNG
Décompresser d'abord les lignes 0 à 18 (19 sur 32)
Chapitre 3
À l'intérieur d'un bloc 4×4
BC1, le plus ancien format largement utilisé, montre le principe le plus clairement. Il stocke un bloc de 16 texels dans seulement 8 octets.
L'encodeur choisit deux couleurs d'extrémité. Le décodeur les mélange pour obtenir quatre couleurs sur une ligne droite, et chaque texel conserve un numéro de 2 bits qui désigne la plus proche. Les blocs aux variations de couleur douces s'en sortent bien ; ceux qui mélangent plusieurs couleurs sans rapport, non.
Chapitre 4
Beaucoup de formats, des compromis différents
Les formats récents exploitent mieux leurs bits que BC1 : davantage d'extrémités, plusieurs lignes de couleur dans un bloc, un meilleur alpha ou le choix de la taille de bloc.
BC7 et ASTC 4×4 utilisent 8 bits par texel et restent très proches de l'original. ASTC échange qualité contre taille grâce à la taille de bloc : un bloc fait toujours 128 bits, donc un bloc 12×12 coûte moins d'un bit par texel. Basis Universal suit une autre voie : il distribue un seul fichier compact et le transcode sur l'appareil vers un format pris en charge par ce GPU.
| Format | Bits par texel | Alpha | Plateformes courantes | Idéal pour |
|---|---|---|---|---|
| BC1 | 4 | 1 bit | Desktop, consoles | Couleur opaque avec peu de mémoire |
| BC3 | 8 | Oui | Desktop, consoles | Couleur avec alpha doux dans du contenu ancien |
| BC4 | 4 | Canaux de données | Desktop, consoles | Un canal : masques, rugosité, hauteur |
| BC5 | 8 | Canaux de données | Desktop, consoles | Normal maps (X et Y) |
| BC6H | 8 | Non | Desktop, consoles | Couleur HDR comme les skyboxes et les lightmaps |
| BC7 | 8 | Oui | Desktop, consoles | Couleur de haute qualité, avec ou sans alpha |
| ETC1 | 4 | Non | Presque tous les Android | Couleur opaque sur des appareils très anciens |
| ETC2 | 4–8 | Oui | Android, iOS | Solution de repli mobile largement prise en charge |
| ASTC | 0.89–8 | Oui | Android et iOS récents, Apple Silicon | Qualité réglable sur mobile |
| PVRTC | 2–4 | Oui | Anciens iPhone et iPad | Anciens appareils Apple uniquement |
| Basis ETC1S | Dépend de la cible | Oui | Tout GPU, via KTX2 | Petits téléchargements qui fonctionnent sur tout GPU |
| Basis UASTC | Dépend de la cible | Oui | Tout GPU, via KTX2 | Haute qualité qui fonctionne sur tout GPU |
Cliquez sur « Lancer les encodeurs » pour compresser l'exemple. Le premier lancement télécharge les encodeurs.
Chapitre 5
Choisir un format
Deux questions réduisent vite le choix : quels GPU doivent charger la texture, et quel type de données contient-elle ?
Les textures de couleur, les normal maps et les masques à un canal réagissent différemment à la compression, et les plateformes desktop, mobile et web prennent en charge des familles de formats différentes. Choisissez votre cas pour obtenir un bon point de départ, puis vérifiez le résultat sur vos propres textures.
Commencez par
ASTC 6×6
À envisager aussi: ASTC 4×4 · ETC2 RGB
ASTC fonctionne sur les GPU Android et iOS récents. 6×6 offre un bon équilibre ; utilisez 4×4 pour les ressources clés et ETC2 pour les anciens appareils.
Ouvrir l'encodeur ASTCChapitre 6
Conseils pratiques
Quelques habitudes évitent la plupart des problèmes de compression de textures.
- 01
Couleur en sRGB, données en linéaire
Les textures d'albédo et d'UI sont en sRGB. Les maps de normales, de rugosité et autres données doivent rester linéaires, sinon l'éclairage sera faux.
- 02
Un format dédié pour les normal maps
Utilisez des formats à deux canaux comme BC5 ou EAC RG11 et reconstruisez Z dans le shader. Les formats de couleur gaspillent des bits et ajoutent des bosses visibles.
- 03
Générez des mipmaps
Elles ajoutent environ 33 % de mémoire, mais évitent le scintillement des surfaces lointaines et accélèrent l'échantillonnage.
- 04
Des dimensions adaptées aux blocs
La plupart des formats travaillent en blocs 4×4 : des tailles divisibles par 4 évitent le remplissage. Les formats anciens comme PVRTC exigent aussi des tailles carrées en puissance de deux.
- 05
Vérifiez du contenu réel sur de vrais appareils
Comparez le résultat décodé à l'original en taille réelle et vérifiez que vos GPU cibles prennent en charge le format.
Questions fréquentes
La compression de textures GPU est-elle sans perte ?
Non. BC, ETC, ASTC et PVRTC sont des formats avec pertes et une taille fixe par bloc. La perte de qualité dépend du format, de la taille de bloc et de l'image.
Pourquoi ne pas utiliser directement des textures PNG ou JPEG ?
Elles se téléchargent plus vite, mais le GPU ne peut pas les échantillonner : elles sont donc décodées en texels bruts et occupent toute la mémoire. Les formats GPU restent compacts en mémoire aussi.
Quel est le meilleur format de texture ?
BC7 est un bon choix par défaut sur desktop, ASTC sur les appareils mobiles récents, et KTX2 avec Basis Universal quand un même fichier doit fonctionner sur de nombreux GPU, comme sur le web.
Que signifie bits par texel ?
C'est le coût de stockage moyen d'un texel. Le RGBA8 brut utilise 32 bits, BC1 4, BC7 8, et ASTC va de 8 à environ 0,89 selon la taille de bloc.
Essayez avec vos propres textures
Tous les encodeurs s'exécutent localement dans votre navigateur. Importez un PNG ou un JPEG, choisissez un format et comparez le résultat.