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.

Environ 10 minutes5 démos interactives
Commencer la lecture

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.

À essayerCalculateur de mémoire graphiqueModifiez la résolution et le nombre de textures pour voir combien de mémoire GPU les mêmes textures nécessitent dans chaque format.
Résolution
  • RGBA8
    32 bits par texel
    213 MiB
    Référence
    21,3 MiB par texture
  • BC7 · ASTC 4×4
    8 bits par texel
    53,3 MiB
    4× plus petit
    5,3 MiB par texture
  • BC1 · ETC2 RGB
    4 bits par texel
    26,7 MiB
    8× plus petit
    2,7 MiB par texture
  • ASTC 6×6
    3,56 bits par texel
    23,8 MiB
    9× plus petit
    2,4 MiB par texture
  • ASTC 8×8
    2 bits par texel
    13,3 MiB
    16× plus petit
    1,3 MiB par texture
  • ASTC 12×12
    0,89 bits par texel
    6 MiB
    35,7× plus petit
    612 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.

À essayerTrouver un texelCliquez sur n'importe quel texel de cette texture 32×32. Un format par blocs peut calculer où il est stocké ; un PNG, non.

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

0511

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.

À essayerExplorateur de blocs BC1Choisissez un bloc 4×4 dans la texture d'exemple et voyez exactement comment BC1 le stocke.
Bloc 12, 4

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.

Formats de texture GPU courants
FormatBits par texelAlphaPlateformes courantesIdéal pour
BC141 bitDesktop, consolesCouleur opaque avec peu de mémoire
BC38OuiDesktop, consolesCouleur avec alpha doux dans du contenu ancien
BC44Canaux de donnéesDesktop, consolesUn canal : masques, rugosité, hauteur
BC58Canaux de donnéesDesktop, consolesNormal maps (X et Y)
BC6H8NonDesktop, consolesCouleur HDR comme les skyboxes et les lightmaps
BC78OuiDesktop, consolesCouleur de haute qualité, avec ou sans alpha
ETC14NonPresque tous les AndroidCouleur opaque sur des appareils très anciens
ETC24–8OuiAndroid, iOSSolution de repli mobile largement prise en charge
ASTC0.89–8OuiAndroid et iOS récents, Apple SiliconQualité réglable sur mobile
PVRTC2–4OuiAnciens iPhone et iPadAnciens appareils Apple uniquement
Basis ETC1SDépend de la cibleOuiTout GPU, via KTX2Petits téléchargements qui fonctionnent sur tout GPU
Basis UASTCDépend de la cibleOuiTout GPU, via KTX2Haute qualité qui fonctionne sur tout GPU
À essayerLancer les vrais encodeursCompressez l'exemple 512×512 avec les mêmes encodeurs WebAssembly que nos outils, puis comparez une zone agrandie.
S'exécute dans votre navigateur. Rien n'est envoyé.
Zone agrandie
Original
RGBA8
1 MiB en mémoire GPU
BC1
BC1
4 bits par texel
128 KiB en mémoire GPU
BC7
BC7
8 bits par texel
256 KiB en mémoire GPU
ASTC 6×6
ASTC 6×6
3,56 bits par texel
116 KiB en mémoire GPU
ASTC 12×12
ASTC 12×12
0,89 bits par texel
29 KiB en mémoire 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.

À essayerSélecteur de formatChoisissez où la texture s'exécute et ce qu'elle contient.
Où sera-t-elle utilisée ?
Que contient la texture ?

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 ASTC

Chapitre 6

Conseils pratiques

Quelques habitudes évitent la plupart des problèmes de compression de textures.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.