Compactação de bloco (Direct3D 10)
A compactação de bloco é uma técnica para reduzir o tamanho da textura. Quando comparada a uma textura com 32 bits por cor, uma textura compactada em bloco pode ser até 75% menor. O desempenho dos aplicativos geralmente melhora com o uso da compactação de bloco devido ao volume de memória mais baixo.
Embora haja perdas, a compactação de blocos funciona bem e é recomendada para todas as texturas que são transformadas e filtradas pelo pipeline. Texturas mapeadas diretamente para a tela (elementos da interface do usuário, como ícones e texto) não são boas opções para compactação porque os artefatos são mais perceptíveis.
Uma textura compactada em bloco deve ser criada como um múltiplo de tamanho 4 em todas as dimensões e não pode ser usada como uma saída do pipeline.
- Como funciona a compactação de bloco?
- Usar a compactação de bloco
- Algoritmos de compactação
- Conversão de formato usando o Direct3D 10.1
- Tópicos relacionados
Como funciona a compactação de bloco?
A compactação de bloco é uma técnica para reduzir a quantidade de memória necessária para armazenar dados de cores. Ao armazenar algumas cores em seu tamanho original e outras usando um esquema de codificação, você pode reduzir drasticamente a quantidade de memória necessária para armazenar a imagem. Como o hardware decodifica automaticamente os dados compactados, não há penalidade de desempenho para o uso de texturas compactadas.
Para saber como a compactação funciona, veja os dois exemplos a seguir. O primeiro exemplo descreve a quantidade de memória usada ao armazenar dados não compactados. O segundo exemplo descreve a quantidade de memória usada ao armazenar dados compactados.
Armazenar dados descompactados
A ilustração a seguir representa uma textura 4×4 não compactada. Suponha que cada cor tenha um único componente de cor (por exemplo, vermelho) e seja armazenada em um byte de memória.
Os dados descompactados são dispostos na memória sequencialmente e requerem 16 bytes, conforme mostrado na ilustração a seguir.
Armazenar dados compactados
Agora que você viu quanto de memória uma imagem não compactada usa, dê uma olhada em quanto de memória uma imagem compactada economiza. O formato de compactação BC4 armazena 2 cores (1 byte cada) e 16 índices de 3 bits (48 bits ou 6 bytes) que são usados para interpolar as cores originais na textura, conforme mostrado na ilustração a seguir.
O espaço total necessário para armazenar os dados compactados é de 8 bytes, o que representa uma economia de memória de 50% em relação ao exemplo não compactado. A economia é ainda maior quando mais de um componente de cor é usado.
A economia substancial de memória fornecida pela compactação de bloco pode melhorar o desempenho. Esse desempenho acaba sacrificando a qualidade da imagem (devido à interpolação de cores), mas a qualidade inferior geralmente não é perceptível.
A próxima seção mostra como o Direct3D 10 facilita o uso da compactação de bloco no seu aplicativo.
Usar a compactação de bloco
Criar uma textura compactada em bloco é como criar uma textura não compactada (consulte Criar uma textura a partir de um arquivo) só que especificando um formato compactado em bloco.
loadInfo.Format = DXGI_FORMAT_BC1_UNORM;
D3DX10CreateTextureFromFile(...);
Em seguida, crie uma exibição para associar a textura ao pipeline. Como uma textura compactada em bloco pode ser usada apenas como uma entrada para um estágio do sombreador, convém criar uma exibição de recurso de sombreador chamando CreateShaderResourceView.
Use uma textura compactada em bloco da mesma forma que usaria uma textura não compactada. Se o aplicativo obtiver um ponteiro de memória para bloquear dados compactados, você precisará considerar o preenchimento de memória em um mipmap que faz com que o tamanho declarado seja diferente do tamanho real.
Comparação do tamanho virtual com o tamanho físico
Se você tiver um código de aplicativo que usa um ponteiro de memória para percorrer a memória de uma textura compactada em bloco, saiba que talvez seja necessário fazer uma modificação no código do aplicativo. Uma textura compactada em bloco deve ser um múltiplo de 4 em todas as dimensões porque os algoritmos de compactação de bloco operam em blocos texel 4x4. Isso será um problema para um mipmap que tem as dimensões iniciais divisíveis por 4, mas os níveis subdivididos não. O diagrama a seguir mostra a diferença de área entre o tamanho virtual (declarado) e o tamanho físico (real) de cada nível de mipmap.
O lado esquerdo do diagrama mostra os tamanhos de nível de mipmap gerados para uma textura 60×40 não compactada. O tamanho do nível superior é obtido a partir da chamada de API que gera a textura, e cada nível subsequente tem metade do tamanho do nível anterior. Para uma textura não compactada, não há diferença entre o tamanho virtual (declarado) e o tamanho físico (real).
O lado direito do diagrama mostra os tamanhos de nível de mipmap gerados para a mesma textura 60×40 com compactação. Observe que o segundo e o terceiro níveis têm preenchimento de memória para transformar os fatores de tamanho de 4 em todos os níveis. Isso é necessário para que os algoritmos possam operar em blocos de texel 4×4. Isso é evidente principalmente se você considerar os níveis de mipmap menores que 4×4. O tamanho desses níveis de mipmap muito pequenos será arredondado para o fator mais próximo de 4 quando a memória de textura for alocada.
O hardware de amostragem usa o tamanho virtual. Quando há amostragem da textura, o preenchimento de memória é ignorado. Para níveis de mipmap menores que 4×4, somente os quatro primeiros texels serão usados para um mapa 2×2 e apenas o primeiro texel será usado por um bloco 1×1. No entanto, não há nenhuma estrutura de API que exponha o tamanho físico (incluindo o preenchimento de memória).
Resumindo, tenha cuidado ao usar blocos de memória alinhados ao copiar regiões que contêm dados compactados em bloco. Para fazer isso em um aplicativo que tem um ponteiro de memória, certifique-se de que o ponteiro usa o passo de superfície para considerar o tamanho da memória física.
Algoritmos de compactação
As técnicas de compactação de bloco no Direct3D dividem os dados de textura não compactados em blocos 4×4, compactam cada bloco e armazenam os dados. Por esse motivo, as texturas que devem ser compactadas precisam ter dimensões de textura que sejam múltiplos de 4.
O diagrama anterior mostra uma textura particionada em blocos de texel. O primeiro bloco mostra o layout dos 16 texels rotulados como "a-p", mas todos os blocos têm a mesma organização de dados.
O Direct3D implementa vários esquemas de compactação, cada um implementa uma compensação diferente entre o número de componentes armazenados, o número de bits por componente e a quantidade de memória consumida. Use esta tabela para ajudar a escolher o formato que funciona melhor com o tipo e a resolução de dados que melhor se adapta ao seu aplicativo.
Dados de origem | Resolução de compactação de dados (em bits) | Escolha este formato de compactação |
---|---|---|
Cor e alfa de três componentes | Cor (5:6:5), Alfa (1) ou sem alfa | BC1 |
Cor e alfa de três componentes | Cor (5:6:5), Alfa (4) | BC2 |
Cor e alfa de três componentes | Cor (5:6:5), Alfa (8) | BC3 |
Cor de um componente | Um componente (8) | BC4 |
Cor de dois componentes | Dois componentes (8:8) | BC5 |
BC1
Use o primeiro formato de compactação de bloco (BC1) (DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM ou DXGI_BC1_UNORM_SRGB) para armazenar dados de cores de três componentes usando uma cor 5:6:5 (vermelho de 5 bits, verde de 6 bits, azul de 5 bits). Isso é verdadeiro mesmo que os dados também contenham alfa de 1 bit. Assumindo uma textura 4×4 com o maior formato de dados possível, o formato BC1 reduz a memória necessária de 48 bytes (16 cores × 3 componentes/cor × 1 byte/componente) para 8 bytes de memória.
O algoritmo funciona em blocos 4×4 de texels. Em vez de armazenar 16 cores, o algoritmo salva 2 cores de referência (color_0 e color_1) e 16 índices de cores de 2 bits (blocos a–p), conforme mostrado no diagrama a seguir.
Os índices de cores (a–p) são usados para procurar as cores originais de uma tabela de cores. A tabela de cores contém 4 cores. As duas primeiras (0 color_0 e color_1) são as cores mínima e a máxima. As outras duas (color_2 e color_3) são cores intermediárias calculadas com interpolação linear.
color_2 = 2/3*color_0 + 1/3*color_1
color_3 = 1/3*color_0 + 2/3*color_1
As quatro cores recebem valores de índice de 2 bits que serão salvos nos blocos a–p.
color_0 = 00
color_1 = 01
color_2 = 10
color_3 = 11
Finalmente, cada uma das cores nos blocos a–p é comparada com as quatro da tabela de cores, e o índice para a cor mais próxima é armazenado nos blocos de 2 bits.
Esse algoritmo também é usado para dados que contêm alfa de 1 bit. A única diferença é que color_3 é definido como 0 (que representa uma cor transparente), e color_2 é uma mistura linear de color_0 e color_1.
color_2 = 1/2*color_0 + 1/2*color_1;
color_3 = 0;
Diferenças entre Direct3D 9 e Direct3D 10:
Esse formato existe no Direct3D 9 e 10.
- No Direct3D 9, o formato BC1 é chamado de D3DFMT_DXT1.
- No Direct3D 10, o formato BC1 é representado por DXGI_FORMAT_BC1_UNORM ou DXGI_FORMAT_BC1_UNORM_SRGB.
BC2
Use o formato BC2 (DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM ou DXGI_BC2_UNORM_SRGB) para armazenar dados de cor e alfa com baixa coerência (use BC3 para dados alfa altamente coerentes). O formato BC2 armazena dados RGB como uma cor 5:6:5 (vermelho de 5 bits, verde de 6 bits, azul de 5 bits) e alfa como um valor separado de 4 bits. Assumindo uma textura 4×4 usando o maior formato de dados possível, essa técnica de compactação reduz a memória necessária de 64 bytes (16 cores × 4 componentes/cor × 1 byte/componente) para 16 bytes de memória.
O formato BC2 armazena cores com o mesmo número de bits e layout de dados que o formato BC1, no entanto, o BC2 requer 64 bits adicionais de memória para armazenar os dados alfa, conforme mostrado no diagrama a seguir.
Diferenças entre Direct3D 9 e Direct3D 10:
Esse formato existe no Direct3D 9 e 10.
No Direct3D 9, o formato BC2 é chamado de D3DFMT_DXT2 e D3DFMT_DXT3.
No Direct3D 10, o formato BC2 é representado por DXGI_FORMAT_BC2_UNORM ou DXGI_FORMAT_BC2_UNORM_SRGB.
BC3
Use o formato BC3 (DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM ou DXGI_BC3_UNORM_SRGB) para armazenar dados de cores altamente coerentes (use BC2 com dados alfa menos coerentes). O formato BC3 armazena dados usando cores 5:6:5 (vermelho de 5 bits, verde de 6 bits, azul de 5 bits) e dados alfa usando um byte. Assumindo uma textura 4×4 usando o maior formato de dados possível, essa técnica de compactação reduz a memória necessária de 64 bytes (16 cores × 4 componentes/cor × 1 byte/componente) para 16 bytes de memória.
O formato BC3 armazena cores com o mesmo número de bits e layout de dados que o formato BC1. No entanto, o BC3 requer 64 bits adicionais de memória para armazenar os dados alfa. O formato BC3 lida com dados alfa armazenando dois valores de referência e interpolando entre eles (da mesma forma que BC1 armazena cores RGB).
O algoritmo funciona em blocos 4×4 de texels. Em vez de armazenar 16 valores alfa, o algoritmo armazena 2 alfas de referência (alpha_0 e alpha_1) e 16 índices de cores de 3 bits (alfa a-p), conforme mostrado no diagrama a seguir.
O formato BC3 usa os índices alfa (a–p) para pesquisar as cores originais de uma tabela de pesquisa que contém 8 valores. Os dois primeiros (alpha_0 e alpha_1) são os valores mínimo e máximo. Os outros seis valores intermediários são calculados por interpolação linear.
O algoritmo determina o número de valores alfa interpolados examinando os dois valores alfa de referência. Se alpha_0 for maior que alpha_1, BC3 interpola 6 valores alfa ou 4. Quando BC3 interpola apenas 4 valores alfa, ele define dois valores alfa adicionais (0 para totalmente transparente e 255 para totalmente opaco). O BC3 compacta os valores alfa na área de texel 4×4 armazenando o código de bits correspondente aos valores alfa interpolados que mais se aproximam do alfa original de um determinado texel.
if( alpha_0 > alpha_1 )
{
// 6 interpolated alpha values.
alpha_2 = 6/7*alpha_0 + 1/7*alpha_1; // bit code 010
alpha_3 = 5/7*alpha_0 + 2/7*alpha_1; // bit code 011
alpha_4 = 4/7*alpha_0 + 3/7*alpha_1; // bit code 100
alpha_5 = 3/7*alpha_0 + 4/7*alpha_1; // bit code 101
alpha_6 = 2/7*alpha_0 + 5/7*alpha_1; // bit code 110
alpha_7 = 1/7*alpha_0 + 6/7*alpha_1; // bit code 111
}
else
{
// 4 interpolated alpha values.
alpha_2 = 4/5*alpha_0 + 1/5*alpha_1; // bit code 010
alpha_3 = 3/5*alpha_0 + 2/5*alpha_1; // bit code 011
alpha_4 = 2/5*alpha_0 + 3/5*alpha_1; // bit code 100
alpha_5 = 1/5*alpha_0 + 4/5*alpha_1; // bit code 101
alpha_6 = 0; // bit code 110
alpha_7 = 255; // bit code 111
}
Diferenças entre Direct3D 9 e Direct3D 10:
No Direct3D 9, o formato BC3 é chamado de D3DFMT_DXT4 e D3DFMT_DXT5.
No Direct3D 10, o formato BC3 é representado por DXGI_FORMAT_BC3_UNORM ou DXGI_FORMAT_BC3_UNORM_SRGB.
BC4
Use o formato BC4 para armazenar dados de cores de um componente usando 8 bits para cada cor. Como resultado da maior precisão (em comparação com BC1), o BC4 é ideal para armazenar dados de ponto flutuante no intervalo de [0 a 1] usando o formato DXGI_FORMAT_BC4_UNORM e [-1 a +1] usando o formato DXGI_FORMAT_BC4_SNORM. Assumindo uma textura 4×4 usando o maior formato de dados possível, essa técnica de compactação reduz a memória necessária de 16 bytes (16 cores × 1 componente/cor × 1 byte/componente) para 8 bytes.
O algoritmo funciona em blocos 4×4 de texels. Em vez de armazenar 16 cores, o algoritmo armazena 2 cores de referência (red_0 e red_1) e 16 índices de cores de 3 bits (red_a a red_p), conforme mostrado no diagrama a seguir.
O algoritmo usa os índices de 3 bits para pesquisar cores de uma tabela que contém 8 cores. As duas primeiras (red_0 e red_1) são as cores mínima e máxima. O algoritmo calcula as cores restantes usando interpolação linear.
O algoritmo determina o número de valores de cores interpolados examinando os dois valores alfa de referência. Se red_0 for maior que red_1,o BC4 interpolará 6 valores de cor ou 4. Quando BC4 interpola apenas 4 valores de cor, ele define dois valores de cor adicionais (0,0f para totalmente transparente e 1,0f para totalmente opaco). O BC4 compacta os valores alfa na área de texel 4×4 armazenando o código de bits correspondente aos valores alfa interpolados que mais se aproximam do alfa original de um determinado texel.
BC4_UNORM
A interpolação dos dados de componente único é feita como no exemplo de código a seguir.
unsigned word red_0, red_1;
if( red_0 > red_1 )
{
// 6 interpolated color values
red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
// 4 interpolated color values
red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
red_6 = 0.0f; // bit code 110
red_7 = 1.0f; // bit code 111
}
As cores de referência são atribuídas a índices de 3 bits (000–111, pois há 8 valores), que serão salvos nos blocos red_a a red_p durante a compactação.
BC4_SNORM
O DXGI_FORMAT_BC4_SNORM é exatamente o mesmo, exceto pelos dados que são codificados no intervalo SNORM e quando 4 valores de cor são interpolados. A interpolação dos dados de componente único é feita como no exemplo de código a seguir.
signed word red_0, red_1;
if( red_0 > red_1 )
{
// 6 interpolated color values
red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
// 4 interpolated color values
red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
red_6 = -1.0f; // bit code 110
red_7 = 1.0f; // bit code 111
}
As cores de referência são atribuídas a índices de 3 bits (000–111, pois há 8 valores), que serão salvos nos blocos red_a a red_p durante a compactação.
BC5
Use o formato BC5 para armazenar dados de cores de dois componentes usando 8 bits para cada cor. Como resultado da maior precisão (em comparação com BC1), o BC5 é ideal para armazenar dados de ponto flutuante no intervalo de [0 a 1] usando o formato DXGI_FORMAT_BC5_UNORM e [-1 a +1] usando o formato DXGI_FORMAT_BC5_SNORM. Assumindo uma textura 4×4 usando o maior formato de dados possível, essa técnica de compactação reduz a memória necessária de 32 bytes (16 cores × 2 componentes/cor × 1 byte/componente) para 16 bytes.
O algoritmo funciona em blocos 4×4 de texels. Em vez de armazenar 16 cores para ambos os componentes, o algoritmo armazena 2 cores de referência para cada componente (red_0, red_1, green_0 e green_1) e 16 índices de cor de 3 bits para cada componente (red_a a red_p e green_a a green_p), conforme mostrado no diagrama a seguir.
O algoritmo usa os índices de 3 bits para pesquisar cores de uma tabela que contém 8 cores. As duas primeiras (red_0 e red_1 ou green_0 e green_1) são as cores mínima e máxima. O algoritmo calcula as cores restantes usando interpolação linear.
O algoritmo determina o número de valores de cores interpolados examinando os dois valores alfa de referência. Se red_0 for maior que red_1,o BC5 interpolará 6 valores de cor ou 4. Quando BC5 interpola apenas 4 valores de cor, ele define os dois valores restantes em 0,0f e 1,0f.
BC5_UNORM
A interpolação dos dados de componente único é feita como no exemplo de código a seguir. Os cálculos para os componentes verdes são semelhantes.
unsigned word red_0, red_1;
if( red_0 > red_1 )
{
// 6 interpolated color values
red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
// 4 interpolated color values
red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
red_6 = 0.0f; // bit code 110
red_7 = 1.0f; // bit code 111
}
As cores de referência são atribuídas a índices de 3 bits (000–111, pois há 8 valores), que serão salvos nos blocos red_a a red_p durante a compactação.
BC5_SNORM
O DXGI_FORMAT_BC5_SNORM é exatamente o mesmo, exceto pelos dados que são codificados no intervalo SNORM e quando 4 valores de dados são interpolados, os dois valores adicionais são -1,0f e 1,0f. A interpolação dos dados de componente único é feita como no exemplo de código a seguir. Os cálculos para os componentes verdes são semelhantes.
signed word red_0, red_1;
if( red_0 > red_1 )
{
// 6 interpolated color values
red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
// 4 interpolated color values
red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
red_6 = -1.0f; // bit code 110
red_7 = 1.0f; // bit code 111
}
As cores de referência são atribuídas a índices de 3 bits (000–111, pois há 8 valores), que serão salvos nos blocos red_a a red_p durante a compactação.
Conversão de formato usando o Direct3D 10.1
O Direct3D 10.1 permite cópias entre texturas de tipo pré-estruturado e texturas compactadas em bloco das mesmas larguras de bits. As funções que podem fazer isso são CopyResource e CopySubresourceRegion.
A partir do Direct3D 10.1, você pode usar CopyResource e CopySubresourceRegion para copiar entre alguns tipos de formato. Esse tipo de operação de cópia executa um tipo de conversão de formato que reinterpreta os dados do recurso como um tipo de formato diferente. Veja este exemplo que mostra a diferença de comportamento entre a reinterpretação dos dados e o uso de uma forma mais comum de conversão:
FLOAT32 f = 1.0f;
UINT32 u;
Para reinterpretar "f" como o tipo de "u", use memcpy:
memcpy( &u, &f, sizeof( f ) ); // ‘u’ becomes equal to 0x3F800000.
Na reinterpretação anterior, o valor subjacente dos dados não muda; e memcpy reinterpreta o float como um inteiro sem sinal.
Para executar o tipo mais comum de conversão, use a atribuição:
u = f; // ‘u’ becomes 1.
Na conversão anterior, o valor subjacente dos dados é alterado.
A tabela a seguir lista os formatos de origem e destino que você pode usar nesse tipo de reinterpretação de conversão de formato. Você deve codificar os valores corretamente para que a reinterpretação funcione conforme o esperado.
Largura do bit | Recurso descompactado | Recurso compactado em bloco |
---|---|---|
32 | DXGI_FORMAT_R32_UINT DXGI_FORMAT_R32_SINT |
DXGI_FORMAT_R9G9B9E5_SHAREDEXP |
64 | DXGI_FORMAT_R16G16B16A16_UINT DXGI_FORMAT_R16G16B16A16_SINT DXGI_FORMAT_R32G32_UINT DXGI_FORMAT_R32G32_SINT |
DXGI_FORMAT_BC1_UNORM[_SRGB] DXGI_FORMAT_BC4_UNORM DXGI_FORMAT_BC4_SNORM |
128 | DXGI_FORMAT_R32G32B32A32_UINT DXGI_FORMAT_R32G32B32A32_SINT |
DXGI_FORMAT_BC2_UNORM[_SRGB] DXGI_FORMAT_BC3_UNORM[_SRGB] DXGI_FORMAT_BC5_UNORM DXGI_FORMAT_BC5_SNORM |
Tópicos relacionados