입문 가이드

텍스처는 GPU 안에서 어떻게 될까

300 KB짜리 PNG가 어느새 그래픽 메모리 5 MB를 차지할 수 있습니다. 이 가이드는 그 이유와 GPU가 블록 압축으로 텍스처를 줄이는 방법, 그리고 포맷을 고르는 방법을 설명합니다. 모든 개념에는 직접 해 볼 수 있는 데모가 있습니다.

약 10분인터랙티브 데모 5개
읽기 시작

1장

파일 크기는 메모리 크기가 아니다

PNG와 JPEG는 이미지를 저장하고 전송하기 위한 형식입니다. GPU가 텍스처를 그리기 전에 이미지는 원시 텍셀로 풀리며, 보통 텍셀당 4바이트를 씁니다.

GPU는 프레임마다 이 텍셀을 수백만 번 샘플링하므로 언제든 읽을 수 있어야 합니다. 그래서 메모리 사용량은 해상도와 픽셀 형식으로만 정해지고, 파일이 얼마나 잘 압축됐는지와는 관계가 없습니다. 먼 표면에 쓰는 축소본인 밉맵을 더하면 약 3분의 1이 늘어납니다.

직접 해 보기그래픽 메모리 계산기해상도와 텍스처 수를 바꿔 같은 텍스처가 포맷별로 GPU 메모리를 얼마나 쓰는지 확인해 보세요.
해상도
  • RGBA8
    텍셀당 32비트
    213 MiB
    기준
    텍스처당 21.3 MiB
  • BC7 · ASTC 4×4
    텍셀당 8비트
    53.3 MiB
    4배 작음
    텍스처당 5.3 MiB
  • BC1 · ETC2 RGB
    텍셀당 4비트
    26.7 MiB
    8배 작음
    텍스처당 2.7 MiB
  • ASTC 6×6
    텍셀당 3.56비트
    23.8 MiB
    9배 작음
    텍스처당 2.4 MiB
  • ASTC 8×8
    텍셀당 2비트
    13.3 MiB
    16배 작음
    텍스처당 1.3 MiB
  • ASTC 12×12
    텍셀당 0.89비트
    6 MiB
    35.7배 작음
    텍스처당 612 KiB

블록 포맷은 모든 밉 레벨에서 완전한 블록 단위로 올림하므로, GPU가 실제로 할당하는 양과 같습니다.

2장

GPU가 PNG를 그대로 쓸 수 없는 이유

셰이더가 텍스처를 샘플링할 때는 어떤 텍셀을 어떤 순서로 요청할지 모릅니다. 하드웨어는 그 텍셀을 즉시 찾아야 합니다.

PNG와 JPEG는 가변 길이 부호화를 쓰기 때문에, 중간의 픽셀을 읽으려면 그 앞을 모두 디코딩해야 합니다. GPU 포맷은 고정 비율이라 모든 4×4 블록이 정확히 같은 바이트 수를 씁니다. 그래서 어떤 텍셀의 주소든 곱셈 한 번으로 구할 수 있습니다. 텍스처는 메모리 안에서 압축된 상태로 유지되고, 텍스처 유닛이 읽을 때 블록을 디코딩합니다.

직접 해 보기텍셀 찾기이 32×32 텍스처의 아무 텍셀이나 클릭해 보세요. 블록 포맷은 저장 위치를 계산할 수 있지만 PNG는 그렇지 못합니다.

방향키로 선택 위치를 옮길 수 있습니다.

선택한 텍셀
x 13, y 18
속한 블록
3열, 4행
BC1에서의 주소
(4 × 8 + 3) × 8바이트 = 280번째 바이트

메모리에 놓인 64개 블록

0511

PNG에서 같은 텍셀을 읽으려면

먼저 0행부터 18행까지 압축을 풀어야 함(32행 중 19행)

3장

4×4 블록 들여다보기

가장 오래 널리 쓰여 온 BC1이 원리를 가장 잘 보여 줍니다. 16개 텍셀로 된 블록을 단 8바이트에 담습니다.

인코더는 두 개의 끝점 색상을 고릅니다. 디코더는 이 둘을 섞어 직선 위의 네 가지 색을 만들고, 각 텍셀은 가장 가까운 색을 가리키는 2비트 번호만 저장합니다. 색이 부드럽게 변하는 블록은 잘 보존되지만, 서로 관계없는 색이 섞인 블록은 망가집니다.

직접 해 보기BC1 블록 탐색기샘플 텍스처에서 4×4 블록을 골라 BC1이 그것을 정확히 어떻게 저장하는지 살펴보세요.
블록 12, 4

4장

포맷마다 다른 절충

새로운 포맷은 BC1보다 비트를 더 영리하게 씁니다. 끝점을 늘리거나, 블록 안에 여러 색상 선을 두거나, 알파를 개선하거나, 블록 크기를 고를 수 있게 합니다.

BC7과 ASTC 4×4는 텍셀당 8비트로 원본에 가깝게 보입니다. ASTC는 블록 크기로 품질과 크기를 조절합니다. 블록은 항상 128비트이므로 12×12 블록은 텍셀당 1비트도 되지 않습니다. Basis Universal은 다른 방식을 씁니다. 작은 파일 하나만 배포하고, 기기에서 그 GPU가 지원하는 포맷으로 트랜스코딩합니다.

주요 GPU 텍스처 포맷
포맷텍셀당 비트알파주요 플랫폼적합한 용도
BC141비트데스크톱, 콘솔메모리가 빠듯할 때의 불투명 색상
BC38지원데스크톱, 콘솔오래된 콘텐츠의 부드러운 알파 포함 색상
BC44데이터 채널데스크톱, 콘솔단일 채널: 마스크, 러프니스, 높이
BC58데이터 채널데스크톱, 콘솔노멀 맵 (X와 Y)
BC6H8미지원데스크톱, 콘솔스카이박스, 라이트맵 같은 HDR 색상
BC78지원데스크톱, 콘솔알파 유무와 상관없는 고품질 색상
ETC14미지원거의 모든 Android아주 오래된 기기의 불투명 색상
ETC24–8지원Android, iOS폭넓게 지원되는 모바일 대체 포맷
ASTC0.89–8지원최신 Android와 iOS, Apple Silicon모바일에서 조절 가능한 품질
PVRTC2–4지원구형 iPhone과 iPad구형 Apple 기기 전용
Basis ETC1S변환 대상에 따라 다름지원모든 GPU (KTX2 사용)작은 다운로드, 모든 GPU에서 동작
Basis UASTC변환 대상에 따라 다름지원모든 GPU (KTX2 사용)높은 품질, 모든 GPU에서 동작
직접 해 보기실제 인코더 실행하기이 사이트의 도구와 같은 WebAssembly 인코더로 512×512 샘플을 압축하고, 확대한 부분을 비교합니다.
브라우저 안에서 실행되며 아무것도 업로드되지 않습니다.
확대할 영역
원본
RGBA8
GPU 메모리 1 MiB
BC1
BC1
텍셀당 4비트
GPU 메모리 128 KiB
BC7
BC7
텍셀당 8비트
GPU 메모리 256 KiB
ASTC 6×6
ASTC 6×6
텍셀당 3.56비트
GPU 메모리 116 KiB
ASTC 12×12
ASTC 12×12
텍셀당 0.89비트
GPU 메모리 29 KiB

“인코더 실행”을 누르면 샘플을 압축합니다. 처음 실행할 때 인코더를 내려받습니다.

5장

포맷 고르기

두 가지 질문이면 선택지가 빠르게 좁혀집니다. 어떤 GPU가 이 텍스처를 불러와야 하는지, 그리고 어떤 데이터가 들어 있는지.

색상 텍스처, 노멀 맵, 단일 채널 마스크는 압축에 반응하는 방식이 다르고, 데스크톱·모바일·웹 플랫폼은 지원하는 포맷 계열이 다릅니다. 자신의 경우를 골라 출발점을 정한 다음, 실제 텍스처로 결과를 확인하세요.

직접 해 보기포맷 선택기텍스처가 실행될 곳과 담긴 내용을 고르세요.
어디에서 실행되나요?
텍스처에 무엇이 들어 있나요?

먼저 써 볼 포맷

ASTC 6×6

함께 고려할 포맷: ASTC 4×4 · ETC2 RGB

ASTC는 최신 Android와 iOS GPU에서 동작합니다. 6×6이 균형이 좋고, 핵심 에셋에는 4×4, 오래된 기기에는 ETC2를 쓰세요.

ASTC 인코더 열기

6장

실전 팁

몇 가지 습관만으로 대부분의 텍스처 압축 문제를 막을 수 있습니다.

  1. 01

    색상은 sRGB, 데이터는 선형으로

    알베도와 UI 텍스처는 sRGB입니다. 노멀, 러프니스 같은 데이터 맵은 선형으로 두어야 조명이 올바르게 계산됩니다.

  2. 02

    노멀 맵에는 전용 포맷을

    BC5나 EAC RG11 같은 2채널 포맷을 쓰고 Z는 셰이더에서 복원하세요. 색상 포맷은 비트를 낭비하고 눈에 띄는 요철을 만듭니다.

  3. 03

    밉맵 생성하기

    메모리가 약 33% 늘지만, 먼 표면의 깜빡임을 막고 샘플링도 빨라집니다.

  4. 04

    크기는 블록 단위에 맞추기

    대부분의 포맷은 4×4 블록 단위이므로 4로 나누어떨어지는 크기면 패딩이 필요 없습니다. PVRTC 같은 오래된 포맷은 정사각형이면서 2의 거듭제곱 크기여야 합니다.

  5. 05

    실제 콘텐츠를 실제 기기에서 확인하기

    원본 크기로 확대해 디코딩 결과와 원본을 비교하고, 대상 GPU가 그 포맷을 지원하는지 확인하세요.

자주 묻는 질문

GPU 텍스처 압축은 무손실인가요?

아닙니다. BC, ETC, ASTC, PVRTC는 블록마다 크기가 고정된 손실 포맷입니다. 품질이 얼마나 떨어지는지는 포맷, 블록 크기, 이미지에 따라 다릅니다.

PNG나 JPEG를 텍스처로 바로 쓰면 안 되나요?

다운로드는 빠르지만 GPU가 직접 샘플링할 수 없어서 원시 텍셀로 디코딩되고 메모리를 전부 차지합니다. GPU 포맷은 메모리 안에서도 작게 유지됩니다.

어떤 텍스처 포맷이 가장 좋나요?

데스크톱에서는 BC7, 최신 모바일 기기에서는 ASTC가 무난한 기본값입니다. 웹처럼 파일 하나가 여러 GPU에서 동작해야 한다면 KTX2와 Basis Universal을 쓰세요.

텍셀당 비트는 무슨 뜻인가요?

텍셀 하나에 드는 평균 저장 비용입니다. 원시 RGBA8은 32비트, BC1은 4비트, BC7은 8비트이고, ASTC는 블록 크기에 따라 8비트에서 약 0.89비트까지 내려갑니다.

내 텍스처로 직접 해 보세요

모든 인코더는 브라우저 안에서 로컬로 실행됩니다. PNG나 JPEG를 올리고 포맷을 골라 결과를 비교해 보세요.