Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
BC6H-formatet är ett texturkomprimeringsformat som har utformats för att stödja hdr-färgrymder (high-dynamic range) i källdata.
- Om BC6H/DXGI_FORMAT_BC6H
- BC6H-implementering
- avkoda BC6H-format
- BC6H-komprimerat slutpunktsformat
- Sign Extension for Endpoint Values
- Transformera inversion för slutpunktsvärden
- Icke-kvantisering av färgslutpunkter
- Relaterade ämnen
Om BC6H/DXGI_FORMAT_BC6H
BC6H-formatet ger högkvalitativ komprimering för bilder som använder tre HDR-färgkanaler, med ett 16-bitars värde för varje färgkanal för värdet (16:16:16). Det finns inget stöd för en alfakanal.
BC6H anges av följande DXGI_FORMAT uppräkningsvärden:
- DXGI_FORMAT_BC6H_TYPELESS.
- DXGI_FORMAT_BC6H_UF16. Det här BC6H-formatet använder inte en teckenbit i 16-bitars flyttalsfärgkanalvärdena.
- DXGI_FORMAT_BC6H_SF16. Det här BC6H-formatet använder en teckenbit i 16-bitars flyttalsfärgkanalens värden.
Not
16-bitars flyttalsformatet för färgkanaler kallas ofta för ett "halvt" flyttalformat. Det här formatet har följande bitlayout:
| Format | Bitlayout |
|---|---|
| UF16 (osignerad flyttal) | 5 exponentbitar + 11 mantissabitar |
| SF16 (signerad flyttal) | 1 tecken bit + 5 exponent bitar + 10 mantissa bitar |
BC6H-formatet kan användas för Texture2D- (inklusive matriser), Texture3D- eller TextureCube-strukturresurser (inklusive matriser). På samma sätt gäller det här formatet för alla MIP-kartytor som är associerade med dessa resurser.
BC6H använder en fast blockstorlek på 16 byte (128 bitar) och en fast panelstorlek på 4x4 texels. Precis som med tidigare BC-format komprimeras strukturbilder som är större än den panelstorlek som stöds (4x4) med hjälp av flera block. Den här adresseringsidentiteten gäller även för tredimensionella bilder, MIP-kartor, kubkartor och strukturmatriser. Alla bildpaneler måste ha samma format.
Några viktiga kommentarer om BC6H-formatet:
- BC6H stöder avnormalisering av flyttalser, men stöder inte INF (oändlighet) och NaN (inte ett tal). Undantaget är det signerade läget BC6H (DXGI_FORMAT_BC6H_SF16), som stöder -INF (negativ oändlighet). Observera att det här stödet för -INF bara är en artefakt av själva formatet och inte stöds specifikt av kodare för det här formatet. När kodare stöter på INF (positiva eller negativa) eller NaN-indata bör de i allmänhet \ konvertera dessa data till det högsta tillåtna icke-INF-representationsvärdet och mappa NaN till 0 före komprimering.
- BC6H stöder inte en alfakanal.
- BC6H-avkodaren utför dekomprimering innan den utför texturfiltrering.
- BC6H-dekomprimering måste vara bit exakt; Maskinvaran måste alltså returnera resultat som är identiska med dekodaren som beskrivs i den här dokumentationen.
BC6H-implementering
Ett BC6H-block består av lägesbitar, komprimerade slutpunkter, komprimerade index och ett valfritt partitionsindex. Det här formatet anger 14 olika lägen.
En slutpunktsfärg lagras som en RGB-trilling. BC6H definierar en palett med färger på en ungefärlig linje över ett antal definierade färgslutpunkter. Beroende på läget kan en panel delas in i två regioner eller behandlas som en enda region, där en panel med två regioner har en separat uppsättning färgslutpunkter för varje region. BC6H lagrar ett palettindex per texel.
I fallet med två regioner finns det 32 möjliga partitioner.
Avkodning av BC6H-format
Pseudokoden nedan visar stegen för att dekomprimera pixeln på (x,y) med tanke på 16 byte BC6H-blocket.
decompress_bc6h(x, y, block)
{
mode = extract_mode(block);
endpoints;
index;
if(mode.type == ONE)
{
endpoints = extract_compressed_endpoints(mode, block);
index = extract_index_ONE(x, y, block);
}
else //mode.type == TWO
{
partition = extract_partition(block);
region = get_region(partition, x, y);
endpoints = extract_compressed_endpoints(mode, region, block);
index = extract_index_TWO(x, y, partition, block);
}
unquantize(endpoints);
color = interpolate(index, endpoints);
finish_unquantize(color);
}
Följande tabell innehåller bitantal och värden för vart och ett av de 14 möjliga formaten för BC6H-block.
| Läge | Partitionsindex | Skifte | Färgslutpunkter | Lägesbitar |
|---|---|---|---|---|
| 1 | 46 bitar | 5 bitar | 75 bitar (10,555, 10,555, 10,555) | 2 bitar (00) |
| 2 | 46 bitar | 5 bitar | 75 bitar (7666, 7666, 7666) | 2 bitar (01) |
| 3 | 46 bitar | 5 bitar | 72 bitar (11,555, 11,444, 11,444) | 5 bitar (00010) |
| 4 | 46 bitar | 5 bitar | 72 bitar (11,444, 11,555, 11,444) | 5 bitar (00110) |
| 5 | 46 bitar | 5 bitar | 72 bitar (11,444, 11,444, 11,555) | 5 bitar (01010) |
| 6 | 46 bitar | 5 bitar | 72 bitar (9555, 9555, 9555) | 5 bitar (01110) |
| 7 | 46 bitar | 5 bitar | 72 bitar (8666, 8555, 8555) | 5 bitar (10010) |
| 8 | 46 bitar | 5 bitar | 72 bitar (8555, 8666, 8555) | 5 bitar (10110) |
| 9 | 46 bitar | 5 bitar | 72 bitar (8555, 8555, 8666) | 5 bitar (11010) |
| 10 | 46 bitar | 5 bitar | 72 bitar (6666, 6666, 6666) | 5 bitar (11110) |
| 11 | 63 bitar | 0 bitar | 60 bitar (10,10, 10,10, 10,10) | 5 bitar (00011) |
| 12 | 63 bitar | 0 bitar | 60 bitar (11,9, 11,9, 11,9) | 5 bitar (00111) |
| 13 | 63 bitar | 0 bitar | 60 bitar (12,8, 12,8, 12,8) | 5 bitar (01011) |
| 14 | 63 bitar | 0 bitar | 60 bitar (16,4, 16,4, 16,4) | 5 bitar (01111) |
Varje format i den här tabellen kan identifieras unikt av lägesbitarna. De första tio lägena används för paneler med två regioner och lägesbitfältet kan vara två eller fem bitar långt. Dessa block har också fält för komprimerade färgslutpunkter (72 eller 75 bitar), partitionen (5 bitar) och partitionsindexen (46 bitar).
För de komprimerade färgslutpunkterna noterar värdena i föregående tabell precisionen för de lagrade RGB-slutpunkterna och antalet bitar som används för varje färgvärde. Till exempel anger läge 3 en precisionsnivå för färgslutpunkten på 11 och antalet bitar som används för att lagra deltavärdena för de transformerade slutpunkterna för de röda, blå och gröna färgerna (5, 4 respektive 4). Läge 10 använder inte deltakomprimering och lagrar i stället alla fyra färgslutpunkterna explicit.
De sista fyra blocklägena används för paneler med en region, där lägesfältet är 5 bitar. Dessa block har fält för slutpunkterna (60 bitar) och de komprimerade indexen (63 bitar). Läge 11 (till exempel Läge 10) använder inte deltakomprimering och lagrar i stället båda färgslutpunkterna explicit.
Lägena 10011, 10111, 11011 och 11111 (visas inte) är reserverade. Använd inte dessa i kodaren. Om maskinvaran skickas block med något av dessa lägen angivet, måste det resulterande dekomprimerade blocket innehålla alla nolla i alla kanaler förutom alfakanalen.
För BC6H måste alfakanalen alltid returnera 1,0 oavsett läge.
BC6H-partitionsuppsättning
Det finns 32 möjliga partitionsuppsättningar för en panel med två regioner och som definieras i tabellen nedan. Varje 4x4-block representerar en enda form.
I den här tabellen med partitionsuppsättningar är den fetstilade och understrukna posten platsen för korrigeringsindexet för delmängd 1 (som anges med en mindre bit). Korrigeringsindexet för delmängd 0 är alltid index 0, eftersom partitioneringen alltid är ordnad så att index 0 alltid finns i delmängd 0. Partitionsordningen går från övre vänstra till nedre högra hörnet, flyttas åt vänster till höger och sedan uppifrån och ned.
BC6H-komprimerat slutpunktsformat
Den här tabellen visar bitfälten för de komprimerade slutpunkterna som en funktion i slutpunktsformatet, där varje kolumn anger en kodning och varje rad som anger ett bitfält. Den här metoden tar upp 82 bitar för paneler med två regioner och 65 bitar för paneler i en region. Till exempel är de första 5 bitarna för enregion [16 4] kodning ovan (särskilt den högra kolumnen) bitar m[4:0], de följande 10 bitarna är bitar rw[9:0], och så vidare med de sista 6 bitarna som innehåller bw[10:15].
Fältnamnen i tabellen ovan definieras på följande sätt:
| Fält | Variabel |
|---|---|
| m | läge |
| d | formindex |
| Rw | endpt[0]. A[0] |
| Rx | endpt[0]. B[0] |
| Ry | endpt[1]. A[0] |
| rz | endpt[1]. B[0] |
| Gw | endpt[0]. A[1] |
| gx | endpt[0]. B[1] |
| Gy | endpt[1]. A[1] |
| gz | endpt[1]. B[1] |
| Bw | endpt[0]. A[2] |
| Bx | endpt[0]. B[2] |
| vid | endpt[1]. A[2] |
| Bz | endpt[1]. B[2] |
Endpt[i], där jag är antingen 0 eller 1, refererar till den 0:e respektive 1:a uppsättningen slutpunkter.
Signera tillägg för slutpunktsvärden
För paneler med två regioner finns det fyra slutpunktsvärden som kan signeras. Endpt[0]. A är endast signerat om formatet är ett signerat format. de andra slutpunkterna signeras endast om slutpunkten omvandlades eller om formatet är ett signerat format. Koden nedan visar algoritmen för att utöka tecknet för slutpunktsvärden för två regioner.
static void sign_extend_two_region(Pattern &p, IntEndpts endpts[NREGIONS_TWO])
{
for (int i=0; i<NCHANNELS; ++i)
{
if (BC6H::FORMAT == SIGNED_F16)
endpts[0].A[i] = SIGN_EXTEND(endpts[0].A[i], p.chan[i].prec);
if (p.transformed || BC6H::FORMAT == SIGNED_F16)
{
endpts[0].B[i] = SIGN_EXTEND(endpts[0].B[i], p.chan[i].delta[0]);
endpts[1].A[i] = SIGN_EXTEND(endpts[1].A[i], p.chan[i].delta[1]);
endpts[1].B[i] = SIGN_EXTEND(endpts[1].B[i], p.chan[i].delta[2]);
}
}
}
För paneler med en region är beteendet detsamma, bara när endpt[1] har tagits bort.
static void sign_extend_one_region(Pattern &p, IntEndpts endpts[NREGIONS_ONE])
{
for (int i=0; i<NCHANNELS; ++i)
{
if (BC6H::FORMAT == SIGNED_F16)
endpts[0].A[i] = SIGN_EXTEND(endpts[0].A[i], p.chan[i].prec);
if (p.transformed || BC6H::FORMAT == SIGNED_F16)
endpts[0].B[i] = SIGN_EXTEND(endpts[0].B[i], p.chan[i].delta[0]);
}
}
Transformera inversion för slutpunktsvärden
För paneler med två regioner tillämpar transformeringen inversen av skillnadskodningen och lägger till basvärdet vid endpt[0]. A till de tre andra posterna för totalt 9 tilläggsåtgärder. I bilden nedan representeras basvärdet som "A0" och har den högsta flyttalsprecisionen. "A1", "B0" och "B1" är alla delta som beräknas från ankarvärdet, och dessa deltavärden representeras med lägre precision. (A0 motsvarar endpt[0]. A, B0 motsvarar endpt[0]. B, A1 motsvarar endpt[1]. A och B1 motsvarar endpt[1].B.)
För paneler med en region finns det bara en deltaförskjutning och därför bara 3 tilläggsåtgärder.
Dekomprimeraren måste se till att resultatet av inverterad transformering inte spiller över precisionen för endpt[0].a. När det gäller ett spill måste värdena som härrör från den omvända transformeringen omslutas inom samma antal bitar. Om precisionen för A0 är "p"-bitar är transformeringsalgoritmen:
B0 = (B0 + A0) & ((1 << p) - 1)
För signerade format måste även resultatet av deltaberäkningen signeras. Om sign extension-åtgärden överväger att förlänga båda tecknen, där 0 är positivt och 1 är negativt, tar teckenförlängningen av 0 hand om klämman ovan. Efter klämman ovan behöver endast ett värde på 1 (negativ) signeras.
Icke-kvantisering av färgslutpunkter
Med tanke på de okomprimerade slutpunkterna är nästa steg att utföra en inledande icke-kvantisering av färgslutpunkterna. Detta omfattar tre steg:
- En icke-kvantisering av färgpaletten
- Interpolering av paletterna
- Slutförande av icke-kvantisering
Om du separerar unquantization-processen i två delar (okvantisering av färgpalett före interpolering och slutlig icke-kvantisering efter interpolering) minskar antalet multiplikationsåtgärder som krävs jämfört med en fullständig icke-kvantiseringsprocess före palettinterpolation.
Koden nedan illustrerar processen för att hämta uppskattningar av de ursprungliga 16-bitars färgvärdena och sedan använda de angivna viktvärdena för att lägga till ytterligare 6 färgvärden i paletten. Samma åtgärd utförs på varje kanal.
int aWeight3[] = {0, 9, 18, 27, 37, 46, 55, 64};
int aWeight4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
// c1, c2: endpoints of a component
void generate_palette_unquantized(UINT8 uNumIndices, int c1, int c2, int prec, UINT16 palette[NINDICES])
{
int* aWeights;
if(uNumIndices == 8)
aWeights = aWeight3;
else // uNumIndices == 16
aWeights = aWeight4;
int a = unquantize(c1, prec);
int b = unquantize(c2, prec);
// interpolate
for(int i = 0; i < uNumIndices; ++i)
palette[i] = finish_unquantize((a * (64 - aWeights[i]) + b * aWeights[i] + 32) >> 6);
}
Nästa kodexempel visar interpoleringsprocessen med följande observationer:
- Eftersom det fullständiga intervallet med färgvärden för icke-likställd funktion (nedan) är från -32768 till 65535 implementeras interpolatorn med hjälp av 17-bitars signerad aritmetik.
- Efter interpolering skickas värdena till funktionen finish_unquantize (beskrivs i det tredje exemplet i det här avsnittet), som tillämpar den slutliga skalningen.
- Alla maskinvarudekomprimatorer måste returnera bit korrekta resultat med dessa funktioner.
int unquantize(int comp, int uBitsPerComp)
{
int unq, s = 0;
switch(BC6H::FORMAT)
{
case UNSIGNED_F16:
if(uBitsPerComp >= 15)
unq = comp;
else if(comp == 0)
unq = 0;
else if(comp == ((1 << uBitsPerComp) - 1))
unq = 0xFFFF;
else
unq = ((comp << 16) + 0x8000) >> uBitsPerComp;
break;
case SIGNED_F16:
if(uBitsPerComp >= 16)
unq = comp;
else
{
if(comp < 0)
{
s = 1;
comp = -comp;
}
if(comp == 0)
unq = 0;
else if(comp >= ((1 << (uBitsPerComp - 1)) - 1))
unq = 0x7FFF;
else
unq = ((comp << 15) + 0x4000) >> (uBitsPerComp-1);
if(s)
unq = -unq;
}
break;
}
return unq;
}
finish_unquantize anropas efter palettinterpolation. Funktionen unquantize skjuter upp skalningen med 31/32 för signerad, 31/64 för osignerad. Det här beteendet krävs för att få det slutliga värdet till ett giltigt halvintervall(-0x7BFF ~ 0x7BFF) efter att palettinterpolationen har slutförts för att minska antalet nödvändiga multiplikationer. finish_unquantize tillämpar den slutliga skalningen och returnerar ett osignerat kort värde som omtolkas till hälften.
unsigned short finish_unquantize(int comp)
{
if(BC6H::FORMAT == UNSIGNED_F16)
{
comp = (comp * 31) >> 6; // scale the magnitude by 31/64
return (unsigned short) comp;
}
else // (BC6H::FORMAT == SIGNED_F16)
{
comp = (comp < 0) ? -(((-comp) * 31) >> 5) : (comp * 31) >> 5; // scale the magnitude by 31/32
int s = 0;
if(comp < 0)
{
s = 0x8000;
comp = -comp;
}
return (unsigned short) (s | comp);
}
}
Relaterade ämnen