Więcej niż łatka tekstur? (Część 2)
W drugiej części tej serii spojrzymy na problemy, które pojawiają się w trakcie wyświetlania tekstur w trójwymiarowej przestrzeni, i ich rozwiązania.
Aby wyświetlić bryłę pokrytą teksturą, odpowiednie piksele tekstury muszą być określone dla każdego punktu monitora i musi być obliczona dla nich średnia wartość. Weźmy dla przykładu Ziemię. Z dystansu, wygląda niebiesko jak oceany i zajmuje trochę powierzchni ekranu, składa się tylko z paru punktów. Z drugiej strony, wiele pikseli tekstury przyczynia się do reprezentacji pojedynczego punktu. Jeśli teraz zmniejszymy dystans do zwykłego rozmiaru, możemy zobaczyć kontynenty i ich charakterystykę. Ziemia zajmuje teraz właśnie cały obszar naszego wyobrażenia, kwadratowy ekran. Niemniej jednak teraz każdy punkt składa się z mniejszej liczby pikseli niż krok wcześniej. Następnie przesuwamy się nieco bliżej i próbujemy rozpoznać miasto, w którym żyjemy. Pojedyncze piksele tekstury powoli stają się rozpoznawalne, więc jest tu tylko około jeden piksel na punkt. Ostatecznie przesuwamy się bardzo blisko i patrzymy na nasz dom, ale nie możemy go zobaczyć, z powodu ograniczonej rozdzielczości tekstury. Osiągnęliśmy minimalną odległość oglądania, każdy piksel jest już wyświetlany w kilku punktach ekranu. Wizualne wrażenie spowodowane przez to zjawisko jest powszechnie określanie jako "rozpikselowanie".
Tak więc odległość oglądania określa, jak wiele pikseli odpowiada punktowi. Odpowiednio, dalekie dystanse prowadzą do wysokiego wysiłku obliczeniowego. Jednakże nie tylko to jest problemem. Ze względu na ilość pikseli i wynikową wariancję kolorów, coraz trudniej jest obliczyć reprezentatywną średnią wartość dla pikseli. Dlatego, szczególnie w przypadku płaskich powierzchni, występuje efekt aliasingu, który objawia się w górnym obszarze poniższego obrazu jako tak zwany wzór Moiré’a. Wyraźnie widać, że czarne i białe pola nie zmieniają już odległości, choć powinny.
Jeśli kolory odpowiednich pikseli są zbliżone do siebie, wtedy ich średnia jest również zbliżona do poszczególnych pikseli, a zatem reprezentatywna. Sytuacja wygląda jednak inaczej, jeśli kolory są od siebie oddalone np. czerń i biel na powyższym obrazku. Wówczas obliczone wartości średnie również znacznie się różnią, co prowadzi do "skoków kolorów". Aby zniwelować ten efekt, w grafice komputerowej jest używana technika zwana mipmappingiem. Więc jeśli oryginalna tekstura ma rozmiar 1024*1024 pikseli, pierwsza mipmapa ma 512*512 pikseli, następna 256*256 pikseli i tak dalej, aż do ostatniej, która ostatecznie ma rozmiar 1*1 piksel. W tej jednorazowej operacji obliczamy średnie wartości z wyprzedzeniem. W ten sposób możemy również korzystać z wyższej jakości i droższych algorytmów, niż byłoby to możliwe w czasie działania gry.
Teraz oryginalna tekstura nie jest już używana wyłącznie do renderowania, ale w zależności od odległości, jedna z jej mniejszych kopii, która ma bardziej odpowiednią liczbę odpowiednich pikseli. Znacząco zmniejsza to wysiłek obliczeniowy na punkt, a efekt aliasingu już nie występuje. Efektem ubocznym jest rozmycie obrazu, które jest tym większe, im dalej znajduje się dany punkt.
Aby móc zobaczyć, której mipmapy używa Gothic w danej odległości, pokolorowałem mipmapy tekstury trawy w różny sposób.
Swoją drogą ten eksperyment miał miejsce w trakcie jednego ze spotkań modderów, więc niektórzy z uczestników nie mogli powstrzymać się od podziwiania tej "tęczowej trawy". Trzeba przyznać, że ma ona psychodeliczny charakter.
W każdym razie otrzeźwiające było to, że oryginalna tekstura prawie nigdy nie była używana do renderowania, ale prawie zawsze jedna z mipmap. Ta konkluzja może być wyciągnięta z faktu, że trawa na zrzucie ekranu ma normalny kolor tylko na dole ekranu. Wkrótce znaleziono tego przyczynę: Gothic nie używa filtrowania anizotropowego (AF). Jest to technika redukcji rozmycia, która bierze pod uwagę kąt między kamerą a daną powierzchnią, oprócz odległości oglądania.
Należy stwierdzić, że silnik graficzny Gothica jest oparty na DirectX 7, i ta technologia była właśnie dostępna tego czasu. Jednakże w Gothicu nie było sposobu by to aktywować, i nie mogło to być zmienione w znaczeniu tradycyjnego moddingu Gothica. To dlatego wymusiłem filtrowanie anizotropowe poprzez sterownik mojej karty graficznej. Jak widać, oryginalna tekstura została następnie użyta w większym promieniu, poszczególne mipmapy są lepiej mieszane, a ostrość jest zachowana nawet w głębi.
Degenerated, oryginalny autor renderera D3D11, jakiś czas później napisał plugin do Gothica, który usuwał limit wierzchołków, który był dla nas zbawienny. Rozszerzyłem potem ten plugin i razem z innymi rzeczami, aktywowałem filtrowanie anizotropowe. Aczkolwiek ponownie zwiększa to wysiłek obliczeniowy; ze współczesnymi kartami graficznymi trudno jest zauważyć jakąś różnicę w wydajności.
Następujący – co prawda nieco starszy – zrzut ekranu porównuje standardowy Gothic z naszą zoptymalizowaną wersją jeszcze raz dla podsumowania. Chcę podkreślić, że są to te same tekstury, które są tylko różnie renderowane.
Nawiasem mówiąc, jakiś czas potem został wydany SystemPack, który zawierał filtrowanie anizotropowe wraz z wieloma poprawkami błędów, i Union, który zaadoptował architekturę pluginu i uprościł rozwój nowych pluginów.
W następnej części serii porozmawiamy o modelu kolorów RGB i renderowaniu przezroczystych pikseli.