Guia para iniciantes

O que acontece com uma textura dentro da GPU

Um PNG de 300 KB pode ocupar, sem você perceber, 5 MB de memória gráfica. Este guia mostra por quê, como as GPUs reduzem texturas com compressão em blocos e como escolher um formato. Cada ideia vem com algo que você pode testar.

Cerca de 10 minutos5 demonstrações interativas
Começar a ler

Capítulo 1

Tamanho do arquivo não é tamanho na memória

PNG e JPEG foram feitos para armazenar e enviar imagens. Antes de a GPU desenhar uma textura, a imagem é descompactada em texels brutos, normalmente com 4 bytes cada.

A GPU amostra esses texels milhões de vezes por quadro, então eles precisam estar prontos para leitura. Por isso, o uso de memória depende apenas da resolução e do formato de pixel, não de quão bem o arquivo foi comprimido. Os mipmaps, cópias reduzidas usadas em superfícies distantes, acrescentam cerca de um terço.

ExperimenteCalculadora de memória gráficaMude a resolução e o número de texturas para ver quanta memória de GPU as mesmas texturas precisam em cada formato.
Resolução
  • RGBA8
    32 bits por texel
    213 MiB
    Referência
    21,3 MiB por textura
  • BC7 · ASTC 4×4
    8 bits por texel
    53,3 MiB
    4× menor
    5,3 MiB por textura
  • BC1 · ETC2 RGB
    4 bits por texel
    26,7 MiB
    8× menor
    2,7 MiB por textura
  • ASTC 6×6
    3,56 bits por texel
    23,8 MiB
    9× menor
    2,4 MiB por textura
  • ASTC 8×8
    2 bits por texel
    13,3 MiB
    16× menor
    1,3 MiB por textura
  • ASTC 12×12
    0,89 bits por texel
    6 MiB
    35,7× menor
    612 KiB por textura

Os formatos em blocos são arredondados para blocos inteiros em cada nível de mip, então os números correspondem ao que a GPU aloca.

Capítulo 2

Por que a GPU não pode manter PNGs

Quando um shader amostra uma textura, ele pode pedir qualquer texel, em qualquer ordem. O hardware precisa encontrá-lo na hora.

PNG e JPEG usam codificação de comprimento variável: para chegar a um pixel no meio, é preciso decodificar tudo o que vem antes. Os formatos de GPU têm taxa fixa: cada bloco 4×4 usa exatamente o mesmo número de bytes, então o endereço de qualquer texel é uma simples multiplicação. A textura fica comprimida na memória e a unidade de textura decodifica os blocos enquanto os lê.

ExperimenteEncontre um texelClique em qualquer texel desta textura 32×32. Um formato em blocos consegue calcular onde ele está guardado; um PNG não.

Use as setas do teclado para mover a seleção.

Texel selecionado
x 13, y 18
Seu bloco
coluna 3, linha 4
Endereço no BC1
(4 × 8 + 3) × 8 bytes = byte 280

Os 64 blocos como ficam na memória

0511

O mesmo texel em um PNG

Primeiro é preciso descompactar as linhas 0 a 18 (19 de 32)

Capítulo 3

Dentro de um bloco 4×4

O BC1, o formato mais antigo de uso amplo, mostra a ideia com mais clareza. Ele guarda um bloco de 16 texels em apenas 8 bytes.

O codificador escolhe duas cores de extremidade. O decodificador as mistura em quatro cores sobre uma linha reta, e cada texel guarda um número de 2 bits que aponta para a mais próxima. Blocos com mudanças suaves de cor se mantêm bem; blocos que misturam várias cores sem relação, não.

ExperimenteExplorador de blocos BC1Escolha um bloco 4×4 na textura de exemplo e veja exatamente como o BC1 o armazena.
Bloco 12, 4

Capítulo 4

Muitos formatos, compromissos diferentes

Formatos mais novos usam seus bits com mais inteligência que o BC1: mais extremidades, várias linhas de cor dentro de um bloco, alfa melhor ou a escolha do tamanho do bloco.

BC7 e ASTC 4×4 usam 8 bits por texel e ficam muito próximos do original. O ASTC troca qualidade por tamanho por meio do tamanho do bloco: um bloco sempre tem 128 bits, então um bloco 12×12 custa menos de um bit por texel. O Basis Universal segue outro caminho: distribui um único arquivo compacto e o transcodifica no dispositivo para um formato que aquela GPU suporta.

Formatos comuns de textura de GPU
FormatoBits por texelAlfaPlataformas comunsIdeal para
BC141 bitDesktop, consolesCor opaca com pouca memória disponível
BC38SimDesktop, consolesCor com alfa suave em conteúdo antigo
BC44Canais de dadosDesktop, consolesUm canal: máscaras, rugosidade, altura
BC58Canais de dadosDesktop, consolesMapas de normais (X e Y)
BC6H8NãoDesktop, consolesCor HDR, como skyboxes e lightmaps
BC78SimDesktop, consolesCor de alta qualidade, com ou sem alfa
ETC14NãoQuase todos os AndroidCor opaca em dispositivos muito antigos
ETC24–8SimAndroid, iOSAlternativa mobile com amplo suporte
ASTC0.89–8SimAndroid e iOS recentes, Apple SiliconQualidade ajustável no mobile
PVRTC2–4SimiPhone e iPad antigosApenas dispositivos Apple antigos
Basis ETC1SDepende do destinoSimQualquer GPU, via KTX2Downloads pequenos que rodam em qualquer GPU
Basis UASTCDepende do destinoSimQualquer GPU, via KTX2Alta qualidade que roda em qualquer GPU
ExperimenteExecute os codificadores reaisComprima a amostra 512×512 com os mesmos codificadores WebAssembly usados pelas nossas ferramentas e compare uma área ampliada.
Roda no seu navegador. Nada é enviado.
Área ampliada
Original
RGBA8
1 MiB na memória da GPU
BC1
BC1
4 bits por texel
128 KiB na memória da GPU
BC7
BC7
8 bits por texel
256 KiB na memória da GPU
ASTC 6×6
ASTC 6×6
3,56 bits por texel
116 KiB na memória da GPU
ASTC 12×12
ASTC 12×12
0,89 bits por texel
29 KiB na memória da GPU

Clique em “Executar codificadores” para comprimir a amostra. Na primeira vez, os codificadores são baixados.

Capítulo 5

Como escolher um formato

Duas perguntas reduzem a escolha rapidamente: quais GPUs precisam carregar a textura e que tipo de dado ela contém?

Texturas de cor, mapas de normais e máscaras de um canal reagem de forma diferente à compressão, e as plataformas desktop, mobile e web suportam famílias de formatos diferentes. Escolha o seu caso para ter um bom ponto de partida e depois confira o resultado com suas próprias texturas.

ExperimenteSeletor de formatoEscolha onde a textura será usada e o que ela contém.
Onde vai rodar?
O que há na textura?

Comece com

ASTC 6×6

Considere também: ASTC 4×4 · ETC2 RGB

O ASTC funciona nas GPUs Android e iOS recentes. 6×6 é um bom equilíbrio; use 4×4 para os recursos principais e ETC2 para aparelhos antigos.

Abrir o codificador ASTC

Capítulo 6

Dicas práticas

Alguns hábitos evitam a maioria dos problemas de compressão de texturas.

  1. 01

    Marque cor como sRGB e dados como lineares

    Texturas de albedo e de UI são sRGB. Mapas de normais, rugosidade e outros dados devem continuar lineares, ou a iluminação ficará errada.

  2. 02

    Dê aos mapas de normais um formato próprio

    Use formatos de dois canais, como BC5 ou EAC RG11, e reconstrua Z no shader. Formatos de cor desperdiçam bits e criam relevos visíveis.

  3. 03

    Gere mipmaps

    Eles acrescentam cerca de 33% de memória, mas impedem o tremido em superfícies distantes e deixam a amostragem mais rápida.

  4. 04

    Use dimensões compatíveis com os blocos

    A maioria dos formatos trabalha com blocos 4×4, então tamanhos divisíveis por 4 evitam preenchimento. Formatos antigos como o PVRTC também exigem tamanhos quadrados em potência de dois.

  5. 05

    Confira conteúdo real em aparelhos reais

    Compare o resultado decodificado com o original em tamanho real e confirme que suas GPUs de destino suportam o formato.

Perguntas frequentes

A compressão de texturas de GPU é sem perdas?

Não. BC, ETC, ASTC e PVRTC são formatos com perdas e tamanho fixo por bloco. Quanto de qualidade se perde depende do formato, do tamanho do bloco e da imagem.

Por que não usar texturas PNG ou JPEG diretamente?

Elas baixam mais rápido, mas a GPU não consegue amostrá-las, então são decodificadas em texels brutos e ocupam a memória inteira. Os formatos de GPU continuam pequenos também na memória.

Qual é o melhor formato de textura?

O BC7 é um ótimo padrão no desktop, o ASTC em aparelhos móveis recentes e o KTX2 com Basis Universal quando um único arquivo precisa funcionar em várias GPUs, como na web.

O que significa bits por texel?

É o custo médio de armazenamento de um texel. O RGBA8 bruto usa 32 bits, o BC1 usa 4, o BC7 usa 8 e o ASTC vai de 8 até cerca de 0,89, conforme o tamanho do bloco.

Teste com suas próprias texturas

Todos os codificadores rodam localmente no seu navegador. Envie um PNG ou JPEG, escolha um formato e compare o resultado.