Czy renderowanie szczegółowej tekstury trwa dłużej?

22

Powiedzmy, że chcę wyrenderować kwadrat; jego tekstura to „square.png”.

Czy komputerowi łatwiej jest to wyrenderować, jeśli tekstura jest po prostu jednolitym kolorem?

A jeśli to bardzo hałaśliwa faktura z przypadkowymi kolorami tu i tam?

A co, jeśli ta tekstura jest głośna w tym sensie, że każdy piksel różni się między sobą, ale tylko nieznacznie?

użytkownik3491043
źródło

Odpowiedzi:

39

Jak większość rzeczy w tworzeniu gier, a zwłaszcza w grafice gier, odpowiedź brzmi „to zależy”

Rozmiar tekstury

Rozdzielczość tekstury może mieć wpływ na szybkość renderowania. Im więcej pikseli zawiera, tym więcej surowych danych ma zostać przesłanych do GPU, i tym mniej tekstury możemy zmieścić w pamięci podręcznej na raz, więc moduł cieniujący może trafić w więcej przerw podczas oczekiwania na odpowiednią część tekstury zostać wciągniętym do pamięci podręcznej.

Użycie mipmapowania może zmniejszyć jego wpływ. Dzięki mipmaps przechowujemy ciąg zmniejszonych wersji tekstury, które na początku brzmią jak jeszcze więcej pamięci. Ale pozwala nam czytać z mniejszych wersji, gdy tekstura jest wyświetlana na ekranie w małym rozmiarze (jak odległy obiekt w perspektywie), więc nasze próbki lepiej wykorzystują pamięć podręczną tekstur, zamiast przeskakiwać. Zmniejsza to również aliasing.

Szczegółowości tekstur

Zawartość twoich tekstur przez większość czasu nie wpływa na wydajność renderowania.

Kolor to po prostu kilka liczb, jeśli chodzi o GPU, więc nie obchodzi go, jakie są te liczby, po prostu rozprowadza je po matematyce w ten sam sposób. Nie robi nic wymyślnego, jak zapamiętywanie „Och, widziałem wcześniej piksel w tej zieleni, po prostu użyję ponownie tego samego wyniku, który obliczyłem, kiedy widziałem to wejście”, więc czy twoja tekstura jest w jednym kolorze lub losowo błyszczy, twój procesor graficzny wykonuje tę samą pracę.

W przeciwieństwie do formatów takich jak PNG i JPG, które kompresują się bardziej efektywnie w przewidywalnych obszarach obrazu i pochłaniają więcej bitów w złożonych regionach, formaty tekstur GPU, takie jak BTC, ETC, PVRTC, a nawet surowe RGBA używają stałej liczby bitów na blok piksele. Zatem uszczegółowienie tekstury przy zachowaniu tego samego formatu kompresji nie zmieni rozmiaru danych ani nie wpłynie na transfer danych i wydajność związaną z pamięcią podręczną.

Ale jeśli użyjesz określonego rodzaju szczegółów, których poprzednia kompresja nie zachowuje dobrze, możesz zostać zmuszony do zmiany całego obrazu, aby użyć innego formatu, co może ponownie zmienić jego rozmiar danych.

Shader Rozgałęzienie i przekierowanie

Oto największa gwiazdka w tej sytuacji: być może używasz tego koloru tekstury do podejmowania decyzji, jak if()gałąź. Tutaj szczegóły mają znaczenie dla prędkości.

Jednostki cieniujące GPU działają na blokach pikseli w partiach, uruchamiając te same instrukcje równolegle na wielu strumieniach danych. Tak więc, gdy niektóre piksele w bloku biorą jedną gałąź ifdrugiego, a inne piksele biorą drugi, cała partia musi przejść przez obie gałęzie (maskowanie wyników, które nie dotyczą jednego zestawu pikseli lub drugiego)

Jeśli dane wejściowe zmieniają się w sposób płynny / przewidywalny, prawdopodobnie będziesz mieć wiele bloków, które potrzebują tylko jednej gałęzi, a te przypadki obu gałęzi będą ograniczone do wąskich pasm wokół granicy przejścia. Ale jeśli dane wejściowe są losowe, spodziewalibyśmy się, że większość bloków przejmie obie gałęzie i spowolni renderowanie.

Może się to również zdarzyć, jeśli używasz jednej tekstury do kontrolowania odnośników do drugiej tekstury, takiej jak zniekształcenie lub mapa indeksu. Jeśli pierwsza tekstura przeskakuje losowo, wówczas będziemy próbkować z rozrzuconych, losowo plamkowych plamek drugiej tekstury, mniej konsekwentnie wykorzystując naszą pamięć podręczną tekstur i dłużej czekając na uzyskanie potrzebnych danych.


Tak więc ogólnie: nie, zawartość tekstury nie ma większego wpływu na szybkość renderowania, z wyjątkiem przypadków, gdy ma to miejsce. ;)

DMGregory
źródło
Tekstury o niskiej rozdzielczości (zdaniem Minecrafta) byłyby bardziej skłonne do ładowania tekstur sąsiadujących pikseli do pamięci podręcznej, gdy konkretny tekstel jest ładowany do pamięci podręcznej, prawda?
user253751
6
@immibis Minecraft ma małe tekstury. Domyślnie jest to tylko 16 x 16, co tak łatwo mieści się w pamięci podręcznej tekstur każdego rdzenia, że ​​nie jest nawet śmieszne: D I tak, większość próbek tekstur będzie miała ten sam tekst, chyba że jesteś bardzo daleko od bloku. Jest to szczególnie prawdziwe, jeśli weźmie się pod uwagę podział ekranu - jeśli jesteś dość blisko, cała partia dla danego rdzenia może być odwzorowana na ten sam tekst: DA prostsza karta graficzna prawdopodobnie lepiej działałaby w przypadku teksturowania w niskiej rozdzielczości - podejrzewam wiele wysiłku marnuje się na optymalizacje, które nic nie pomogą Minecraftowi.
Luaan
1
Uwaga dodatkowa: „Używa tej samej liczby bajtów na piksel” jest w rzeczywistości kluczem do niektórych szybkich zmian, których używa kod graficzny. Jeśli spróbujesz użyć PNG wewnętrznie, a nawet czegoś takiego jak UTF-8 o zmiennej wielkości pikseli, aby dostać się do ntego piksela, będziesz musiał przejść przez każdy piksel przed nim. O stałej szerokości piksela bajtów, to po prostu start_of_buffer + width * n, co jest o wiele szybsze, zwłaszcza dla dużych n.
Pozew funduszu Moniki z
@Luaan Mam na myśli, że nawet jeśli jesteś daleko od bloku, gdy pobiera jeden texel (którykolwiek z nich jest pierwszy), powinien również przyciągnąć sąsiednie do pamięci podręcznej.
user253751
4
Właśnie o tym mówię powyżej przy użyciu mipmapowania. Aby uniknąć przeskakiwania próbek po całej teksturze, pozostawiając duże luki między ponownym użyciem pamięci podręcznej bez użycia pamięci podręcznej lub bez niej, przechowujemy wersję 512x512 i wersję 256x256 i ... czasami aż do 1x1. Rysując teksturę 1024 x 1024 w formacie 16 x 16, większość gier będzie czytać z mipa 16 x 16 i działa podobnie jak w przypadku Minecrafta 16 x 16 pod względem wydajności pamięci podręcznej. Zmniejsza to również błyszczące artefakty aliasingu podczas próbkowania w dół.
DMGregory
1

Oprócz doskonałej odpowiedzi DMGregory powyżej, być może istnieje jeden przypadek, w którym złożoność „tekstury” może wpłynąć na wydajność renderowania, i to w którym wyniki poprzedniego renderowania są wykorzystywane jako źródło w kolejnym, np. Mapy cieni / odbicia / mapy środowiska.

Niektóre nowoczesne urządzenia mogą stosować bezstratną kompresję tych buforów: na przykład PowerVR ma PVRIC , AMD, Delta Color Compression , a ARM ma coś podobnego. Celem tych technik kompresji jest zmniejszenie ogólnej przepustowości, co z kolei może poprawić wydajność renderowania.

Im prostsze dane, czy to głębokość, czy kolor (liczba całkowita lub liczba zmiennoprzecinkowa), tym lepsze będą te schematy. Oczywiście nie sugerowałbym celowego uproszczenia wyników renderowania tylko po to, aby działały lepiej, ale unikanie używania zaszumionych danych może w niektórych przypadkach pomóc.

Również robienie rzadkiego próbkowania buforów ramek / głębokości korzystających z tych schematów, w próżnej próbie zmniejszenia przepustowości, nie pomoże, ponieważ bardzo prawdopodobne jest, że będą oparte na blokach.

Ponadto możesz znaleźć te dwa pytania i odpowiedzi dotyczące grafiki komputerowej SE:

Simon F.
źródło