빠른 비교
| 방식 | 구조 | 강점 | 약점 |
|---|---|---|---|
| Texture atlas | 큰 2D texture 안에 여러 이미지 배치 | batching에 유리 | bleeding, UV 관리 필요 |
| Texture array | 같은 크기·포맷 texture를 layer로 저장 | layer 선택이 명확 | 크기와 포맷 통일 필요 |
| 개별 texture | 각 이미지가 독립 resource | 단순함 | binding과 state change 증가 |
atlas:
one texture, many UV rectangles
array:
one texture object, many layers구조
Texture atlas는 여러 작은 이미지를 하나의 큰 texture에 넣고, 각 sprite나 material이 자기 영역의 UV만 사용하도록 만드는 방식입니다. 같은 atlas를 쓰는 객체는 texture binding을 바꾸지 않아도 되므로 batching에 유리합니다.
atlas uv
u = rect.x + localU * rect.width
v = rect.y + localV * rect.heightTexture array는 여러 이미지를 같은 크기와 포맷의 layer로 저장합니다. shader는 UV와 함께 layer index를 넘겨 특정 slice를 샘플링합니다. atlas처럼 UV rectangle을 다시 계산하지 않아도 되지만, 모든 layer가 같은 해상도와 format 조건을 맞춰야 합니다.
mipmap과 bleeding
Atlas의 가장 흔한 문제는 경계 bleeding입니다. mipmap이나 bilinear filtering이 인접한 sprite의 픽셀을 섞어 읽으면 가장자리에 다른 이미지 색이 번집니다. 이를 줄이려면 padding, extrude border, UV inset을 사용합니다.
sprite padding
-> 가장자리 픽셀을 바깥으로 복제
-> mipmap에서 이웃 sprite 색이 섞이는 문제 완화Texture array는 layer끼리 filtering이 섞이지 않으므로 atlas bleeding이 덜합니다. 대신 서로 다른 크기의 이미지를 효율적으로 packing하는 데는 atlas가 더 유리할 수 있습니다.
선택 기준
| 상황 | 선택 |
|---|---|
| 2D sprite를 많이 그림 | texture atlas |
| 같은 크기 tile이 많음 | texture array |
| material별 이미지 크기가 제각각 | atlas 또는 개별 texture |
| mip bleeding이 문제 | padding 또는 texture array |
| draw call을 줄이고 싶음 | atlas/array로 binding 통합 |
| runtime streaming이 중요 | 개별 texture 또는 virtual texturing 검토 |
Atlas와 array는 texture binding 비용을 줄이는 장치입니다. fragment shader의 샘플 수나 texture bandwidth 자체를 없애지는 않습니다.
주의할 점
Texture atlas를 쓰면 UV가 원본 이미지 기준이 아니라 atlas 영역 기준으로 바뀝니다. sprite trim, rotation packing, padding이 섞이면 UV 생성과 shader sampling 규칙을 함께 관리해야 합니다.
Texture array는 layer 크기와 format이 같아야 하므로 다양한 해상도의 아트 리소스를 그대로 넣기 어렵습니다. batching 이득과 리소스 제작 제약을 같이 봐야 합니다.
참고 링크
2 sources