Compactação de bloco

Começando com Windows 8.1, Direct2D dá suporte a vários formatos de pixel compactados em bloco. Além disso, Windows 8.1 contém um novo codec DDS do WIC (Windows Imaging Component) para habilitar o carregamento e o armazenamento de imagens compactadas em bloco no formato de arquivo DDS. A compactação de blocos é uma técnica para reduzir a quantidade de memória gráfica consumida pelo conteúdo de bitmap. Usando compactação de bloco, seu aplicativo pode reduzir o consumo de memória e os tempos de carregamento para as mesmas imagens de resolução. Ou, seu aplicativo pode usar mais ou mais imagens de resolução enquanto ainda consome o mesmo volume de memória de GPU.

A compactação de blocos tem sido usada por aplicativos Direct3D há muito tempo e com Windows 8.1 também está disponível para desenvolvedores de aplicativos base e Direct2D.

Este tópico descreve como funciona a compactação de blocos e como usá-la no WIC e no Direct2D.

Sobre compactação de bloco

Bc (Compactação de Bloco ) refere-se a uma classe de técnicas de compactação para reduzir tamanhos de textura. O Direct3D 11 dá suporte a até 7 formatos BC diferentes, dependendo do nível do recurso. Em Windows 8.1 Direct2D apresenta suporte para os formatos BC1, BC2 e BC3 que estão disponíveis em todos os níveis de recursos.

Como funciona a Compactação de Blocos

Todos os formatos compactados em bloco usam a mesma técnica básica para reduzir o espaço consumido pelos dados de cores. Esta seção resume o algoritmo mais simples, BC1. Para obter uma explicação mais detalhada, consulte Compactação de blocos.

Primeiro, a imagem é dividida em blocos de 4 por 4 pixels. Cada bloco é compactado separadamente.

Observação

Isso significa que a largura e a altura de uma imagem devem ser um múltiplo de 4 pixels para que ela seja compactada em bloco.

 

Esta imagem de exemplo mostra um bloco de 4x4 pixels dentro de uma imagem.

uma imagem de exemplo mostra um bloco de 4x4 pixels dentro de uma imagem.

Em seguida, dentro de um bloco de 4 por 4, duas cores de "referência" são selecionadas e codificadas como dois valores de 16 bits (5 bits vermelho, 6 bits verde, 5 bits azul). A escolha dessas cores afeta significativamente a qualidade da imagem e não étrivial. Duas cores intermediárias são calculadas pela interpolação linear entre as duas cores de referência no espaço de cores RGB. Isso produz um total de quatro cores possíveis diferentes; cada cor recebe um valor de índice de dois bits. No entanto, observe que apenas as duas cores de ponto de extremidade precisam ser armazenadas à medida que a interpolação é fixa.

Nessa figura, as cores 0 e 3 são selecionadas como cores de "referência" para o bloco, enquanto as cores 1 e 2 são calculadas usando interpolação linear.

Diagrama que mostra o cálculo de quatro valores de cor para representar o bloco.

Por fim, cada pixel no bloco é mapeado para uma das quatro cores calculadas anteriormente e cada pixel é codificado usando o valor de índice de dois bits.

A quantidade total de dados usados para representar esses 16 pixels é:

16 bits [to define a reference color] * 2 + 2 bits * 16 [number of pixels] = 64 bits

Isso resulta em uma densidade média de 4 bits por pixel. Para comparação, o formato de pixel DXGI_FORMAT_B8G8R8A8_UNORM comum consome 32 bits por pixel.

Este diagrama mostra que cada pixel é codificado como um índice de 2 bits. O bloco inteiro é codificado em 64 bits.

calculando quatro valores de cor para representar o bloco.

Há variações para dar suporte a dados alfa e números variados de canais de cores. BC6H e BC7 usam algoritmos significativamente diferentes para dar suporte ao conteúdo hdr (alto alcance dinâmico) e aumentar a qualidade da imagem, respectivamente.

Formato de arquivo do DirectDraw Surface (DDS)

Os dados compactados de bloco normalmente são armazenados em arquivos DDS (DirectDraw Surface ). Talvez você esteja familiarizado com arquivos DDS se for um desenvolvedor do Direct3D. Observe que Direct2D dá suporte apenas a determinados recursos de DDS; para obter mais informações, consulte Requisitos de DDS.

Vantagens da compactação de bloco

Os formatos compactados em bloco diferem dos formatos comuns de compactação de imagem do setor, como JPEG, em que os formatos BC têm suporte nativo de GPUs modernas. Isso significa que você pode carregar diretamente uma imagem compactada de bloco na GPU sem nenhuma decodificação ou descompactação. Os formatos BC consomem de 4 a 8 bits por pixel em média; quando comparado a um bitmap BGRA típico de 32 bits por pixel, isso resulta em uma economia de memória de 75% a 87,5%. Além disso, como não há nenhuma etapa de decodificação, o tempo para carregar uma imagem BC é significativamente reduzido em comparação com formatos como JPEG.

Quando usar compactação de bloco

Você deve considerar o uso de imagens compactadas em bloco em seu aplicativo em vez de outros formatos, como JPEG, se quiser reduzir o consumo de memória de bitmaps ou quiser reduzir os tempos de decodificação e carregamento.

No entanto, a compactação de blocos não é apropriada para todos os casos e requer algumas compensações. Primeiro, os algoritmos de compactação de bloco são perdidos. A compactação de bloco funciona bem com conteúdo fotográfico natural, mas pode introduzir artefatos visuais indesejados em imagens com limites de alto contraste nítidos, como capturas de tela geradas por computador. Você deve garantir que os ativos de imagem compactadas em bloco tenham uma qualidade de imagem aceitável antes de usá-los.

Em segundo lugar, bloquear arquivos DDS compactados geralmente consomem mais espaço em disco do que imagens JPEG comparáveis. Isso, por sua vez, aumentará o tamanho do pacote do aplicativo e os requisitos de largura de banda de rede.

Usando compactação de bloco

Esta seção explica como gerar e usar ativos compactados em blocos em um aplicativo Direct2D.

Visão geral

Bloquear arquivos DDS compactados é um formato otimizado para runtime, o que significa que eles são especificamente otimizados para um bom desempenho no runtime do aplicativo. Recomendamos que você continue a usar o pipeline de criação e edição de ativos existentes e converta-o apenas em um formato compactado em bloco ao importá-los para seu projeto de aplicativo ou no momento da compilação.

Requisitos de DDS

O formato de arquivo DDS foi projetado para dar suporte a uma ampla variedade de recursos usados no Direct3D. Direct2D usa apenas um subconjunto desses recursos. Portanto, ao criar imagens DDS para uso com Direct2D, você deve ter em mente as seguintes restrições:

  • Somente os seguintes valores de DXGI_FORMAT são permitidos:
    • DXGI_FORMAT_BC1_UNORM
    • DXGI_FORMAT_BC2_UNORM
    • DXGI_FORMAT_BC3_UNORM
  • Dados alfa pré-multiplicados devem ser usados. Isso inclui arquivos DDS herdados usando formatos que definem explicitamente alfa pré-multiplicado (DXT1, DXT2, DXT4), bem como arquivos DDS que usam a estrutura DDS_HEADER_DX10 com os valores DDS_ALPHA_MODE_OPAQUE e DDS_ALPHA_MODE_PREMULTIPLIED.
  • As dimensões X e Y devem ter múltiplos de 4 pixels.
  • Texturas de volume, cubemaps, mipmaps ou matrizes de textura não são permitidas. Você deve usar apenas imagens de origem de quadro único.

Gerando ativos compactados em bloco

Há uma variedade de ferramentas de criação de DDS disponíveis para criar ou converter arquivos DDS compactados em bloco. Observe que nem todas as ferramentas dão suporte aos requisitos para usar arquivos DDS com Direct2D, conforme detalhado na seção anterior.

Começando com Visual Studio 2013, você pode fazer com que o Visual Studio converta ativos visuais existentes, como JPEG e PNG, no formato compactado correto do bloco DDS como parte automática do processo de build. Isso é feito usando a etapa de build personalizada da Tarefa de Conteúdo da Imagem.

Para obter informações sobre como configurar isso para seu projeto, consulte: Como exportar uma textura para uso com aplicativos Direct2D ou Javascipt.

APIs Direct2D

Direct2D é atualizado em Windows 8.1 para dar suporte aos seguintes formatos de pixel:

  • DXGI_FORMAT_BC1_UNORM
  • DXGI_FORMAT_BC2_UNORM
  • DXGI_FORMAT_BC3_UNORM

Para os formatos anteriores, você deve usar alfa pré-multiplicado. Além disso, esses formatos são válidos apenas para uso como uma origem, não como um destino. Por exemplo, isso significa que você pode criar um bitmap Direct2D usando BC1, mas não um contexto de dispositivo.

Os seguintes métodos são atualizados em Windows 8.1 para dar suporte a formatos BC:

Observe que CreateBitmapFromWicBitmap usa IWICBitmapSource como uma interface; no entanto, em Windows 8.1 WIC não dá suporte à obtenção de dados compactados em bloco de IWICBitmapSource e não há nenhum formato de pixel WIC correspondente a DXGI_FORMAT_BC1_UNORM etc. Em vez disso, CreateBitmapFromWicBitmap determina se iWICBitmapSource é um DDS IWICBitmapFrameDecode válido e carrega diretamente os dados compactados do bloco. Você pode especificar explicitamente o formato de pixel no struct D2D1_BITMAP_PROPERTIES1 ou permitir que Direct2D determinem automaticamente o formato correto.

APIs de componente de imagem do Windows

O WIC (Componente de Imagem do Windows) adiciona um novo codec DDS em Windows 8.1. Além disso, ele adiciona novas interfaces que dão suporte ao acesso a dados específicos do DDS, incluindo dados de pixel compactados em bloco:

Bloquear formatos de pixel WIC compactados

Não há novos formatos de pixel compactados de bloco WIC em Windows 8.1. Em vez disso, se você obtiver um IWICBitmapFrameDecode do decodificador DDS e chamar CopyPixels, receberá pixels padrão não compactados, como WICPixelFormat32bppPBGRA. Você pode usar IWICDdsFrameDecode::CopyBlocks para obter os dados compactados de bloco bruto na forma de um buffer de memória de um arquivo DDS.

Acesso ao DDS de vários quadros

O formato de arquivo DDS permite que várias imagens relacionadas sejam armazenadas em um único arquivo. Por exemplo, um arquivo DDS pode conter um cubemap, textura de volume ou matriz de textura, que pode ser mipmapped. No Direct3D, essas várias imagens são expostas como sub-recursos. No WIC, várias imagens são expostas como quadros (IWICBitmapFrameDecode e IWICBitmapFrameEncode).

O WIC só dá suporte à noção de uma única matriz dimensional de quadros, enquanto o DDS dá suporte a três dimensões independentes (embora apenas duas possam ser usadas em qualquer arquivo). O WIC fornece métodos de conveniência para ajudar no mapeamento entre um sub-recurso DDS e um quadro WIC. Para decodificação, IWICDdsDecoder::GetFrame permite especificar o índice da matriz, o nível de mip e o índice de fatia do sub-recurso e retorna o quadro WIC correto.

Para codificação, IWICDdsEncoder::CreateNewFrame calcula o índice de matriz resultante, o nível de mip e o índice de fatia ao criar um novo quadro. Primeiro, você deve ter chamado IWICDdsEncoder::SetParameters para definir os parâmetros de arquivo específicos do DDS.

Como exportar uma textura para uso com aplicativos Direct2D ou Javascipt

Referência para DDS

Compactação de blocos