Przewodnik dla początkujących
Co dzieje się z teksturą wewnątrz GPU
PNG o rozmiarze 300 KB może po cichu zająć 5 MB pamięci graficznej. Ten przewodnik pokazuje, dlaczego tak się dzieje, jak GPU zmniejszają tekstury dzięki kompresji blokowej i jak wybrać format. Każdemu pomysłowi towarzyszy coś, co możesz wypróbować.
Rozdział 1
Rozmiar pliku to nie rozmiar w pamięci
PNG i JPEG służą do przechowywania i przesyłania obrazów. Zanim GPU narysuje teksturę, obraz zostaje rozpakowany do surowych tekseli, zwykle po 4 bajty każdy.
GPU próbkuje te teksele miliony razy na klatkę, więc muszą być gotowe do odczytu. Dlatego zużycie pamięci zależy tylko od rozdzielczości i formatu pikseli, a nie od tego, jak dobrze skompresowano plik. Mipmapy, czyli pomniejszone kopie dla odległych powierzchni, dokładają około jednej trzeciej.
- RGBA832 bitów na teksel213 MiBPunkt odniesienia21,3 MiB na teksturę
- BC7 · ASTC 4×48 bitów na teksel53,3 MiB4× mniej5,3 MiB na teksturę
- BC1 · ETC2 RGB4 bitów na teksel26,7 MiB8× mniej2,7 MiB na teksturę
- ASTC 6×63,56 bitów na teksel23,8 MiB9× mniej2,4 MiB na teksturę
- ASTC 8×82 bitów na teksel13,3 MiB16× mniej1,3 MiB na teksturę
- ASTC 12×120,89 bitów na teksel6 MiB35,7× mniej612 KiB na teksturę
Formaty blokowe są zaokrąglane w górę do pełnych bloków na każdym poziomie mip, więc liczby odpowiadają temu, co faktycznie przydziela GPU.
Rozdział 2
Dlaczego GPU nie może trzymać PNG
Gdy shader próbkuje teksturę, może zażądać dowolnego teksela w dowolnej kolejności. Sprzęt musi go znaleźć natychmiast.
PNG i JPEG używają kodowania o zmiennej długości: aby dotrzeć do piksela w środku, trzeba najpierw zdekodować wszystko, co jest przed nim. Formaty GPU mają stałą przepływność: każdy blok 4×4 zajmuje dokładnie tyle samo bajtów, więc adres dowolnego teksela to proste mnożenie. Tekstura pozostaje skompresowana w pamięci, a jednostka teksturująca dekoduje bloki w trakcie odczytu.
Użyj strzałek, aby przesunąć zaznaczenie.
- Wybrany teksel
- x 13, y 18
- Jego blok
- kolumna 3, wiersz 4
- Adres w BC1
- (4 × 8 + 3) × 8 bajtów = bajt 280
64 bloki w kolejności w pamięci
Ten sam teksel w PNG
Najpierw trzeba rozpakować wiersze od 0 do 18 (19 z 32)
Rozdział 3
Wnętrze bloku 4×4
BC1, najstarszy powszechnie używany format, najlepiej pokazuje tę ideę. Zapisuje blok 16 tekseli w zaledwie 8 bajtach.
Koder wybiera dwa kolory końcowe. Dekoder miesza je w cztery kolory leżące na prostej, a każdy teksel przechowuje 2-bitowy numer wskazujący najbliższy z nich. Bloki z łagodnymi zmianami koloru zachowują się dobrze; bloki mieszające kilka niezwiązanych kolorów – nie.
Rozdział 4
Wiele formatów, różne kompromisy
Nowsze formaty wykorzystują bity sprytniej niż BC1: więcej punktów końcowych, kilka linii kolorów w bloku, lepsza alfa albo wybór rozmiaru bloku.
BC7 i ASTC 4×4 używają 8 bitów na teksel i wyglądają bardzo podobnie do oryginału. ASTC wymienia jakość na rozmiar przez rozmiar bloku: blok ma zawsze 128 bitów, więc blok 12×12 kosztuje mniej niż jeden bit na teksel. Basis Universal idzie inną drogą: dostarcza jeden kompaktowy plik i transkoduje go na urządzeniu do formatu obsługiwanego przez dany GPU.
| Format | Bity na teksel | Alfa | Typowe platformy | Najlepszy do |
|---|---|---|---|---|
| BC1 | 4 | 1 bit | Desktop, konsole | Nieprzezroczysty kolor przy małej ilości pamięci |
| BC3 | 8 | Tak | Desktop, konsole | Kolor z łagodną alfą w starszych materiałach |
| BC4 | 4 | Kanały danych | Desktop, konsole | Jeden kanał: maski, chropowatość, wysokość |
| BC5 | 8 | Kanały danych | Desktop, konsole | Mapy normalnych (X i Y) |
| BC6H | 8 | Nie | Desktop, konsole | Kolor HDR, np. skyboxy i lightmapy |
| BC7 | 8 | Tak | Desktop, konsole | Kolor wysokiej jakości, z alfą lub bez |
| ETC1 | 4 | Nie | Prawie każdy Android | Nieprzezroczysty kolor na bardzo starych urządzeniach |
| ETC2 | 4–8 | Tak | Android, iOS | Szeroko obsługiwany zapasowy format mobilny |
| ASTC | 0.89–8 | Tak | Nowsze Androidy i iOS, Apple Silicon | Regulowana jakość na urządzeniach mobilnych |
| PVRTC | 2–4 | Tak | Starsze iPhone’y i iPady | Tylko starsze urządzenia Apple |
| Basis ETC1S | Zależy od formatu docelowego | Tak | Dowolny GPU, przez KTX2 | Małe pobieranie, działa na każdym GPU |
| Basis UASTC | Zależy od formatu docelowego | Tak | Dowolny GPU, przez KTX2 | Wysoka jakość, działa na każdym GPU |
Kliknij „Uruchom kodery”, aby skompresować próbkę. Przy pierwszym uruchomieniu kodery zostaną pobrane.
Rozdział 5
Jak wybrać format
Dwa pytania szybko zawężają wybór: które GPU muszą wczytać teksturę i jakie dane ona zawiera?
Tekstury kolorów, mapy normalnych i jednokanałowe maski różnie reagują na kompresję, a platformy desktopowe, mobilne i webowe obsługują różne rodziny formatów. Wybierz swój przypadek, aby dostać rozsądny punkt wyjścia, a potem sprawdź wynik na własnych teksturach.
Zacznij od
ASTC 6×6
Rozważ też: ASTC 4×4 · ETC2 RGB
ASTC działa na nowszych GPU z Androidem i iOS. 6×6 to dobry kompromis; użyj 4×4 dla kluczowych zasobów i ETC2 dla starszych urządzeń.
Otwórz koder ASTCRozdział 6
Praktyczne wskazówki
Kilka nawyków zapobiega większości problemów z kompresją tekstur.
- 01
Oznaczaj kolor jako sRGB, a dane jako liniowe
Tekstury albedo i UI są w sRGB. Mapy normalnych, chropowatości i inne dane muszą pozostać liniowe, inaczej oświetlenie będzie błędne.
- 02
Daj mapom normalnych osobny format
Używaj formatów dwukanałowych, takich jak BC5 lub EAC RG11, i odtwarzaj Z w shaderze. Formaty kolorów marnują bity i dodają widoczne nierówności.
- 03
Generuj mipmapy
Zwiększają zużycie pamięci o około 33%, ale zapobiegają migotaniu odległych powierzchni i przyspieszają próbkowanie.
- 04
Dobieraj wymiary pod bloki
Większość formatów działa na blokach 4×4, więc rozmiary podzielne przez 4 nie wymagają dopełniania. Starsze formaty, takie jak PVRTC, wymagają też kwadratowych rozmiarów będących potęgą dwójki.
- 05
Sprawdzaj prawdziwe materiały na prawdziwych urządzeniach
Porównaj zdekodowany wynik z oryginałem w pełnym powiększeniu i upewnij się, że docelowe GPU obsługują dany format.
Najczęstsze pytania
Czy kompresja tekstur GPU jest bezstratna?
Nie. BC, ETC, ASTC i PVRTC to formaty stratne ze stałym rozmiarem bloku. Ile jakości się traci, zależy od formatu, rozmiaru bloku i obrazu.
Dlaczego nie używać bezpośrednio tekstur PNG lub JPEG?
Szybciej się pobierają, ale GPU nie potrafi ich próbkować, więc są dekodowane do surowych tekseli i zajmują pełną pamięć. Formaty GPU pozostają małe także w pamięci.
Który format tekstur jest najlepszy?
BC7 to dobry domyślny wybór na desktopie, ASTC na nowszych urządzeniach mobilnych, a KTX2 z Basis Universal, gdy jeden plik musi działać na wielu GPU, np. w sieci.
Co oznacza liczba bitów na teksel?
To średni koszt zapisu jednego teksela. Surowe RGBA8 używa 32 bitów, BC1 4, BC7 8, a ASTC od 8 do około 0,89 w zależności od rozmiaru bloku.
Wypróbuj na własnych teksturach
Wszystkie kodery działają lokalnie w przeglądarce. Prześlij PNG lub JPEG, wybierz format i porównaj wynik.