Dela via


Blockera komprimering

Från och med Windows 8.1 har Direct2D stöd för flera blockkomprimerade pixelformat. Dessutom innehåller Windows 8.1 en ny Windows Imaging Component (WIC) DDS codec för att aktivera inläsning och lagring av blockkomprimerade bilder i DDS-filformatet. Blockkomprimering är en teknik för att minska mängden grafikminne som används av bitmappsinnehåll. Genom att använda blockkomprimering kan din app minska minnesförbrukningen och inläsningstiderna för samma upplösningsbilder. Eller så kan din app använda fler eller högre upplösningsbilder samtidigt som samma GPU-minnesfotavtryck används.

Blockkomprimering har använts av Direct3D-program under en lång tid och med Windows 8.1 är även tillgängligt för vanliga programutvecklare och Direct2D-programutvecklare.

Det här avsnittet beskriver hur blockkomprimering fungerar och hur du använder den i WIC och Direct2D.

Om blockkomprimering

Block Compression (BC) refererar till en klass med komprimeringstekniker för att minska texturstorlekar. Direct3D 11 stöder upp till 7 olika BC-format beroende på funktionsnivå. I Windows 8.1 Direct2D introduceras stöd för BC1-, BC2- och BC3-format som är tillgängliga på alla funktionsnivåer.

Så här fungerar blockkomprimering

Blockkomprimerade format använder alla samma grundläggande teknik för att minska utrymmet som förbrukas av färgdata. Det här avsnittet sammanfattar den enklaste algoritmen BC1. En mer detaljerad förklaring finns i Blockera komprimering.

För det första är bilden uppdelad i block på 4 och 4 bildpunkter. Varje block komprimeras separat.

Not

Det innebär att en bilds bredd och höjd måste vara en multipel på 4 bildpunkter för att den ska blockeras.

 

Den här exempelbilden visar ett block på 4 x 4 bildpunkter i en bild.

en exempelbild visar ett block på 4 x 4 bildpunkter i en bild.

Inom ett 4 x 4-block väljs sedan två "referensfärger" och kodas som två 16-bitarsvärden (5 bitar rött, 6 bitar grönt, 5 bitar blått). Valet av dessa färger påverkar bildkvaliteten avsevärt och är icke-prövande. Två mellanliggande färger beräknas genom linjär interpolering mellan de två referensfärgerna i RGB-färgområdet. Detta ger totalt 4 olika möjliga färger; varje färg tilldelas ett två bitars indexvärde. Observera dock att endast de två slutpunktsfärgerna behöver lagras eftersom interpolationen är fast.

I den här bilden väljs färgerna 0 och 3 som "referensfärger" för blocket, medan färgerna 1 och 2 beräknas med linjär interpolation.

diagram som visar beräkningen av 4 färgvärden för att representera blocket.

Slutligen mappas varje pixel i blocket till en av de fyra tidigare beräknade färgerna, och varje pixel kodas med hjälp av två bitars indexvärde.

Den totala mängden data som används för att representera dessa 16 bildpunkter är:

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

Detta resulterar i en genomsnittlig densitet på 4 bitar per pixel. Som jämförelse förbrukar det vanliga DXGI_FORMAT_B8G8R8A8_UNORM pixelformatet 32 bitar per pixel.

Det här diagrammet visar att varje pixel kodas som ett 2-bitars index. Hela blocket kodas i 64 bitar.

att beräkna 4 färgvärden för att representera blocket.

Det finns varianter som stöder alfadata och olika antal färgkanaler. BC6H och BC7 använder betydligt olika algoritmer för att stödja hdr-innehåll (high dynamic range) respektive öka bildkvaliteten.

DirectDraw Surface -filformat (DDS)

Blockera komprimerade data lagras vanligtvis i DirectDraw Surface (DDS) filer. Du kanske är bekant med DDS-filer om du är Direct3D-utvecklare. Observera att Direct2D endast stöder vissa DDS-funktioner. Mer information finns i DDS-krav.

Fördelar med blockkomprimering

Blockera komprimerade format skiljer sig från vanliga branschbildkomprimeringsformat, till exempel JPEG, eftersom BC-format stöds internt av moderna GPU:er. Det innebär att du direkt kan läsa in en blockkomprimerad bild på GPU:n utan avkodning eller dekomprimering. BC-format förbrukar mellan 4 och 8 bitar per pixel i genomsnitt. jämfört med en typisk okomprimerad BGRA-bitmapp på 32 bitar per bildpunkt resulterar detta i minnesbesparingar på 75% till 87,5%. Eftersom det inte finns något avkodningssteg minskar också tiden för att läsa in en BC-bild avsevärt jämfört med format som JPEG.

När blockkomprimering ska användas

Du bör överväga att använda blockkomprimerade bilder i appen i stället för andra format som JPEG om du vill minska minnesförbrukningen för bitmappar eller vill minska avkodnings- och inläsningstiderna.

Blockkomprimering är dock inte lämpligt för alla fall och kräver vissa kompromisser. Först är blockkomprimeringsalgoritmerna förlustiga. Blockkomprimering fungerar bra med naturligt fotografisk innehåll men kan introducera oönskade visuella artefakter i bilder med skarpa, höga kontrastgränser, till exempel datorgenererade skärmbilder. Du bör se till att dina blockkomprimerade bildtillgångar har acceptabel bildkvalitet innan du använder dem.

För det andra förbrukar komprimerade DDS-filer i allmänhet mer utrymme på disken än jämförbara JPEG-bilder. Detta ökar i sin tur appens krav på paketstorlek och nätverksbandbredd.

Använda blockkomprimering

I det här avsnittet beskrivs hur du genererar och använder komprimerade tillgångar i en Direct2D-app.

Överblick

Blockera komprimerade DDS-filer är ett körningsoptimerad format, vilket innebär att de är särskilt optimerade för bra prestanda vid appkörning. Vi rekommenderar att du fortsätter att använda din befintliga pipeline för att skapa och redigera tillgångar och endast konvertera till ett blockkomprimerat format när du importerar dem till ditt programprojekt eller vid byggtiden.

DDS-krav

DDS-filformatet har utformats för att stödja en mängd olika funktioner som används i Direct3D. Direct2D använder bara en delmängd av dessa funktioner. När du skapar DDS-avbildningar för användning med Direct2D måste du därför tänka på följande begränsningar:

  • Endast följande DXGI_FORMAT värden tillåts:
    • DXGI_FORMAT_BC1_UNORM
    • DXGI_FORMAT_BC2_UNORM
    • DXGI_FORMAT_BC3_UNORM
  • Fördefinierade alfadata måste användas. Detta omfattar äldre DDS-filer med format som uttryckligen definierar förmultiplied alfa (DXT1, DXT2, DXT4), samt DDS-filer som använder DDS_HEADER_DX10 struktur med värdena DDS_ALPHA_MODE_OPAQUE och DDS_ALPHA_MODE_PREMULTIPLIED.
  • X- och Y-dimensionerna måste vara multiplar på 4 bildpunkter.
  • Volymstrukturer, kubkartor, mipmaps eller strukturmatriser tillåts inte. Du bör bara använda källbilder med en enda ram.

Generera blockkomprimerade tillgångar

Det finns en mängd olika DDS-redigeringsverktyg för att skapa eller konvertera blockkomprimerade DDS-filer. Observera att alla verktyg inte stöder kraven för att använda DDS-filer med Direct2D, enligt beskrivningen i föregående avsnitt.

Från och med Visual Studio 2013 kan du låta Visual Studio konvertera befintliga visuella tillgångar som JPEG och PNG till rätt DDS-block komprimerat format som en automatisk del av byggprocessen. Detta görs med hjälp av det anpassade byggsteget för bildinnehållsaktivitet.

Information om hur du konfigurerar det här för projektet finns i: How to: Export a Texture for Use with Direct2D or Javascipt Apps.

Direct2D-API:er

Direct2D uppdateras i Windows 8.1 för att stödja följande pixelformat:

  • DXGI_FORMAT_BC1_UNORM
  • DXGI_FORMAT_BC2_UNORM
  • DXGI_FORMAT_BC3_UNORM

För föregående format måste du använda förmultiplied alfa. Dessutom är dessa format endast giltiga för användning som källa, inte ett mål. Det innebär till exempel att du kan skapa en Direct2D-bitmapp med HJÄLP av BC1, men inte en enhetskontext.

Följande metoder uppdateras i Windows 8.1 för att stödja BC-format:

Observera att CreateBitmapFromWicBitmap tar IWICBitmapSource som ett gränssnitt. Men i Windows 8.1 har WIC inte stöd för att hämta blockkomprimerade data från IWICBitmapSource, och det finns inget WIC-pixelformat som motsvarar DXGI_FORMAT_BC1_UNORM osv. I stället avgör CreateBitmapFromWicBitmap om IWICBitmapSource är en giltig DDS-IWICBitmapFrameDecode och läser in blockkomprimerade data direkt. Du kan antingen uttryckligen ange pixelformatet i D2D1_BITMAP_PROPERTIES1 struct eller låta Direct2D automatiskt fastställa rätt format.

API:er för Windows Imaging-komponent

Windows Imaging Component (WIC) lägger till en ny DDS-codec i Windows 8.1. Dessutom lägger den till nya gränssnitt som stöder åtkomst till DDS-specifika data, inklusive blockkomprimerade pixeldata:

Blockera komprimerade WIC-pixelformat

Det finns inga nya WIC-block komprimerade pixelformat i Windows 8.1. Om du i stället skaffar en IWICBitmapFrameDecode- från DDS-avkodaren och anropar CopyPixelsfår du okomprimerade standardpixlar som WICPixelFormat32bppPBGRA. Du kan använda IWICDdsFrameDecode::CopyBlocks för att hämta komprimerade rådata i form av en minnesbuffert från en DDS-fil.

DDS-åtkomst med flera ramar

DDS-filformatet gör att flera relaterade bilder kan lagras i en enda fil. En DDS-fil kan till exempel innehålla en kubkarta, volymstruktur eller texturmatris, som alla kan vara mipmappade. I Direct3D exponeras dessa flera bilder som underresurser. I WIC exponeras flera bilder som ramar (IWICBitmapFrameDecode och IWICBitmapFrameEncode).

WIC stöder endast begreppet en endimensionell matris med bildrutor, medan DDS stöder tre oberoende dimensioner (även om endast två kan användas i en enda fil). WIC tillhandahåller praktiska metoder för att hjälpa till med mappning mellan en DDS-underresurs och en WIC-ram. För avkodning IWICDdsDecoder::GetFrame låter dig ange matrisindex, mip-nivå och segmentindex för underkällan och returnerar rätt WIC-ram.

För kodning beräknar IWICDdsEncoder::CreateNewFrame det resulterande matrisindexet, mip-nivån och segmentindexet när du skapar en ny ram. Du måste först ha anropat IWICDdsEncoder::SetParameters för att definiera de DDS-specifika filparametrarna.

Så här exporterar du en struktur för användning med Direct2D- eller Javascipt-appar

referens för DDS-

Blockera komprimering