본문 바로가기

Graphics , Rendering

ASTC Texture Format

https://github.com/ARM-software/astc-encoder/blob/main/Docs/Encoding.md

 

astc-encoder/Docs/Encoding.md at main · ARM-software/astc-encoder

The Arm ASTC Encoder, a compressor for the Adaptive Scalable Texture Compression data format. - ARM-software/astc-encoder

github.com

 

ASTC 개요

ASTC (=Adaptive Scalable Texture Format) 은 진보된 텍스처 손실압축 기술로, Khronos 에서 OpenGL, OpenGL ES API 에서 공식 Extension 으로 채택되었으며, Vulkan API 에서도 표준 선택기능으로 채택되었다.

다른 텍스처 압축 포맷과 아래와 같은 차별점을 갖고 있다.

  • Format 이 유연함 : 1~4개 채널의 데이터를 압축할 수 있다. RGB + A처럼 1개의 연관 없는 (non-correlated) 채널도 지원한다.
  • Bit rate 이 유연함 : 컬러 포맷 선택과 무관하게 0.89 ~ 8bpt(bit per texel) 을 지원한다.
  • 더 향상된 Format 지원 : LDR, LDR sRGB, HDR 컬러 스페이스와 3D 볼륨 텍스처도 압축할 수 있음
  • 향상된 이미지 퀄리티 : 포맷이 유연함에도, 거의 모든 legacy 텍스처 압축 포맷을 지원함 - ETX2, PVRCT, BC 포맷.. 같은 bitrate대에서도 이미지 품질 면에서 더 뚸어남

 

왜 ASTC인가?

ASTC가 생겨나기 전, 사용가능한 포맷의 bitrate 분포도는 아래와 같이 매우 듬성듬성했음

특정 OS 에서 지원히지 않는 포맷들이 있기 때문에 실제로는 위보다 더 열악했다고 볼 수 있음 = 플랫폼별로 아주 제한적인 압축 방식만을 사용할 수 있었음.

여러 플랫폼에 사용 가능한 압축 포맷을 지원해야 하는 개발자 입장에서는 더욱 곤란했음.

 

Block Compression

Sample 좌표만 가지고도 데이터의 주소를 계산할 수 있어야 하고, 랜덤한 샘플을 그 주위의 데이터를 너무 많이 압축 해제하지 않고 압축 해제할 수 있어야함. 이 조건들을 만족하기 위해 ASTC 와 그 외 현대의 실시간 포맷들이 사용하는 일반적인 방법은, 이미지를 고정된 사이즈의 block 단위로 나눠서, 각각의 block을 정해진 갯수의 bit 결과값으로 압축하는 것이었음. 이렇게 하면 순서와 관계없이 texel에 더 빠르게 접근할 수 있고, decomprression 비용도 명확해 진다.

ASTC에서 block 이 차지하는 범위는 4x4 텍셀에서 12ㅌ12 텍셀까지이다. 모두 블록마다 128 bit의 결과값으로 압축한다. 이 128비트를 footprint 내의 텍셀로 나누면, 8bpt(128 / (4x4) )~0.89 bpt (128 / (12x12)) bit rate 범위임을 알 수 있다.

 

Color Encoding

ASTC는 각 텍셀의 컬러를 압축하는데 그라디언트를 사용한다. 압축된 각 블록은 그라디언트의 end point 컬러들과 각 텍셀의 interpolation weight (보간 가중치) - 그라디언트 내에서 texel location을 나타내는 값을 나타낸다. 압축 해제 과정에서 각 텍셀의 컬러값은 이 두 개의 endpoint 컬러들 사이를 텍셀 별 가중치에 따라 보간해서 생성된다.

대부분의 경우에서 블록 1개에는 복잡한 조합의 컬러들이 담기게 된다. 예를 들어. 초록색 바닥 위의 붉은 색 공이 있다고 해 보자. 이 경우에는 컬러 그라디언트 1개로는 모든 텍셀의 값을 정확히 구현하기 힘들다. 이때 ASTC는 블록 당 4개의 개별적인 컬러 그라디언트 - 파티션(partitions) 이라고 함 - 을 정의할 수 있고, 각 텍셀을 1개의 파티션에 할당한다. 앞의 사례에서는 (붉은 공 텍셀과 푸른 바닥 텍셀을 위한) 2개의 파티션이 필요하다.

Integer encoding

texel 당 저장되는 bit 수가 소수인 것이 이상할 수 있지만, ASTC는 BISE(Bounded Integer Sequence Encoding) 라는 인코딩 기술을 사요하기 때문에, 소수로 된 비트 갯수에 데이터를 패킹할 수 있다.

 

Storing Alphabets

컬러와 가중치가 개념상 floating-point 값이 아니지만, 여전히 실제 데이터를 그대로 저장하기에는 bit 수가 부족할 수 있다. 그래서 저장되는 크기를 줄이기 위해 압축하는 과정에서 값이 quantize 된다. 예를 들어, 각 텍셀에 0.0 ~ 1.0 사이의 가중치 값을 저장해야 할 경우, 0.0, 0.25, 0.5, 0.75, 그리고 1.0 다섯 개 값 중 하나를 고를 수 있다. integer 값으로 나타내면 0~4가 된다.

… 이 이후는 생략.

 

 

ASTC 가 아닐 때의 압축 포맷 일람

+ 표시로 결합된 채널들끼리는 압축할 때 Correlated 되지 않는 것으로(서로 관련되지 않는 것으로) 간주
(BC5 포맷일 경우 R. G 채널만 각각 압축됨.

 

ASTC Format Mapping

이러한 Non ACTC 포맷 텍스처를 ASTC 포맷으로 압축할 때, 가장 의문이 드는 것은 RGBA 4개의 컴포넌트가 아닌 텍스처를 어떻게 다루어야 하느냐이다. ASTC는 항상 4개 컴포넌트인 결과로 텍스처를 압축 해제한다. 하지만 압축 규칙이 아주 유연하기 때문에, 블록 단위로 1~4개 어느 갯수의 컴포넌트라도 저장할 수 있다. 압축 과정에서 최대한 적은 컴포넌트가 압축되도록 해야 공간을 낭비하지 않을 수 있다.

아래와 같은 방식들로 텍스처를 구성해 ASTC로 인코딩 되는 텍스처를 최적화 할 수 있다.

  • RGB 컴포넌트를 1개의 밝기 컴포넌트로 인코딩해서, 실제 값 1개만 저장되도록 한다.
  • 알파 채널을 1.0 상수로 지정해서 픽셀 별 알파를 저장하지 않아도 되게끔 한다.

입력되는 텍스처를 위와 같은 방식으로 구성하면 보다 효율적으로 텍스처를 압축할 수 있다.

 

Encoding 1-4 component data

아래의 테이블은 실제 데이터에 존재하는 각 컬러 컴포넌트의 갯수별로 추천되는 컴포넌트 사용 방법이다.

coding swizzle 은 이미지를 압축할 때 적용되어야 한다. 압축되지 않은 이미지를 압축기에서 읽어올 때, -esw 파라미터로 지정해 줄 수 있다.

sampling swizzle은 어플리케이션에서 API 레벨에서의 추가적인 component swizzling 은 적용되지 않았다고 가정했을 때, 압축된 텍스처로부터 데이터를 셰이더 프로그램에서 읽어들일 때 적용되어야 한다.

 

1 : r 채널보다 g 채널로부터 샘플링 되는 것이 선호되는 이유는, 셰이더 1개가 ASTC, BC1 또는 ETC 포맷 모두에게 적합하게끔 하기 때문이다. BC1과 ETC1 은 컬러 endpoint를 RGB565 데이터에 저장하기 때문에 g 컴포넌트가 더 높은 정밀도를 가진다. ASTC에서는 이런 차이가 없다 - rgb 컴포넌트에 각각에 모두 같은 1개의 luminance가 적용된다.

 

Equivalence with other formats

이 컴포넌트 인코딩 조건들에 맞춰, 다른 텍스처 압축 포맷에 대응되는 ASTC 텍스처 형태를 알아낼 수 있다.

  • 1 : ASTC는 BC1 또는 ETC2 에 해당하는 1bit punch-through alpha 에 해당하는 것이 없다. 만약 alpha가 있다면, full-alpha component일 것이다. (0.0 ~ 1.0 까지 모두 쓰는 컴포넌트라는 의미인 듯)
  • 2 : ASTC는 2개 컴포넌트로 구성된 데이터를 다룰 때 L+A 컬러 endpoint 타입에 의존한다. 따라서 BC5 또는 EAC-RG11처럼 r,g 2개의 컴포넌트로부터 샘플링 되는 two-plane 포맷에 해당하는 것이 없다. 이것은 런타임시 API에서 (glTexParameteri 같은 명령어로) 텍스처 컴포넌트를 swizzle 해 주면 된다.
  • 3 : ASTC는 unsigned 값만 저장할 수 있기 때문에, BC6 같은 signed endpoint 모드는 없다.

 

Other Considerations

ASTC로 텍스처를 인코딩할 때 고려하면 좋을 다른 요소들

 

Decode mode extensions

ASTC는 기본적으로 컴포넌트당 16bit로 텍스처를 압축 해제하는데, 예외적으로 sRGB 포맷은 RGB 각 컴포넌트에 대해 8bit 값을 사용한다.

컴포넌트당 16 bit로 압축 해제하는 것은 많은 사용례에서 필요한 것보다 더 많다 - 특히 채널당 8bit인 소스 이미지로부터 만들어진 LDR 텍스처에서는 더욱 그렇다. ASTC 의 대부분의 구현에서 decode mode extension을 지원하는데, 어플리케이션이 더 낮은 정밀도의 포맷으로 압축할 수 있게 선택하도록(LDR은 RGBA8로, HDR은 RGB9E5로) 지원한다. 이런 extension을 사용하면 GPU 텍스처 캐시 효율을 높일 수 있고, 나아가 높은 정밀도를 요하지 않는 경우에서 텍스처 필터링 자료 처리량을 늘릴 수 있다.

ASTC 포맷은 사용된 압축 해제 모드 extension 에 따라 다른 데이터 rounding 룰을 적용한다. 압축기가 RGBA8 형태에 가장 최적의 rounding rule을 적용하게끔 하기 위해, RGBA8 형태로 압축 해제되게끔 할 텍스처들을 압축할 때 -decode_unorm8을 지정해 줄 수 있다. 이미지 퀄리티가 약간 향상된다.

(astcenc decomporessor가 컴포넌트당 8-bit인 아웃풋 이미지를 쓰게끔 했을 경우, 이 부분은 자동으로 enabled 된다)

Encoding non-correlated components

달느 텍스처 암축 포맷들은 예상되는 데이터 연관성에 따라 컴포넌트 적용 형태가 정해져 있다. 예를 들어, ETC2+EAC는 RGB가 항상 연관되어 있고, alpha는 연관성이 없는 것으로 간주한다. ASTC는 4개의 컴포넌트가 서로 완전히 연관되어 있거나, 혹은 서로 전혀 연관되어 있지 않은 1개의 컴포넌트를 나머지 3개와 연관없는 파티션에 자동으로 할당할 수 있다.

연관 없는 채널 1개는 블록 단위로 바뀔 수 있다. 따라서 압축기가 동적으로 이미지에 구현된 데이터를 바탕으로 압축 형태를 정한다. 이것은 연관 없는 데이터기 인풋 이미지의 어느 특정한 컴포넌트에 저장될 필요가 없음을 뜻한다.

그러나 몇몇 경우에서는 Alpha 컴포넌트가 RGB 컬러 컴포넌트와는 다르게 취급됨에 주목하자.

  • sRGB 이미지를 압축할 때 alpha component는 항상 선형 공간에 저장된다.
  • HDR 이미지를 압축할 때 alpha component는 선택적으로 LDR 데이터로 저장될 수 있다.

Encoding Normal Maps

ASTC에 노멀 맵을 저장하는 최선의 방법은 BC5와 비슷하다 -단위 길이의 벡터로 X와 Y 컴포넌트를

저장한다. 노멀의 Z 컴포넌트는 셰이더 코드에서 재구성된다.

컴포넌트 2개만 필요하기 때문에 rrrg coding swizzle 을 사용해 ASTC의 luminance + alpha(L+A) endpoint 에 정렬되도록 한다. 셰이더 코드에서는 .ga 로 sampling swizzle 한다. 이렇게 얻은 X, Y, 값으로 Z component값을 계산한다.

swizzle과 적절한 component weighting을 적용해 압축하는 것은 -normal 커맨드라인 옵션을 사용하면 된다. 만약 다른 컴포넌트 쌍을 사용하고 싶을 경우 -normal 파라미터 뒤에 커스텀 swizzle을 추가하면 된다. 예를 들어, BC5n 컴포넌트 순서를 사용하고 싶다면, normal -esw gggr 을 압축시에 사용하고 -normal -dsw arz1 을 압축 해제시에 사용하면 된다.

Encoding sRGB data

ASTC LDR profile은 sRGB로 인코딩된 컬러를 압축할 수 있고, 이것은 선형 공간으로 인코딩 된 컬러를 저장하는 것 보다 더 효율적으로 비트를 사용할 수 있다 - Gamma corrected 된 값 분포가 실제 인간의 밝기 인식에 더 가깝기 때문이다.

컬러 데이터에서는 sRGB 인풋 소스 텍스처를 사용하는 것이 시각적으로 퀄리티가 거의 항상 더 우수하다. (-cl 커맨드라인 옵션보다 -cs 커맨드라인 옵션을 사용해 압축하는 편이) sRGB 감마 코렉션은 압축 해제시에 RGB 컴포넌트에만 적용됨에 유의하자. alpha 컴포넌트는 항상 선형으로 압축된 데이터로 간주된다.

 

중요 : 압축되지 않은 인풋 텍스처는 -cs 커맨드 라인 옵션으로 sRGB 컬러 스페이스로 인코딩 되어야 정상 작동한다.