시작하기 전에..
프로젝트에서 자체 텍스처 포멧을 사용하는 경우 텍스처 압축 포멧을 추가해야 할 때마다 압축기를 통해 압축 데이터를 지원해야 하는 경우가 발생한다. 압축기를 제공하는 오픈소스 라이브러리가 여러가지 있는데 NVIDIA의 NVTT의 경우 NVIDIA Texture Tools 3 부터는 풀 소스가 아닌 SDK 형식의 라이브러리를 제공한다. 빌드된 툴로는 DDS 형식의 포멧으로 적용을 해야 했기에 텍스처 데이터만 필요한 경우 SDK를 활용하여 압축기를 구성해야한다.
https://developer.nvidia.com/gpu-accelerated-texture-compression
NVIDIA Texture Tools 3
NVTT 3 can be used to compress textures to and from block-compressed formats including BC1-7 and LDR ASTC, which stay small both on disk and in GPU memory. Or use its image processing functions, like mipmapping and convolution, as part of a custom app or a
developer.nvidia.com
- 텍스처 압축을 어떻게든 한다 치고.. 압축 해제는 어느 시점에?
압축 해제는 GPU에서 텍스처를 샘플링하는 순간에 이루어집니다.
GPU에 업로드된 텍스처가 압축 상태 그대로 VRAM에 존재하고, Shader에서 샘플링을 실행할 때 GPU는 해당 텍셀을 포함하는 압축된 블록을 가져와서 하드웨어가 실시간 압축 해제를 수행하므로 CPU 측에서 압축 해제 단계가 필요하지 않다.
- 텍스처 포멧별 BPP(Bits Per Pixel)는 실제로 텍셀당 저장되는 비트 크기인가?
일반적인 비트맵처럼 1:1 대응은 아닙니다. BC Format의 실제 데이터 레이아웃은 고정 블록 크기 (ex: 4x4, 6x6 ...) 를 기준으로 압축을 수행하며, 해당 블록 전체에 대한 비트 수를 기준으로 BPP를 계산한다.
텍셀마다 다르게 저장되는 게 아니라, 블록 단위 압축이므로 평균 BPP(Bits Per Pixel)라고 표현할 수 있다.
텍스처 압축의 필요성
- 컴퓨터 메모리가 수년에 걸쳐 더 커지고 빨라지고 저렴해졌음을 고려하면 여전히 메모리에서 텍스처를 압축해야 하는 필요성이 있는지 의문이 들지만 시각적 디테일을 높이고 반복을 줄이기 위해 더 높은 해상도의 더 많은 텍스처를 계속해서 요구하고 있다.
- 게임 쉐이딩 모델이 더욱 정교해짐에 따라 각 재질에는 Diffuse Color, Normal, Specular Color, Emissive, Metalic, Roughness, AO 등 더 많은 수의 텍스처가 필요하다.
- 리소스 용량이 작아지면 리소스 로딩 속도도 빨라진다. 또한 GPU가 텍스처 메모리에서 텍스처 픽셀 당 읽어들이는 데이터의 크기도 작아지므로 해당 픽셀을 GPU의 셰이더 코어로 가져오는 데 필요한 메모리 대역폭도 줄어들어 성능 향상을 가져온다. 압축된 텍스처를 디코딩하는 과정이 추가되지만 압축된 텍스처는 GPU에서 디코딩하고, GPU는 빠르다.
압축 포멧별 요구사항
포멧별 압축률 비교
PC Format
S3TC
- 4x4의 블록 기반 압축 형식이다.
- 팔레트는 모든 색상이 RGB 공간의 선분을 따라 균일한 간격으로 배치되어 있다고 가정하여 더욱 압축된다.
- 압축 데이터 파일은 블록당 해당 선의 끝점만 저장하면 되며 다른 모든 팔레트 항목은 두 끝점을 서로 다른 비율로 혼합하여 재구성된다.
BC1 (DXT1) / BC1a (DXT1a)
- BC1은 블록당 두개의 Endpoint를 설정하며 각각 RGB(5:6:5)의 16bit 색상 데이터를 저장한다.
- 각 텍셀당 2bit의 색상 인덱스를 저장하여 디코딩 과정에서 보간한다.
- 인코딩 과정에서 Endpoint을 반전을 주어 저장할 경우 알파 지원이 가능하지만 보간 단계가 4단계에서 3단계로 한단계 줄어드는 대신 알파 1bit의 활용이 가능하다.
BC2 (DXT2 / DXT3)
- BC2은 RGB 디코딩 보간 방식은 BC1과 동일하며 알파 데이터만 추가된 형태이다.
- 알파 데이터는 각 텍셀별로 존재하기에 블록당 4x4x4 64bit 추가 메모리가 필요하다.
- 각 텍셀별 알파의 보간은 0~255 사이의 4bit 인덱스값이 텍셀에 저장되어 있으며 해당 인덱스를 통한 16단계의 보간이 이루어진다.
- 알파 데이터의 추가로 인해 BC1은 픽셀당 8bit인 반면, BC2는 데이터의 크기가 픽셀당 16bit로 압축된다.
BC3 (DXT4 / DXT5)
- BC3는 RGB 디코딩 보간 방식은 BC1과 동일하며 알파 데이터만 추가된 형태이다.
- 알파 데이터는 텍셀당 3bit 인덱스와 두개의 8bit Endpoint를 저장한다.
- 각 텍셀별 알파 보간은 RGB 디코딩 방식과 유사하며 두개의 Endpoint를 기준으로 텍셀의 인덱스를 통해 보간이 이루어진다.
- BC3가 4개의 알파 값만 보간하는 경우 두 개의 추가 알파 값(완전 투명의 경우 0, 완전 불투명의 경우 255)을 설정한다.
- BC2와 데이터 크기는 동일하나 보간 기준점이 블록 단위의 최소 최대값으로 저장되어 텍셀별 인덱스에 할당되는 비트수가 적더라도 정밀도가 높게 표현되기 쉽다.
RGTC
- RG 압축 형식에는 부호 없는 빨간색(BC4_UNORM), 부호 있는 빨간색(BC4_SNORM), 부호 없는 빨간색/녹색(BC5_UNORM), 부호 있는 빨간색/녹색(BC5_NORM)의 4가지가 있다.
- BC4 / BC5는 동일한 알고리즘을 통해 인코딩 및 디코딩이 이루어지며 필요한 구성의 개수에 따라 선별하여 사용하여야 한다.
- 해당 압축 포멧의 알고리즘은 BC3(DXT5)의 알파 형식과 동일한 압축을 사용한다.
BC4
- 각 색상에 대해 8bit를 사용하여 단일 구성 요소 색상 데이터를 저장하기 위한 포멧이다.
- 인코딩 및 디코딩 방식은 BC3의 알파 채널의 처리 방식과 동일하다.
- BC4의 알고리즘은 3bit 인덱스를 사용하여 8가지 색상이 포함된 색상표에서 색상을 찾는다. 저장된 두 색상(red_0 및 red_1)은 최소 및 최대 색상이다. 알고리즘은 선형 보간을 사용하여 나머지 색상을 계산한다.
- 4개의 알파 값만 보간하는 경우 두 개의 추가 알파 값을 설정한다. 추가된 알파 값은 포멧 표현 형식에 따라 최소 최대값이 설정된다.
- BC4는 signed( -1.0 ~ 1.0 )와 unsigned( 0.0 ~ 1.0 ) 포멧 형식에 따라 해당 범위로 인코딩 및 디코딩이 처리된다.
BC5
- 각 색상에 대해 8bit를 사용하여 2성분 색상 16bit 데이터를 저장하기 위한 포멧이다.
- 각 채널별 알고리즘은 BC4와 동일하며 단일 채널에서 2개의 채널로 확장된 포멧이다.
- BC5 또한 signed와 unsigned 포멧 형식을 지원한다.
BPTC
# 용어 정리
- Partition은 64개의 공간 분할 패턴으로 이루어져 있으며, 인코딩 과정에서 블록당 적절한 패턴을 선정하여 Partition ID를 저장한다.
- Subset의 개수에 대한 공간 분할 패턴이 사전에 계산되어 있어 Partition ID를 통해 해당 블록을 선정힌다.
- 해당 텍스처의 블록당 지정된 Subset 개수와 Partition ID를 기반으로 4x4 각 텍셀의 인덱스를 통해 색상 보간이 이루어진다.
- 구성 요소당 보간 비트는 2, 3, 4비트일 수 있다. 각 비트 수에 해당하는 aWeight2, aWeight3, aWeight4 가중치 테이블이 사전에 계산되어 있으며 보간 비트는 이에 대한 인덱스이다.
- 이러한 가중치는 6비트 고정 소수점 승수 역할을 한다.
- 인덱스값의 총 비트수가 3비트×4×4의 48비트가 아니라 45비트이거나, 2비트×4×4의 32비트가 아니라 30비트 등의 인덱스 비트수에 대한 총합이 다르게 되어 있는 것을 볼 수 있다.
- BPTC는 여러 개의 모드가 존재하며 각 블록의 데이터 크기는 동일해야 한다. 이로 인해 저장해야하는 인덱스 테이블의 크기가 부족하게 되는데 Subset의 개수에 따라 fix-up index를 추가하여 해당 인덱스들은 다른 텍셀의 인덱스에 비해 1비트 적게 저장되며 임의로 지정하는 것이 아닌 파티션의 타입별로 고정적으로 지정되어 있다.
- fix-up index의 정밀도는 다른 텍셀에 비해 1bit 떨어지지만 기존에 S3TC보다 많은 Subset을 사용하기에 보다 나은 퀄리티를 제공할 수 있다.
BC6H
- Partitioning

- 블록당 두 개의 개별 라인 세그먼트를 허용한다.
- 색상 변화가 큰 블록의 품질을 높인다.
- 사전에 계산된 32개의 파티션 중 하나를 사용하여 현재 텍셀을 두 개의 라인 세그먼트 중 하나에 할당한다.
- Delta Compression


- 첫 번째 끝점은 반정밀도 부동 소수점(half 16bit)으로 저장된다. (Base Endpoint)
- 비슷한 값을 가진 블록의 품질을 높인다.
- 끝점은 RGB 공간에서 선분을 정의한다.
- 나머지 3개의 Endpoint는 기본 끝점에서 부호 있는 오프셋으로 저장된다.
- 저장된 값은 정수이며 끝점 보간은 정수로 처리한다.
- BC6H는 부동 소수점 비정규화를 지원하지만 INF, Nan은 지원하지 않으므로 인코더에서 해당 데이터는 변환이 필요하다.
- 부동 소수점으로의 변환은 디코딩의 마지막 단계에서 발생한다. (텍스처 필터링 이전)
- BC6H는 각 블록에 대한 14가지 모드가 존재하며 모드 번호는 하위 2bit 또는 하위 5bit로 인코딩된다.
- 인코딩된 모드 번호는 하위 2bit가 2보다 작으면 모드 번호이고 그렇지 않으면 하위 5bit가 모드 번호로 식별한다.
- 모드 중 파티션 비트가 없는 경우에는 단일 하위 집합(Subset) 블록이다.
- Base Endpoint를 제외한 Offset Delta Vector의 경우 ( Endpoint 개수 - 1 x Delta Vector Bit ) 의 데이터가 인코딩 된다.
BC7
- 원리는 S3TC와 비슷하며 4x4 블록단위로 압축이 이루어지고 블록당 Endpoint가 한쌍이 아닌 최대 3쌍을 보유할 수 있으며, 공간 분할 패턴에 의한 64개의 Partition이 나뉘어 Endpoint 개수에 대한 패턴들이 사전에 계산되어 있어 보간에 사용되는 비트를 늘려 정밀도를 높일 수 있도록 설계되어 있다.
- BC3와 동일하게 알파 채널의 독립적인 인덱스 테이블이 있는 경우도 있으며 다른 채널과의 스위칭도 하드웨어 디코딩 과정에서 처리하기 위해 Mode 4,5에서 회전 비트를 사용할 수 있도록 되어있다.
- BC7에는 공유 비트(P-bit)란 것이 존재하는데 모든 채널은 공유 비트 수 만큼 확장되어 가장 낮은 비트로 사용된다.
- 이전의 S3TC의 경우 단일 모드로 모든 블록들의 디코딩 처리가 동일한 알고리즘으로 처리되었지만, BPTC의 경우 모드별로 다양한 디코딩 방식을 활용할 수 있도록 되어있다.
- Mode 0은 상위 16개의 패턴만 사용한다.
- Mode 0

- Color components only (no alpha)
- 3 subsets per block
- RGBP 4.4.4.1 endpoints with a unique P-bit per endpoint
- 3-bit indices
- 16 partitions
- Mode 1

- Color components only (no alpha)
- 2 subsets per block
- RGBP 6.6.6.1 endpoints with a shared P-bit per subset)
- 3-bit indices
- 64 partitions
- Mode 2

- Color components only (no alpha)
- 3 subsets per block
- RGB 5.5.5 endpoints
- 2-bit indices
- 64 partitions
- Mode 3

- Color components only (no alpha)
- 2 subsets per block
- RGBP 7.7.7.1 endpoints with a unique P-bit per subset)
- 2-bit indices
- 64 partitions
- Mode 4

- Color components with separate alpha component
- 1 subset per block
- RGB 5.5.5 color endpoints
- 6-bit alpha endpoints
- 16 x 2-bit indices
- 16 x 3-bit indices
- 2-bit component rotation
- 1-bit index selector (whether the 2- or 3-bit indices are used)
- Mode 5

- Color components with separate alpha component
- 1 subset per block
- RGB 7.7.7 color endpoints
- 8-bit alpha endpoints
- 16 x 2-bit color indices
- 16 x 2-bit alpha indices
- 2-bit component rotation
- Mode 6

- Combined color and alpha components
- One subset per block
- RGBAP 7.7.7.7.1 color (and alpha) endpoints (unique P-bit per endpoint)
- 16 x 4-bit indices
- Mode 7

- Combined color and alpha components
- 2 subsets per block
- RGBAP 5.5.5.5.1 color (and alpha) endpoints (unique P-bit per endpoint)
- 2-bit indices
- 64 partitions
Mobile Format
ETC
- Android 기반 장치의 표준 압축 방식이다.
- ETC 블록의 크기는 4x4이며, 두 개의 하위 블록으로 구성된다. Differential 블록 유형은 첫 번째 하위 블록의 기본 색상이 RGB555 정밀도로 저장되고 두 번째 기본 색상에 대해 3bit 오프셋이 저장된다. Individual 블록 유형의 경우 두 기본 색상이 모두 RGB444 형식으로 직접 저장된다.
- 두 모드 모두에서 4×4 블록은 2×4 또는 4×2 크기의 두 개의 하위 블록으로 나뉜다. 이에 대한 결정은 플립 비트(flip)를 통해 이루어진다.
- T0 / T1은 각 기준 색상별 휘도 테이블에 대한 3bit의 인덱스 값이며 0~7까지의 구간이 있다. 각 텍셀별 보간 구간에 대한 2bit의 인덱스 값을 저장한다.
PVRTC
- 주로 iOS 장치에서 사용 가능하며 드물게 Android에서 PowerVR 그래픽 코어를 사용하는 기기의 경우 지원 가능한 압축 방식이다.
- PVRTC의 주요 목표는 S3TC 및 ETC1과 같은 블록 기반 방법에서 자주 발생하는 직사각형 영역의 불연속성을 피하는 것이다. 텍스처를 독립적인 텍셀 블록으로 간주하는 대신 텍스처를 이중선형으로 확대된 한 쌍의 저해상도 이미지로 나타낸다.
- 알파 채널을 지원하는 경우 각 블록의 Endpoint RGB의 각 채널별 1bit씩 총 3bit를 알파 채널에 할당하여 활용한다.
- 해당 압축 포멧은 샘플링 과정에서 디코딩 이후 Blurring이 추가적으로 진행된다.
- 블록내의 다른 픽셀의 색은, 자신의 대표색과 주위의 블록의 대표색을 사용해 보간하는 것으로 색을 넣어 간다.
ASTC
- 모든 OpenGL ES 3.2 및 OpenGL ES 3.1+AEP GPU와 일부 OpenGL ES 3.0 GPU에서 지원한다.
- ASTC는 S3TC/BC7과 유사합니다. 최대 4개의 Subset과 보간 가중치가 압축된 블록에 저장되고 사전 정의된 파티션만 지원되며 파티션 ID는 블록에 저장된다.
- LDR, HDR, 2D 및 3D 텍스처도 지원하므로 유연한 형식이다.
- ASTC는 S3TC/BC7과 다르게 고정 블록 형식이 아닌 가변 블록 형식을 지원한다. 모든 형식의 블록의 크기는 128bit로 동일하며 필요에 따라 정밀도가 중요하지 않는 텍스처의 경우 블록의 크기를 크게 설정하여 메모리를 절약 할 수 있다.
References
- BC Format
https://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats
https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression
https://learn.microsoft.com/en-us/windows/win32/direct3d11/texture-block-compression-in-direct3d-11
https://registry.khronos.org/DataFormat/specs/1.1/dataformat.1.1.html#BPTC
https://fileadmin.cs.lth.se/cs/Education/EDAN35/lectures/L8-texcomp.pdf
- Mobile Format
https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.pdf
https://sv-journal.org/2014-1/06/en/index.php?lang=en#6-4
'Graphics' 카테고리의 다른 글
Animation Compression (0) | 2025.04.22 |
---|---|
Animation Retargeting (0) | 2025.04.16 |
[DirectX 11] Dissolve Effect (0) | 2022.06.27 |
[DirectX 11] Color Grading & LookUpTable Texture (0) | 2022.06.23 |
[DirectX 11] HDRI Sky Light & Sky Cube Baking (0) | 2022.05.25 |