GPU를 위한 텍스쳐 압축 기법 (DXT, PVRTC, ETC, ASTC)

2023. 11. 4. 02:33배움엔 끝이없다/그래픽스

유튜브 Unity Korea 채널의 알쓸유잡 - 효율적인 텍스처 압축 이해하기 영상을 참고해 공부한 내용을 정리했습니다.
추가로 유니티의 ETC 관련 블로그 포스팅을 참고했습니다.

 

기본적으로 텍스쳐는 32bpp, half color 표현시 16bpp로 텍스쳐를 표현한다.
보통 익숙한 png나 jpg등의 가변비율 인코딩 방식은 디스크에 이미지를 저장할 때 사용하는 방식으로,
GPU에서 텍스쳐를 사용할 때는 Sample 연산을 위해 다시 원본을 복원해 메모리에 올려야한다.

GPU에선 interpolation 등의 이유로 Sample 연산을 무지 많이 해야하기 때문에, 실제 메모리에 올라가는 텍스쳐를 압축하려면

  • 빠른 디코딩이 되어야 하고
  • Random Access가 되어야한다.

블럭기반 압축

앞으로 설명할 텍스쳐 압축 방식은 블럭기반 압축을 사용한다.
이미지를 4x4 등의 작은 블록으로 나누어 블록 내 Dominant한 색을 인코딩 해 압축하는 방법을 말한다.
이런 방법을 이용하기 때문에 블럭기반 압축은 고정비율 압축이다.

 

쭉 보아하니 모든 방식이 디테일에서 차이가 있지 다 같은 방식을 사용한다.
4x4 블록을 이용한다고 가정하면 큰 흐름은 아래와 같다.

  1. 이미지를 4x4블록 단위로 나눈다.
  2. 해당 블록 내 Dominant한 대표색을 X개 추출한다. (보통 2개) 이를 Base color라 한다.
  3. 블록 내 픽셀들을 추출한 대표색 사이의 interpolation을 이용해 낮은 비트 수로 표현한다. 이를 modifier table라 한다.

https://blog.unity.com/technology/crunch-compression-of-etc-textures

DXT

DirectX Texture로, DirectX에서 사용하는 텍스쳐 압축 기법이다.
S3TC, BC 등으로 표현되기도 하고, DXT1, DXT2, BC1, BC2 등 뒤에 숫자가 붙는다.

 

4x4 블록을 이용하며, 대표색 2개를 추출한다. 대표색 2가지를 각 16bit로 표현한다.

이후 블록내 각 픽셀에 2bit가 할당되며, 대표색 2개 사이의 색 2개를 포함해 4가지 색을 매핑한다.

예를들어 대표색이 검정과 밝은 빨강이면, 00이 검정, 11이 밝은 빨강, 01은 어두운 빨강, 10은 좀 밝은 빨강이 된다.

이렇게하면 16픽셀을 표현하는데 16 * 2 + 2 * 4 * 4 = 64bit를 사용해, 4bpp로 압축하는 효과가 있다.

 

앞으로 기술할 압축 방법들이 이 방식을 기반으로 압축하게된다.

당연히 이렇게 할 경우 블록 내에 Dominant한 색이 3가지라면, 한가지 색이 사라지기 때문에 변질이 일어날 수 있다.

PVRTC

Power VR Texture Compression으로, 예전 애플 기기에서 주로 활용했다고 한다.

 

DXT와 비슷하나, DXT 이용 시 블록의 경계가 보이는 경우가 있어 이 경계를 Blur해주는 과정을 추가했다.

이 방법은 Solid한 색을 이용해야하는 UI 이미지 등에는 부적절하다.

ETC

Ericsson Texture Compression으로, 안드로이드 기기에서 주로 사용한다.

ETC1과 2가 있는데, ETC2가 alpha 표현을 지원하며 더 많은 bpp를 사용하지만, 비교적 최신 디바이스에서만 사용이 가능하다. (그래도 대부분의 기기에서 사용 가능하다.)

 

ETC는 인간의 눈이 채도에는 둔감하지만 밝기에는 민감하다는 사실을 이용해 조금 다른 방식으로 블록내 색을 인코딩한다.

  1. 4x2 2개로 나눠서 이용한다. (가로인지 세로인지 flip bit에 포현)
  2. 각 sub block의 대표색 2가지씩 계산한다. 이는 RGB444로 표현되기도 하고, 한쪽은 RGB555로 표현하고 다른쪽은 RGB333으로 반대쪽 대표색으로부터의 offset을 표현하기도 한다. (방식은 diff bit에 표현)
  3. 이후 각 픽셀마다 2bit씩 할당되어 색을 표현한다.
  4. 각 sub block에 3bit씩 modifier table index가 주어지는데, 이는 미리 정해진 8가지 intensity 조정값 중 하나이다.

https://blog.unity.com/technology/crunch-compression-of-etc-textures

ETC1은 한 블록 16픽셀을 표현하는데 12*2 (base color) + 2 (flip, diff) + 16 * 2 + 3 * 2 (modifier table index) = 64bit로,

4bpp로 한 비트를 표현한다. ETC2는 8bpp를 사용한다.

ASTC

Adaptable Scalable Texture Compression으로, 모바일 기기 대부분이 이 방식을 사용한다.

 

기본적으로는 DXT와 같은 대표색을 블렌딩하는 방식으로 표현하는데,

그 블렌딩 방법을 8가지 다른 모드로 지정할 수 있다.

 

또 ASTC는 가변 블록크기를 사용한다. 블럭을 4x4에서 12x12로 원하는 크기로 지정할 수 있다.

ASTC는 블록마다 128bit를 사용하기 때문에, 블록 크기에 따라 압축률이 달라진다.

 

대표색을 4개 활용하며, 2개의 대표색 partition으로 만든다. 각 partition은 한 색으로부터 다른 색으로의 그라디언트다.

어떤 대표색 partition인지에 해당하는 partition index와 그 색 그라디언트에서의 값을 나타내는 texel weight 두가지 정보를 활용하는 방법을 사용한다.

여기서 partition index는 등장하는 패턴 4만 3천여가지 미리 지정해둬 인코딩해 사용한다.

BC7

앞선 DTX 시리즈 중 하나인 BC7은 ASTC와 유사하나 partition index 패턴을 64가지 사용한다는 차이점이 있다.

반응형