Dlaczego tekstury są zawsze kwadratowymi potęgami dwóch? Co jeśli nie są?

53

Dlaczego rozdzielczość tekstur w grach jest zawsze potęgą dwóch (128x128, 256x256, 512x512, 1024x1024 itd.)? Czy nie byłoby mądrze zaoszczędzić na rozmiarze pliku gry i dopasować teksturę dokładnie do modelu bez opakowania UV?

Co by się stało, gdyby istniała tekstura, która nie byłaby potęgą dwóch?

Czy niepoprawne byłoby mieć teksturę taką jak 256 x 512 lub 512 x 1024? A może spowodowałoby to problemy, które mogą powodować inne niż potęgi tekstury?

Keavon
źródło
9
Twoje pozostałe przykłady to także potęgi dwóch, ale nie ta sama potęga dwóch. Potęga dwóch sprawia, że ​​tekstura jest zoptymalizowana pod kątem sprzętu graficznego.
MichaelHouse
1
@ Byte56 Myślę, że ma na myśli teksturę 2 ^ nx 2 ^ n, gdzie n zmienia się od 1 do nieskończoności. (Niezupełnie nieskończony.)
Robin
Zauważ także, że potęgi dwóch mają tę zaletę, że mipmapy są trywialne.
Pubby
Ponieważ tekstura zwykle się zawija (chociaż możesz to wybrać w niestandardowym module cieniującym), nie musisz marnować miejsca, po prostu owiń współrzędne UV wielokątów wokół krawędzi i możesz znacznie łatwiej wykorzystać dostępną przestrzeń. Jeśli nie potrzebujesz tłoczenia, najbezpieczniej jest trzymać tekstury o szerokości = wysokość = 2 ^ n, ponieważ pozwoli to na szerszy zakres sprzętu kosztem nieco bardziej skomplikowanego układu UV.
Daniel Carlsson
Nie zawsze są potęgami dwojga.
Almo

Odpowiedzi:

49

Dlaczego rozdzielczość tekstur w grach jest zawsze potęgą dwóch (128x128, 256x256, 512x512, 1024x1024 itd.)?

Jak sugeruje Byte56, ograniczenia wielkości „potęgi dwóch” są (były), że każdy wymiar musi być niezależnie potęgą dwóch, nie zaś tekstury muszą być kwadratowe i mieć wymiary, które są potęgą dwóch.

Jednak w przypadku nowoczesnych kart i interfejsów API współczesnej grafiki to „ograniczenie” zostało znacznie złagodzone, dzięki czemu wymiary tekstur mogą, z uzasadnionego powodu, być czymkolwiek innym. Jednak:

Czy nie byłoby mądrze zaoszczędzić na rozmiarze pliku gry i dopasować teksturę dokładnie do modelu bez opakowania UV? Co by się stało, gdyby istniała tekstura, która nie byłaby potęgą dwóch?

Zapewniając, że wymiary tekstury są potęgą dwóch, potok graficzny może korzystać z optymalizacji związanych z wydajnością pracy z potęgami dwóch. Na przykład może być (i absolutnie było kilka lat temu, zanim mieliśmy dedykowane układy GPU i niezwykle sprytne kompilatory optymalizujące) szybciej dzielić i mnożyć przez potęgę dwóch. Praca w potęgach dwóch również uproszczonych operacji w potoku, takich jak obliczanie i użycie mipmap (liczba, która jest potęgą dwóch, zawsze dzieli się równo na pół, co oznacza, że ​​nie musisz zajmować się scenariuszami, w których musisz zaokrąglić wymiary mipmapy w górę lub w dół).

To prawda, że ​​„marnujesz” trochę miejsca w ten sposób, ale dodatkowa przestrzeń jest zwykle tego warta na kompromis w wydajności renderowania. Ponadto istnieją techniki, takie jak kompresja lub pakowanie wielu obrazów w jedną przestrzeń tekstur, które mogą złagodzić część odpadów związanych z przechowywaniem.

Josh
źródło
11
„To prawda, że„ marnujesz ”w ten sposób trochę miejsca, ale dodatkowe miejsce zwykle jest tego warte, aby obniżyć wydajność renderowania.” - Około dziesięć lat temu pracowałem w studiu, które przenosiło grę PS2 na XBox. Chociaż PS2 technicznie nie obsługuje tekstur innych niż potęga dwóch, w niektórych przypadkach możesz zmusić go do tego przy odrobinie sprytnej manipulacji i bez utraty prędkości. Z drugiej strony XBox całkowicie ich nie obsługiwał. Ostateczny wynik jest taki, że pomimo tego, że XBox ma prawie dwa razy więcej pamięci RAM niż PS2, musieliśmy przeskalować niektóre tekstury, aby dopasować.
ZorbaTHut
Trudno mi znaleźć cytat, ale wcześniej przeczytałem, że obrazy JPEG powinny być wielokrotności 8, aby uzyskać maksymalną wydajność, ponieważ wszystko poza tym nadal wymaga bloku 8x8.
łosoś łososiowy
1
@salmonmoose: Poprawnie; JPEG kompresuje każdy blok 8x8 niezależnie i wstawia bloki na krawędzi. Ale to nie ma związku z tym pytaniem.
MSalters
1
Pliki JPEG są kodowane w blokach 8x8, tak. Jednak nie jest to tak naprawdę kwestia wydajności. I niekoniecznie jest to również potęga 2. :)
Kylotan
Przykładem jest system Android, w którym często nie-poweroftwo tekstury powodują białe tekstury.
user717572,
17

Dlaczego tekstury są zawsze kwadratowymi potęgami dwóch?

Tekstury nie są zawsze kwadratowe nie są one zawsze potęgami dwójki . Powodem, dla którego zwykle są potęgami dwóch, jest zwykle zwiększenie kompatybilności ze starszymi kartami wideo, które narzuciły to ograniczenie. Co do tekstur nie kwadratowych, zwykle nie stanowi to problemu. Podsumowując:

  • Tekstury zwykle nie muszą być kwadratowe - chociaż DirectX ma taką D3DPTEXTURECAPS_SQUAREONLYmożliwość, ale pracowałem z teksturami nie kwadratowymi nawet na starszym sprzęcie bez żadnych problemów.
  • Tekstury powinny mieć potęgę dwóch, ponieważ wiele starszych kart graficznych wciąż tego wymaga. Powodem tego ograniczenia było to, że mogli dokonać pewnych optymalizacji operacji mapowania tekstur. Większość współczesnych kart graficznych również nie ma tego ograniczenia.
David Gouveia
źródło
12
Należy zauważyć, że przez „starsze karty graficzne” rozumie on rzeczy wykonane przed około 2006 rokiem.
Nicol Bolas
1
@NicolBolas Dzięki, naprawdę starałem się znaleźć jakieś referencje na ten temat.
David Gouveia
7

Dotyczy optymalizacji kart graficznych. Zostały zaprojektowane do przetwarzania ich w ten sposób. Większość kart w tych dniach będzie pozwalają na załadowanie tekstur o wymiarach, które nie są potęgami dwójki, ale to będzie prawdopodobnie mieć negatywny wpływ na wydajność. Istnieje duża szansa, że ​​kiedy się załaduje, faktycznie zostanie przekonwertowany, co kosztuje czas ładowania i nie oszczędza żadnej pamięci. Tekstury niekwadratowe są ogólnie OK, o ile oba ich wymiary są potęgami dwóch.

Jednym ze sposobów radzenia sobie z teksturami o nieparzystych rozmiarach jest użycie Atlasu Tekstur . Zasadniczo umieszczasz wiele tekstur razem w jednej teksturze i używasz współrzędnych tekstury swoich wierzchołków, aby odnieść się do konkretnego obrazu, którego potrzebujesz. Ma to również dodatkowe zalety w zakresie wydajności, ponieważ pozwala uniknąć zmian stanu. Powszechnym zastosowaniem tego jest umieszczenie wszystkich elementów interfejsu w jednej teksturze, co oznacza, że ​​jeśli zestawiłeś wierzchołki interfejsów w jeden obiekt buforowy, możesz narysować całość za pomocą jednego wywołania, zamiast przełączać tekstury wiele razy i osobne sprawdzenie losowania dla każdego z nich.

Jason Morales
źródło
6

Problem polega na tym, że niektóre urządzenia mają ograniczoną obsługę tekstur, które nie mają mocy dwóch wymiarów.

Na przykład spójrz na dół http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876%28v=vs.85%29.aspx i przeczytaj tam przypisy 3 i 4.

3 Na poziomach funkcji 9_1, 9_2 i 9_3 urządzenie wyświetlające obsługuje tekstury 2-D o wymiarach, które nie są potęgami dwóch w dwóch warunkach. Po pierwsze, można utworzyć tylko jeden poziom mapy MIP dla każdej tekstury, a po drugie, nie są dozwolone żadne tryby próbkowania zawijania dla tekstur (to znaczy, że członkowie AddressU, AddressV i AddressW członków D3D11_SAMPLER_DESC nie mogą być ustawione na D3D11_TEXTURE_ADDRESS_WRAP).

4 Na poziomach funkcji 10_0, 10_1 i 11_0 urządzenie wyświetlające bezwarunkowo obsługuje użycie tekstur 2-D o wymiarach, które nie są potęgami dwóch.

Adam
źródło
6

Sprzęt graficzny jest zoptymalizowany do operacji matrycowych, fragmentarycznych i wektorowych. Po prostu matryce kwadratowe są łatwiejsze w obsłudze, ponieważ obliczenia mogą być wykonywane w blokach (zwanych fragmentami), sprzęt jest zoptymalizowany do operacji na blokach, dlatego istnieją rzeczy takie jak bufory plików, blit RAM nie łączy się z dyskiem aż do bloku został zaludniony. To samo dotyczy pamięci graficznej.

Bufor ramki składa się z kwadratowych fragmentów. Na przykład na ekranie o rozdzielczości 800 x 600 i przestrzeni kolorów RGB (0–255) jest 800 x 600 punktów z 3 bajtami na każdym kanale, w sumie 3 x 800 x 600 = 1 440 000 bajtów do zaadresowania w buforze ramki. Oznacza to, że istnieje 1875 adresowalnych fragmentów o rozmiarze 256 x 256 x 3 bajtów. Ponieważ dane tekstury są kwadratowe, znacznie ułatwia mapowanie z macierzy GRAM do macierzy bufora ekranowego przy użyciu skalowania dwubiegunowego, przy czym tak, jakby to nie było kwadratowe, odchylenie dla dłuższej strony zajęłoby więcej czasu, aby obliczyć, kiedy trzeba być skalowanym.

Wiele graficznych interfejsów API akceptuje dane kwadratowych tekstur, ponieważ akceptuje współrzędne mapowania UV jako dane zmiennoprzecinkowe, jednak po wysłaniu do GPU dopełnienie jest dodawane do danych tekstur, ponieważ rzeczywiste proporcje obrazu nie zmieniają mapowania wydaje się niezmieniony, jednak do danych tekstury dodaje się dopełnianie, ponieważ GPU lubi traktować to jako idealny kwadrat.

Więc jeśli użyty zostanie obraz 100x1024, a użyty zostanie obraz 1024x1024, to znaczy zmarnuje się 946,176 bajtów. Tym bardziej, jeśli kompozycja ma być wykonana, ponieważ trzeba będzie dodać kanał alfa, aby wskazać, że dane wypełnienia nie powinny wpływać na teksturę złożoną.

awiebe
źródło
To ciekawe wyjaśnienie (titbit o macierzach kwadratowych), którego nie ma w zwykłej sile 2 odpowiedzi (+1) - czy możesz podać jakieś cytaty, jeśli to możliwe?
Samaursa
1

Nasz cyfrowy świat pracuje z numeracją binarną, a następnie do wielokrotnego grania lub dzielenia przez 2 wartości, którą można „przenieść” w lewo lub w prawo, tj.

<<  Left shift      x = 5 << 1    0101 << 1     1010     10
>>  Right shift     x = 5 >> 1    0101 >> 1     0010      2

Praca z wartościami „potęga dwóch” jest łatwiejsza dla procesora.

esdebon
źródło
0

Nowoczesny sprzęt może (w końcu) poradzić sobie z włączeniem trybów zawijania przy braku zasilania dwóch bazujących tekstur, jednak brak zasilania dwóch tekstur nadal ma tendencję do marnowania pamięci GPU, ponieważ mają one tendencję do zwiększania się wzdłuż szerokości o pewną określoną ilość sprzętu (albo do jakiegoś rozmiaru kafelka lub w zaokrągleniu do następnej potęgi dwóch rozmiarów, która zawiera teksturę).

Ponieważ jest to zależne od sprzętu, a dostawcy zazwyczaj nie zajmują się szczegółami tych szczegółów, najbezpieczniej jest nadal używać mocy dwóch wymiarów do tekstur, aby nie marnować pamięci RAM.

Strefa
źródło