BC7 형식

BC7 형식은 RGB 및 RGBA 데이터의 고품질 압축에 사용되는 텍스처 압축 형식입니다.

BC7 형식의 블록 모드에 대한 자세한 내용은 BC7 형식 모드 참조참조하세요.

BC7/DXGI_FORMAT_BC7 정보

BC7은 다음 DXGI_FORMAT 열거형 값으로 지정됩니다.

  • DXGI_FORMAT_BC7_TYPELESS.
  • DXGI_FORMAT_BC7_UNORM.
  • DXGI_FORMAT_BC7_UNORM_SRGB.

BC7 형식은 Texture2D(배열 포함), Texture3D 또는 TextureCube(배열 포함) 텍스처 리소스에 사용할 수 있습니다. 마찬가지로 이 형식은 이러한 리소스와 연결된 모든 MIP 맵 화면에 적용됩니다.

BC7은 16바이트(128비트)의 고정 블록 크기와 4x4 텍셀의 고정 타일 크기를 사용합니다. 이전 BC 형식과 마찬가지로 지원되는 타일 크기(4x4)보다 큰 질감 이미지는 여러 블록을 사용하여 압축됩니다. 이 주소 지정 ID는 3차원 이미지 및 MIP 맵, 큐브맵 및 텍스처 배열에도 적용됩니다. 모든 이미지 타일은 동일한 형식이어야 합니다.

BC7은 3개 채널(RGB)과 RGBA(4개 채널) 고정 소수점 데이터 이미지를 모두 압축합니다. 일반적으로 원본 데이터는 색 구성 요소(채널)당 8비트이지만 형식은 색 구성 요소당 더 높은 비트로 원본 데이터를 인코딩할 수 있습니다. 모든 이미지 타일은 동일한 형식이어야 합니다.

BC7 디코더는 텍스처 필터링이 적용되기 전에 압축 해제를 수행합니다.

BC7 압축 해제 하드웨어는 비트 정확해야 합니다. 즉, 하드웨어는 이 문서에 설명된 디코더에서 반환한 결과와 동일한 결과를 반환해야 합니다.

BC7 구현

BC7 구현은 16 바이트(128비트) 블록 중 가장 중요한 비트에 지정된 모드를 사용하여 8개 모드 중 하나를 지정할 수 있습니다. 모드는 값이 0이고 그 뒤에 1이 있는 0개 이상의 비트로 인코딩됩니다.

BC7 블록에는 여러 엔드포인트 쌍이 포함될 수 있습니다. 엔드포인트 쌍에 해당하는 인덱스 집합을 "하위 집합"이라고 할 수 있습니다. 또한 일부 블록 모드에서 엔드포인트 표현은 "RBGP"라고 할 수 있는 형식으로 인코딩됩니다. 여기서 "P" 비트는 엔드포인트의 색 구성 요소에 대해 가장 중요하지 않은 공유 비트를 나타냅니다. 예를 들어 형식의 엔드포인트 표현이 "RGB 5.5.5.1"인 경우 엔드포인트는 RGB 6.6.6 값으로 해석됩니다. 여기서 P비트 상태는 각 구성 요소의 가장 중요한 비트를 정의합니다. 마찬가지로 알파 채널이 있는 원본 데이터의 경우 형식에 대한 표현이 "RGBAP 5.5.5.5.1"인 경우 엔드포인트는 RGBA 6.6.6.6으로 해석됩니다. 블록 모드에 따라, 하위 집합의 각 엔드포인트에 대해 개별적으로 최소 중요 비트를 지정할 수 있습니다(하위 집합당 2개의 P-비트). 또한, 하위 집합의 엔드포인트에 대해 공유된 최소 중요 비트를 지정할 수도 있습니다(하위 집합당 1개의 P-비트).

알파 구성 요소를 명시적으로 인코딩하지 않는 BC7 블록의 경우 BC7 블록은 모드 비트, 파티션 비트, 압축된 엔드포인트, 압축된 인덱스 및 선택적 P 비트로 구성됩니다. 이러한 블록에서 엔드포인트에는 RGB 전용 표현이 있고 알파 구성 요소는 원본 데이터의 모든 텍셀에 대해 1.0으로 디코딩됩니다.

색과 알파 구성 요소가 결합된 BC7 블록의 경우 블록은 모드 비트, 압축된 엔드포인트, 압축된 인덱스, 선택적 파티션 비트 및 P비트로 구성됩니다. 이러한 블록에서 끝점 색은 RGBA 형식으로 표현되며, 알파 구성 요소 값은 색 구성 요소 값과 함께 보간됩니다.

별도의 색 및 알파 구성 요소가 있는 BC7 블록의 경우 블록은 모드 비트, 회전 비트, 압축된 엔드포인트, 압축된 인덱스 및 선택적 인덱스 선택기 비트로 구성됩니다. 이러한 블록에는 효과적인 RGB 벡터 [R, G, B] 및 스칼라 알파 채널 [A]가 별도로 인코딩됩니다.

다음 표에서는 각 블록 유형의 구성 요소를 나열합니다.

BC7 블록에는... 모드 비트 회전 비트 인덱스 선택 비트 파티션 비트 압축된 엔드포인트 P비트 압축된 인덱스
색상 구성 요소만 필수 해당 없음(N/A) 해당 없음(N/A) 필수 필수 선택 사항 필수
색과 알파가 결합됨 필수 해당 없음(N/A) 해당 없음(N/A) 선택 사항 필수 선택 사항 필수
색 및 알파 구분 필수 필수 선택 사항 해당 없음(N/A) 필수 해당 없음(N/A) 필수

 

BC7은 두 엔드포인트 사이의 대략적인 선에 색 팔레트를 정의합니다. 모드 값은 블록당 보간 엔드포인트 쌍 수를 결정합니다. BC7은 텍셀당 하나의 색상표 인덱스만 저장합니다.

엔드포인트 쌍에 해당하는 인덱스의 각 하위 집합에 대해 인코더는 해당 하위 집합에 대한 압축된 인덱스 데이터의 1비트 상태를 수정합니다. 지정된 "수정" 인덱스가 가장 중요한 비트를 0으로 설정할 수 있도록 하는 엔드포인트 순서를 선택함으로써, 이후 삭제되어 하위 집합당 1비트를 절약할 수 있습니다. 단일 하위 집합만 있는 블록 모드의 경우 수정 인덱스는 항상 인덱스 0입니다.

BC7 형식 디코딩

16 바이트 BC7 블록이 주어졌을 때 (x,y)의 픽셀을 압축 해제하는 단계를 다음과 같은 의사 코드로 요약합니다.

decompress_bc7(x, y, block)
{
    mode = extract_mode(block);
    
    //decode partition data from explicit partition bits
    subset_index = 0;
    num_subsets = 1;
    
    if (mode.type == 0 OR == 1 OR == 2 OR == 3 OR == 7)
    {
        num_subsets = get_num_subsets(mode.type);
        partition_set_id = extract_partition_set_id(mode, block);
        subset_index = get_partition_index(num_subsets, partition_set_id, x, y);
    }
    
    //extract raw, compressed endpoint bits
    UINT8 endpoint_array[num_subsets][4] = extract_endpoints(mode, block);
    
    //decode endpoint color and alpha for each subset
    fully_decode_endpoints(endpoint_array, mode, block);
    
    //endpoints are now complete.
    UINT8 endpoint_start[4] = endpoint_array[2 * subset_index];
    UINT8 endpoint_end[4]   = endpoint_array[2 * subset_index + 1];
        
    //Determine the palette index for this pixel
    alpha_index     = get_alpha_index(block, mode, x, y);
    alpha_bitcount  = get_alpha_bitcount(block, mode);
    color_index     = get_color_index(block, mode, x, y);
    color_bitcount  = get_color_bitcount(block, mode);

    //determine output
    UINT8 output[4];
    output.rgb = interpolate(endpoint_start.rgb, endpoint_end.rgb, color_index, color_bitcount);
    output.a   = interpolate(endpoint_start.a,   endpoint_end.a,   alpha_index, alpha_bitcount);
    
    if (mode.type == 4 OR == 5)
    {
        //Decode the 2 color rotation bits as follows:
        // 00 – Block format is Scalar(A) Vector(RGB) - no swapping
        // 01 – Block format is Scalar(R) Vector(AGB) - swap A and R
        // 10 – Block format is Scalar(G) Vector(RAB) - swap A and G
        // 11 - Block format is Scalar(B) Vector(RGA) - swap A and B
        rotation = extract_rot_bits(mode, block);
        output = swap_channels(output, rotation);
    }
    
}

다음 의사 코드는 16 바이트 BC7 블록이 지정된 각 하위 집합에 대한 엔드포인트 색 및 알파 구성 요소를 완전히 디코딩하는 단계를 간략하게 설명합니다.

fully_decode_endpoints(endpoint_array, mode, block)
{
    //first handle modes that have P-bits
    if (mode.type == 0 OR == 1 OR == 3 OR == 6 OR == 7)
    {
        for each endpoint i
        {
            //component-wise left-shift
            endpoint_array[i].rgba = endpoint_array[i].rgba << 1;
        }
        
        //if P-bit is shared
        if (mode.type == 1) 
        {
            pbit_zero = extract_pbit_zero(mode, block);
            pbit_one = extract_pbit_one(mode, block);
            
            //rgb component-wise insert pbits
            endpoint_array[0].rgb |= pbit_zero;
            endpoint_array[1].rgb |= pbit_zero;
            endpoint_array[2].rgb |= pbit_one;
            endpoint_array[3].rgb |= pbit_one;  
        }
        else //unique P-bit per endpoint
        {  
            pbit_array = extract_pbit_array(mode, block);
            for each endpoint i
            {
                endpoint_array[i].rgba |= pbit_array[i];
            }
        }
    }

    for each endpoint i
    {
        // Color_component_precision & alpha_component_precision includes pbit
        // left shift endpoint components so that their MSB lies in bit 7
        endpoint_array[i].rgb = endpoint_array[i].rgb << (8 - color_component_precision(mode));
        endpoint_array[i].a = endpoint_array[i].a << (8 - alpha_component_precision(mode));

        // Replicate each component's MSB into the LSBs revealed by the left-shift operation above
        endpoint_array[i].rgb = endpoint_array[i].rgb | (endpoint_array[i].rgb >> color_component_precision(mode));
        endpoint_array[i].a = endpoint_array[i].a | (endpoint_array[i].a >> alpha_component_precision(mode));
    }
        
    //If this mode does not explicitly define the alpha component
    //set alpha equal to 1.0
    if (mode.type == 0 OR == 1 OR == 2 OR == 3)
    {
        for each endpoint i
        {
            endpoint_array[i].a = 255; //i.e. alpha = 1.0f
        }
    }
}

각 하위 집합에 대해 보간된 각 구성 요소를 생성하려면 다음 알고리즘을 사용하십시오. "c"가 생성할 구성 요소가 되도록 합니다. "e0"이 하위 집합의 엔드포인트 0 구성 요소가 되도록 합니다. 그리고 "e1"이 하위 집합의 엔드포인트 1 구성 요소가 되도록 합니다.

UINT16 aWeight2[] = {0, 21, 43, 64};
UINT16 aWeight3[] = {0, 9, 18, 27, 37, 46, 55, 64};
UINT16 aWeight4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};

UINT8 interpolate(UINT8 e0, UINT8 e1, UINT8 index, UINT8 indexprecision)
{
    if(indexprecision == 2)
        return (UINT8) (((64 - aWeights2[index])*UINT16(e0) + aWeights2[index]*UINT16(e1) + 32) >> 6);
    else if(indexprecision == 3)
        return (UINT8) (((64 - aWeights3[index])*UINT16(e0) + aWeights3[index]*UINT16(e1) + 32) >> 6);
    else // indexprecision == 4
        return (UINT8) (((64 - aWeights4[index])*UINT16(e0) + aWeights4[index]*UINT16(e1) + 32) >> 6);
}

다음 의사코드는 색상 및 알파 구성 요소의 인덱스와 비트 수를 추출하는 방법을 보여줍니다. 색상과 알파가 분리된 블록은 벡터 채널용과 스칼라 채널용 두 가지 인덱스 데이터 집합을 가지고 있습니다. 모드 4의 경우 이러한 인덱스는 너비가 다르며(2비트 또는 3비트), 벡터 또는 스칼라 데이터가 3비트 인덱스를 사용하는지 여부를 지정하는 1비트 선택기가 있습니다. (알파 비트 수를 추출하는 것은 색 비트 수를 추출하는 것과 유사하지만 idxMode 비트에 따라 역 동작을 사용합니다.)

bitcount get_color_bitcount(block, mode)
{
    if (mode.type == 0 OR == 1)
        return 3;
    
    if (mode.type == 2 OR == 3 OR == 5 OR == 7)
        return 2;
    
    if (mode.type == 6)
        return 4;
        
    //The only remaining case is Mode 4 with 1-bit index selector
    idxMode = extract_idxMode(block);
    if (idxMode == 0)
        return 2;
    else
        return 3;
}

BC7 형식 모드 참조

이 섹션에는 BC7 텍스처 압축 형식 블록에 대한 8개 블록 모드 및 비트 할당 목록이 포함되어 있습니다.

블록 내의 각 하위 집합에 대한 색은 두 개의 명시적 엔드포인트 색과 둘 사이의 보간된 색 집합으로 표시됩니다. 블록의 인덱스 정밀도에 따라 각 하위 집합에는 4, 8 또는 16개의 가능한 색이 있을 수 있습니다.

모드 0

BC7 모드 0에는 다음과 같은 특징이 있습니다.

  • 색 구성 요소만(알파 없음)
  • 블록당 3개의 하위 집합
  • 엔드포인트당 고유한 P비트가 있는 RGBP 4.4.4.1 엔드포인트
  • 3비트 인덱스
  • 파티션 16개

모드 0비트 레이아웃

모드 1

BC7 모드 1에는 다음과 같은 특징이 있습니다.

  • 색 구성 요소만(알파 없음)
  • 블록당 2개의 하위 집합
  • 하위 집합당 공유 P비트가 있는 RGBP 6.6.6.1 엔드포인트)
  • 3비트 인덱스
  • 파티션 64개

모드 1비트 레이아웃

모드 2

BC7 모드 2에는 다음과 같은 특징이 있습니다.

  • 색 구성 요소만(알파 없음)
  • 블록당 3개의 하위 집합
  • RGB 5.5.5 엔드포인트
  • 2비트 인덱스
  • 파티션 64개

모드 2비트 레이아웃

모드 3

BC7 모드 3에는 다음과 같은 특징이 있습니다.

  • 색 구성 요소만(알파 없음)
  • 블록당 2개의 하위 집합
  • 하위 집합당 고유한 P비트를 사용하는 RGBP 7.7.7.1 엔드포인트)
  • 2비트 인덱스
  • 파티션 64개

모드 3비트 레이아웃

모드 4

BC7 모드 4에는 다음과 같은 특징이 있습니다.

  • 별도의 알파 구성 요소가 있는 색 구성 요소
  • 블록당 1 하위 집합
  • RGB 5.5.5 색 끝점
  • 6비트 알파 엔드포인트
  • 16 x 2비트 인덱스
  • 16 x 3 비트 인덱스들
  • 2비트 구성 요소 회전
  • 1비트 인덱스 선택기(2비트 또는 3비트 인덱스 사용 여부)

모드 4비트 레이아웃

모드 5

BC7 모드 5에는 다음과 같은 특징이 있습니다.

  • 별도의 알파 구성 요소가 있는 색 구성 요소
  • 블록당 1 하위 집합
  • RGB 7.7.7 색 끝점
  • 6비트 알파 엔드포인트
  • 16 x 2비트 색 인덱스
  • 16 x 2비트 알파 인덱스
  • 2비트 구성 요소 회전

모드 5비트 레이아웃

모드 6

BC7 모드 6에는 다음과 같은 특징이 있습니다.

  • 결합된 색 및 알파 구성 요소
  • 블록당 하나의 하위 집합
  • RGBAP 7.7.7.7.1 색(및 알파) 엔드포인트(엔드포인트당 고유한 P비트)
  • 16 x 4비트 인덱스

모드 6비트 레이아웃

모드 7

BC7 모드 7에는 다음과 같은 특징이 있습니다.

  • 결합된 색 및 알파 구성 요소
  • 블록당 2개의 하위 집합
  • RGBAP 5.5.5.5.1 색(및 알파) 엔드포인트(엔드포인트당 고유한 P비트)
  • 2비트 인덱스
  • 파티션 64개

모드 7비트 레이아웃

설명

모드 8(가장 유의하지 않은 바이트가 0x00 설정됨)은 예약되어 있습니다. 인코더에서 사용하지 마세요. 이 모드를 하드웨어에 전달하면 모든 0으로 초기화된 블록이 반환됩니다.

BC7에서는 다음 방법 중 하나로 알파 구성 요소를 인코딩할 수 있습니다.

  • 명시적 알파 구성 요소 인코딩이 없는 블록 형식입니다. 이러한 블록에서 색 엔드포인트에는 RGB 전용 인코딩이 있으며 알파 구성 요소는 모든 텍셀에 대해 1.0으로 디코딩됩니다.

  • 색상과 알파 값이 결합된 블록 유형. 엔드포인트 색 값은 이러한 블록에서 RGBA 형식으로 지정되며, 알파 구성 요소 값은 색 값과 함께 보간됩니다.

  • 색상 및 알파 구성 요소가 분리된 블록 유형. 이러한 블록에서 색과 알파 값은 각각 고유한 인덱스 집합을 사용하여 개별적으로 지정됩니다. 결과적으로 유효 벡터와 스칼라 채널은 별도로 인코딩됩니다. 여기서 벡터는 일반적으로 색 채널 [R, G, B]를 지정하고 스칼라는 알파 채널 [A]를 지정합니다. 이 방법을 지원하기 위해 별도의 2비트 필드가 인코딩에 제공되므로 별도의 채널 인코딩을 스칼라 값으로 사양할 수 있습니다. 결과적으로 블록은 이 알파 인코딩의 다음 네 가지 표현 중 하나를 가질 수 있습니다(2비트 필드로 표시됨).

    • RGB|A: 알파 채널 구분
    • AGB|R: "빨강" 색 채널 구분
    • RAB|G: "녹색" 색 채널 분리
    • RGA|B: "파란색" 채널 분리

    디코더는 디코딩 후 채널 순서를 다시 RGBA로 다시 정렬하므로 내부 블록 형식이 개발자에게 보이지 않습니다. 색상 및 알파 채널을 별도로 가진 블랙에는 벡터화된 채널 집합과 스칼라 채널을 위한 두 개의 인덱스 데이터 세트가 있습니다. (모드 4의 경우 이러한 인덱스의 너비는 [2비트 또는 3비트]입니다. 모드 4에는 벡터 또는 스칼라 채널이 3비트 인덱스를 사용하는지 여부를 지정하는 1비트 선택기도 포함되어 있습니다.)

텍스처 블록 압축