Arm에서 ASTC를 상세하게 설명해주는 문서가 있다.
https://github.com/ARM-software/astc-encoder/blob/main/Docs/FormatOverview.md
위 글을 천천히 읽어 보며, 정리해 보는 포스팅을 해보려고 한다.
ASTC는 분명 ETC2보다 개선된 압축방식이고, 같은 용량의 결과물이더라도 품질은 극명하게 차이가 난다.
왜 그런걸까? 그 몇년 사이에 압축 알고리즘이 비약적으로 상승한 것 때문일까?
이에 대한 답변이 확실히 될 수 있도록, 문서를 같이 읽어보자.
ASTC format overview
특징
포맷 유연성
ASTC는 1~4채널의 데이터 압축을 지원합니다.
RGB+A에서의 A채널과 같이, 상관관계가 없는 독립된 채널도 포함입니다.
비트레이트 유연성
ASTC 이전의 타입들은, 타입 당 비트레이트가 고정되어 있었습니다.
ETC2 RGBA인 경우 bit per texel 이 8인 식입니다.
하지만, ASTC는, bit per texel 이 8 (ASTC 4x4)부터, 0.89 (ASTC 12x12) 까지로 다양합니다.
확장된 포맷 지원
ASTC는 LDR (Low Dynamic Range) 뿐만 아니라,
LDR sRGB, HDR, 3D volumic 텍스처까지 모두 지원합니다.
향상된 이미지 품질
동일한 bit per texel 에서라도, 기존의 ETC2, PVRCT, BC 압축 텍스처보다 좋은 이미지 품질을 보여줍니다.
블럭 압축
렌더링을 위해서는, 메모리 데이터에서 특정 픽셀 위치로의 랜덤 엑세스가 가능해야 하므로,
가변 압축 대신 블럭 기반의 압축을 사용합니다.
ASTC는 한 블럭을 128bit의 데이터로 표현합니다.
대신, 4x4 px 를 한 블럭으로 다룰지, 12x12px 를 한 블럭으로 다룰 지, 압축할 때 선택할 수 있습니다.
이에 대해 설명이 조금 더 필요하다면,
혹은 PNG를 리소스 형식으로 쓰지 못하는 이유가 궁금하다면,
https://hotfoxy.tistory.com/116 이 글을 참고하세요!
색상 인코딩
블럭 인코딩 방식에서는, 색상 값의 표현을, 그라디언트를 이용해서 표현합니다.
위의 이미지에서와 같이, 블럭마다 색상의 시작 값과 끝 값을 정해 놓습니다.
이후, 블럭의 텍셀마다 weight값을 통해 gradient 에서의 위치를 통해 색상을 결정합니다.
하지만, 기존의 위 방식에는 문제가 있습니다.
예를 들어, 잔디밭에 빨간 공이 있다고 가정해 볼까요?
그렇다면, 위의 방식으로는 초록 색상들의 값도, 빨간 값도 정교하게 표현하기는 어려울 것입니다.
이를 해결하기 위해, ASTC는 파티셔닝 이라는 개념을 도입합니다.
위처럼 파티션을 초록 영역과 빨간 영역 두 개로 나누어서,
gradient를 각 파티션마다 개별적으로 적용시킬 수 있도록 했습니다.
덕분에, 초록 색상들의 미묘한 변화도, 빨간 색상의 미묘한 변화도 모두 표현 가능할 수 있게 되었습니다.
ASTC가 색상 경계선에서 확실한 성능 개선을 보여주는 주된 원인이, 위 파티셔닝입니다.
파티셔닝
한 블럭에 들어갈 색상 조합은 단순할 때도 있지만, 복잡할 때도 많습니다.
위에서 설명한 대로, ASTC는 파티셔닝을 사용하여 여러 개의 gradient 영역을 가질 수 있습니다.
ASTC는 이러한 파티셔닝을, 최대 4개까지 지원합니다.
아래는 ASTC 8x8 일 때의 파티셔닝 테이블입니다.
파티션이 2개일 때, 3개일 때, 4개일 때마다 어떤 형태로 나뉠 지를 테이블로 저장합니다.
위 이미지에서 볼 수 있다싶이, 파티셔닝은 2개 색상일때부터, 4개 색상일 때까지, 다양한 경우의 수를 가집니다.
하지만, 저 파티션 테이블 데이터를 블럭마다, 혹은 ASTC 압축 파일마다 가지게 한다면,
너무나도 큰 용량을 필요로 하게 됩니다.
따라서, ASTC를 지원하는 하드웨어,혹은 소프트웨어에서 저 파티션 테이블을 관리합니다.
ASTC의 각 블럭은 그렇기에, 파티션 테이블의 인덱스만 데이터로 가지고 있으면 됩니다.
위 이미지에서 볼 수 있다 싶이, 블럭마다 일부 비트를 파티션 인덱스를 저장하는데 사용하고 있습니다.
BISE 인코딩
기존 이진 인코딩
ASTC는 BISE라는 방식으로 데이터를 압축하여, 저장 공간을 효율적으로 사용합니다.
위 이미지는, 이진법을 사용할 때, alphabet 만큼으로 양자화된 값을 저장할 때, 낭비되는 비트 수입니다.
x가지 경우의 수를 이진 데이터로 저장하고 싶다면, log2(x) 만큼의 이진 저장소가 필요합니다.
예를 들어, 4가지의 경우의 수를 데이터로 표현하고 싶다면, 2비트 (2^2=4) 로 이를 저장할 수 있습니다.
하지만, 5가지의 경우의 수를 데이터로 표현하고 싶다면, log2(5), 약 2.32 비트가 필요합니다.
실제로는 올림하여 3비트를 사용할 수밖에 없기에, 약 22.3%의 비트 낭비를 보여주는 셈입니다.
블럭 내부의 gradient weight를 0, 0.25, 0.5, 0.75, 1.0 의 다섯 가지 종류로 관리한다면,
3비트가 할당될 것이고, 이는 22.3%의 비트 낭비를 유발하고 있는 것입니다.
BISE 인코딩
위 문제를 개선하기 위해, BISE는 이진법 뿐만 아니라,
삼진법 (trits), 오진법 (quints) 을 혼합하여 사용합니다.
위처럼 BISE 인코딩을 통하면, 기존 낭비되는 비트가 10~30% 였던 것에 비해, 월등히 개선됩니다.
따라서, 같은 128bit의 블럭일지라도, 기존의 압축타입보다 더 해상도 높은 데이터를 담고 있습니다.
정리
ASTC는 파티셔닝을 통해, 여러 개의 gradient를 지원합니다.
따라서 색상들의 경계가 더욱 명확해집니다.
ASTC는 BISE 인코딩을 사용합니다.
이로서 기존의 압축 타입보다 더 좋은 저장공간 효율을 보이고 있습니다.
'연구한 이야기 > 맡은 업무 이야기' 카테고리의 다른 글
드로우콜을 낮춰보자 (0) | 2024.09.01 |
---|---|
게임 서버 로그 처리하기 (0) | 2024.04.14 |
conan 패키지 관리자 도입하기 : 개론 (1) | 2024.02.04 |
Prometheus + Grafana 패키징 (0) | 2024.01.19 |
텍스처 압축과 ASTC (3) | 2024.01.14 |