RetroAge Artykuł, Publicystyka Na progu rewolucji – część 1
ArtykułPublicystyka

Na progu rewolucji – część 1

Loading

Po rewolucji związanej z przejściem w grafikę 3D na konsolach Sega Saturn, Sony PlayStation oraz Nintendo 64 od kolejnej generacji konsol oczekiwaliśmy, że wszystkiego będzie więcej oraz wszystko będzie lepsze. Ponieważ wszyscy czterej producenci (Sega, Sony, Nintendo oraz Microsoft) zaprezentowali troszeczkę inne podejście do tematu, dlatego też, w poniższym artykule postaram się pokrótce zaprezentować jak to „więcej” i „lepiej” zostało zrealizowane.

Przed przystąpieniem do lektury artykułu zalecam zapoznanie się lub przypomnienie sobie artykułu „Na poligonie.”

Spirala historii

Pierwsze gry z grafiką 3D pojawiły się na rynku dużo wcześniej niż usłyszeliśmy nazwę PlayStation, a dokładniej na samym początku lat ’80. Oczywiście grafika w tych pozycjach była bardzo uproszczona, a główne powody tego stanu były dwa:
– po pierwsze, wszystkie obliczenia związane z generowaniem świata 3D, jak i samo tworzenie grafiki 3D spoczywało na procesorze głównym konsoli/komputera, a układ graficzny (2D) służył przede wszystkim do wyświetlania wytworzonego obrazu i ewentualnie nałożenia elementów 2D.

– po drugie, oczywistym powodem była sama niewielka moc obliczeniowa procesorów.

Z czasem moc procesorów rosła, a oprawa grafiki 3D zyskiwała na atrakcyjności. Ewolucją tego stanu rzeczy było wykorzystanie koprocesora matematycznego przez grę DOOM. Koprocesor odciążał procesor główny przy skomplikowanych obliczeniach związanych z przekształceniami środowiska 3D, dzięki czemu gry zyskiwały na płynności animacji. Kolejnym milowym krokiem na drodze ewolucji grafiki 3D było pojawienie się Akceleratorów grafiki 3D (występujące, jako osobne układy lub zintegrowane z układami grafiki 2D). Akceleratory odciążały procesory (lub tandemy procesor+koprocesor) od żmudnego zadania, jakim było przetwarzanie matematycznego modelu świata 3D na obraz wyświetlany na ekranie monitora/telewizora (czyli tzw. renderingu). Układy akceleratorów posiadały też często funkcje poprawiające jakość generowanego obrazu, takie jak cieniowanie wielokątów czy też ich teksturowanie. Tego typu układy znajdziemy w konsolach Saturn (kombinacja 2 układów procesora głównego oraz akceleratora 3D) oraz PlayStation (Procesor główny, koprocesor geometryczny oraz akcelerator 3D). Nowocześniejsze podejście do tematu zostało zaprezentowane w konsoli Nintendo 64 – układ graficzny RPC odciążał również procesor w zakresie obliczeń związanych z „transformacją”, czyli przekształceniami położenia elementów sceny 3D, oraz ich oświetleniem (tak zwane Hardware T&L). Układ ten dodatkowo wybiegał w przyszłość umożliwiając niewielkie zmiany w oprogramowaniu wewnętrznym pozwalając tworzyć własne efekty.

Rozwiązanie ze sprzętowym wsparciem dla transformacji i oświetlenia było obarczone jednak pewnym minusem – uniemożliwiało swobodę w kreowaniu przekształceń światów 3D, oraz sposobu ich oświetlania, jaką twórcy gier posiadali używając do tego celu procesorów (i/lub koprocesorów) ograniczając je do funkcji zaprogramowanych w układzie akceleratora 3D. Niewątpliwym zaś plusem była dużo większa szybkość generowania scen 3D. Z czasem układy otrzymywały coraz to nowsze funkcje, nie dając jednak autorom gier wpływu na zasady ich działania.

(porównanie prędkości renderowania obrazu pomiędzy operacjami transformacji i oświetlenia realizowanymi przez procesor główny a układ graficzny)

Kolejnym oczywistym krokiem na drodze ewolucji układów wspomagających tworzenie grafiki 3D były procesory grafiki z w pełni programowalnymi jednostkami odpowiadającymi za transformację oraz oświetlenie scen trójwymiarowych. Pierwotnie w układach pojawiły się 2 rodzaje programowalnych jednostek – Vertex Shader (odpowiadająca za przekształcenia wierzchołków oraz ustalająca kolor i jasność wierzchołków) oraz Pixel Shader (odpowiadająca za ostateczny kolor i jasność każdego punktu wyświetlanego obrazu).

O prymitywach słów kilka

Jak powszechnie wiadomo (np. z artykułu „Na poligonie”) podstawowym elementem tworzącym scenę 3D jest poligon, czyli wielokąt. W przypadku konsoli Sega Saturn jest to czworokąt a w przypadku Sony PlayStation oraz Nintendo 64 jest to trójkąt. W przypadku konsol szóstej generacji używamy prymitywów („primitves”), czyli elementów podstawowych nie koniecznie będących wielokątami. Każdy z prymitywów posiada przynajmniej jeden określony współrzędnymi w przestrzeni punkt oznaczony „v” (od angielskiego vertice – wierzchołek). Konsole szóstej generacji do tworzenia scen 3D używają często kilku różnych elementów podstawowych, takich jak:

– punkt – czyli dowolny punkt z określonymi współrzędnymi w przestrzeni (x,y,z). W tym miejscu należy wyjaśnić sens renderowania czegoś tak małego jak „punkt” – rysując ten typ prymitywu, nie możemy utożsamiać go z punktem rysowanym na ekranie, czyli pikselem, ani też z pikselem tekstury, czyli tekselem. Prymityw będący punktem określonym w trójwymiarowym układzie współrzędnych naszej sceny 3D możemy rysować różnymi „grubościami” począwszy od ułamków piksela (np. ½, 1/3, 1/6) do kilkudziesięciu pikseli. Biorąc pod uwagę, że taki „punkt” możemy oświetlać, cieniować, teksturować dostajemy możliwość wyświetlenia „konkretnego” kwadratu przeliczając współrzędne tylko jednego punktu zamiast czterech.

odcinek – powstaje z połączenia dwóch punktów z określonymi położeniami w przestrzeni. W przypadku odcinków podobnie jak z „punktami” mamy możliwość określenia ich grubości.

ciąg odcinków – powstaje przez dołączanie do linii kolejnych punktów sceny 3D (każda dodatkowa linia w ciągu to jeden dodatkowy punkt). W przypadku ciągu odcinków tworzących pętlę, oświetlane, cieniowane, teksturowane mogą być jednie odcinki na całej swojej grubości, a nie przestrzenie ograniczone tymi odcinkami.

trójkąt – pierwszy polygon, czyli wielokąt w zestawieniu, posiada 3 punkty określone w przestrzeni.

ciąg trójkątów – powstaje przez dodanie do poprzedniego trójkąta kolejnego punktu, kolejne trójkąty w ciągu mają jeden wspólny bok.

wachlarz trójkątów – powstaje z przynajmniej trzech trójkątów posiadających jeden wspólny wierzchołek.

czworokąt – wielokąt z czterema punktami określonymi w przestrzeni.

ciąg czworokątów – powstaje przez dodanie do poprzedniego czworokąta kolejnych dwóch punktów, kolejne czworokąty w ciągu mają jeden wspólny bok.

wielokąt (polygon) – dowolna, zamknięta wypukła figura geometryczna – ostatni „n’ty” wierzchołek jest połączony z pierwszym.

Łączenie elementów w „ciągi” oraz „wachlarze” pozwala zaoszczędzić na obliczeniach transformacji i oświetlenia wspólnych punktów.

Wodotryski i fajerwerki szóstej generacji

Najwyższa pora przejść do konkretów, czyli do efektów i funkcji obsługiwanych przez konsole szóstej generacji.

Podwójne i potrójne buforowanie (Double & Triple Buffering)

Podczas procesu renderingu dane obrazu zapisywane są w buforze ramki skąd zostają przesyłane do układów generujących wyjściowy sygnał video. Po utworzeniu danej klatki obrazu, bufor zostaje wyczyszczony, a następnie zapisywany danymi kolejnej klatki obrazu. W takim układzie zdarzają się sytuacje gdzie układ wizyjny odczytuje zawartość bufora ramki w momencie, gdy jest on pusty, co objawia się migotaniem obrazu na ekranie telewizora/monitora. Aby temu zapobiec konsole szóstej generacji stosują podwójne lub potrójne bufory ramki. W przypadku bufora podwójnego, dane kolejnych klatek obrazu zapisywane są na przemian w dwóch buforach ramki, w taki sposób, że zawsze jeden z nich zawiera dane obrazu. Przy tego typu rozwiązaniu należy natomiast uważać na synchronizację programową) przełączania buforów z odświeżaniem ekranu – w przeciwnym wypadku będziemy mieli do czynienia z „przedarciem ekranu (screen tearing)” spowodowanym wyświetlaniem na górnej części ekranu danych z pierwszego bufora, a na dolnej części ekranu danych z drugiego bufora. Problem z „rozdarciem ekranu” załatwia zastosowanie dodatkowego pośredniego trzeciego bufora ramki. Dodatkowo konsole szóstej generacji używają podwójnego buforowania ramek w celu zapobiegnięciu migotania drobnych elementów obrazu w rozdzielczościach wyświetlanych z przeplotem. Należy jednak pamiętać, że każdy dodatkowy bufor zabiera miejsce w pamięci (video) – dla przykładu pojedynczy bufor ramki w rozdzielczości 640×480 z 32bitowym kolorem zajmuje 1200kB. Co przy dwóch buforach ramki oraz 32bitowym buforze „Z” daje 3600kB na same dane buforów.

Pełnoekranowe wygładzanie krawędzi (Full Screen Anti Aliasing – FSAA)

Zastosowane w konsoli N64 wygładzanie krawędzi (Edge Anti Aliasing) posiada dwie poważne wady – po pierwsze wymaga „odszukania” krawędzi, które mają zostać wygładzone (a tych w grach na konsole szóstej generacji jest dużo więcej), a po drugie utrudnia korzystanie z bufora Z (kolory krawędzi są interpolowane z kolorami otoczenia). Pełnoekranowe wygładzanie krawędzi obchodzi się z tym tematem bardziej brutalnie, wygładzając grafikę całej sceny bez badania czy w danym miejscu znajdują się jakieś krawędzie, czy też nie. Jedną z metod takiego wygładzania jest „supersampling” – technika ta polega na renderowaniu sceny do pamięci w odpowiednio wyższej niż wyjściowa rozdzielczości, a następnie kopiowane do bufora ramki ze skalowaniem w dół do żądanej rozdzielczości z filtrowaniem dwuliniowym.

Filtrowanie anizotropowe (Anisotropic filtering)

Technika ta będącą rozwinięciem filtrowania trójliniowego ma za zadanie zachowanie ostrości tekstur znajdujących się w pewnej większej odległości oraz pod ostrym kątem względem obserwatora. Odbywa się to za pomocą dodatkowych mip-map przybierających tym razem kształt prostokątów (zamiast kwadratów jak w przypadku filtrowania trójliniowego).

Kompresja tekstur

Jednym z problemów związanych z generowaniem grafiki 3D na konsolach piątej generacji była zbyt mała pojemność pamięci video na tekstury. Mimo iż konsole szóstej generacji posiadają znacznie więcej pamięci video, wzrosła także ilość i rozdzielczość używanych tekstur. Dlatego też zdecydowano się na sprzętową implementacje dekompresji tekstur. Do kompresji tekstur nie użyto popularnych algorytmów takich jak JPEG, które mimo dużej wydajności przy zachowaniu rozsądnej jakości wymagają sporej ilości mocy obliczeniowej.  Dlatego też na konsolach szóstej generacji spotkamy dwa rodzaje kompresji, nieużywane standardowo przy zapisywaniu plików graficznych:

– VQ (Vector Quantization) – metoda ta polega na utworzeniu tak zwanego „słownika tekstury” o objętości 2kB, a następnie podzieleniu tekstury na kwadraty 2×2 teksele, oraz zapisaniu ich odpowiedników ze „słownika” jako skompresowanej tekstury.

Wydajność kompresji zależy od rozmiarów tekstury: 16×16 – 425%, 32×32 – 112.5% (do tej wielkości „kompresja” zwiększa objętość pliku tekstury), 64×64 – 37.5%, 128×128 – 18.75%, 256×256 – 14.06%, 512×512 – 12.89%, 1024×1024 – 12.6%

– S3TC – metoda ta polega na podzieleniu tekstury na kwadraty 4×4 teksele, a następnie wyznaczenie dla każdego z nich dwóch kolorów bazowych, a kolejne dwa kolory ustalane są na podstawie interpolacji liniowej kolorów bazowych. W rezultacie plik skompresowanej tekstury zawiera informację o dwóch kolorach bazowych oraz ich położeniu na teksturze. Dla tekstur z 24bitową głębią kolorów wydajność kompresji wynosi 16,7% niezależnie od rozmiarów samej tekstury.

Renderowanie tekstur (renderowanie do tekstury)

Technika ta polega na zapisie danych renderowanego obiektu (polygon, model 3D, scena) do pamięci video w miejsce przeznaczone na tekstury zamiast do bufora ramki. Następnie tak zapisany obraz możemy użyć, jako tekstury nakładając na inne obiekty. Tak spreparowane tekstury mogliśmy zaobserwować w demonstracji możliwości konsoli PlayStation 2 przygotowanej przez Square pt. „Facial Animation”. W demonstracji tej mogliśmy zobaczyć utworzoną z około 100’000 polygonów animowaną twarz starca, która następnie zostaje użyta, jako tekstura dla obracających się kwadratów.

Oczywiście nałożenie tekstur w żaden sposób nie zmienia geometrii sceny i ilość widocznych polygonów po nałożeniu tekstury jest równa ilości widocznych kwadratów (x2 w przypadku zastosowania trójkątnych prymitywów), co możemy zaobserwować na poniższym filmie:

Zastosowanie renderowania tekstur w sposób zaprezentowany w powyższych przypadkach rzadko znajduje odzwierciedlenie w rzeczywistości. Wyrenderowane wcześniej tekstury zostają najczęściej używane przy generowaniu bardziej zaawansowanych efektów (opisy, których znajdują się w dalszej części artykułu) a także do generowania „oszukanych” bardziej zaawansowanych efektów, co postaram się przestawić na poniższym przykładzie:

Szalona małpa ucieka z laboratorium rozwalając skrzynie z bananami oraz włączając alarm z czerwoną migającą lampą. Renderując tak przedstawioną scenę możemy obrabiać teksturę każdego z bananów uwzględniając ich błyszczące nawoskowane pomarszczone skórki oświetlane migającym czerwonym światłem. Z drugiej strony przy szybkiej akcji, komu by się chciało przyglądać każdemu z bananów z osobna? Dlatego też możemy sobie „wirtualnie” w pamięci wyrenderować  jednego banana z uwzględnieniem wszystkich potrzebnych efektów i/lub warunków oświetleniowych, następnie „ściągnąć” z niego tak stworzoną teksturę, którą następnie nałożymy na wszystkie znajdujące się w scenie banany.

Proceduralne generowanie obiektów

Jeden z najbardziej znanych tytułów z 8 bitowych konsol i komputerów – „River Raid” oferuje ponad 65 tysięcy odcinków rzeki upchanych maksymalnie w 8kB pamięci. Odcinki te nie zostały zaprojektowane w żadnym edytorze – są tworzone na bieżąco za pomocą sprytnie przemyślanych wzorów matematycznych. Konsole szóstej generacji posiadają odpowiednią moc obliczeniową, aby za jej pomocą na podstawie odpowiednich „wzorów” tworzyć całe obiekty a nawet światy 3D, dzięki czemu możemy oszczędzać pamięć główną z przeznaczeniem na inne dane.

Renderowanie wieloprzebiegowe (Multipass rendering)

Dzięki odpowiedniej mocy obliczeniowej dany polygon, obiekt, scenę możemy renderować więcej niż raz, za każdym razem używając wyników z poprzednich obliczeń. Dzięki czemu możemy wzmacniać działanie pewnych efektów, nakładać efekty z innymi parametrami… albo na przykład nałożyć drugą (a także kolejną) warstwę tekstury. A dzięki wielowarstwowemu teksturowaniu możemy zaoszczędzić sporo pamięci, co postaram się wyjaśnić w poniższym przykładzie:

Zestaw tekstur pewnego poziomu gry zawiera 5 rodzajów tekstury pokrywającej ściany, oraz kolejne 5 rodzajów tekstury odpowiadające poprzednim, ale z naniesionym włącznikiem światła. Stosując teksturowanie wielowarstwowe potrzebujemy jedynie 5 rodzajów tekstury pokrywającej ściany, oraz jedną teksturę przedstawiającą włącznik, którą w razie potrzeb możemy nanosić na tektury ścian.

W ten sposób na tekstury „główne” możemy nanosić różnego rodzaju „detale” takie jak błoto na samochodach rajdowych czy też krople wody na obiektach podczas deszczu.

Multiteksturowanie (Multitexturing)

Jest funkcją układu graficznego konsoli/komputera do nanoszenia więcej niż jednej warstwy tekstur podczas jednego przebiegu renderowania.

Na konsolach piątej generacji „ozdabiano” obiekty 3D teksturami w procesie „mapowanie tekstur”. Z czasem w celu realizowania pewnych efektów, zaczęto w połączeniu z mapowaniem tekstur stosować mapowanie innych „obrazów” niebędących teksturami zwanymi „mapami” realizowanych przez nie efektów.  Efekty te są realizowane na zasadzie łączenia wielowarstwowych „map” na zasadzie podobnej do mieszania warstw w programach graficznych obsługujących edycję wielowarstwową.

Mapowanie światła (Light mapping)

Mapa światła służy do symulacji natężenia światła padającego na znajdującą się pod nią teksturą. Stosuje się ją w celu uproszczenia obliczeń oświetlenia danego obiektu (zazwyczaj przy zastosowaniu źródła/źródeł lokalnych).

Mapa oświetlenia może zawierać również informacje o kolorze padającego światła, co przestawia poniższy film:

(zaprezentowana na filmie „mapa oświetlenia” przedstawia zbiór wszystkich map oświetleniowych użytych przy renderowaniu sceny)

Mapowanie wytłoczeń/wybojów (Emboss bump mapping)

Mapa wytłoczeń służy do symulacji różnego rodzaju drobnych nierówności teksturowanej powierzchni, takich jak wgłębienia, wypukłości, rysy, chropowatość… Mapę zapisujemy w odcieniach szarości, gdzie jaśniejsze punkty oznaczają wypukłości tekstury, a ciemniejsze wgłębienia. Technika ta nie zmienia geometrii obiektów – oglądana pod różnymi kątami tekstura jest nadal płaska – nic nie wystaje poza teksturowany obiekt. Efekt opiera się jedynie na modyfikacji przez mapę wybojów światła odbijanego przez teksturowany obiekt. Mapowanie wytłoczeń może być realizowane sprzętowo przez układ graficzny, a także z powodu mało skomplikowanych obliczeń również za pomocą procesora graficznego (stosując dwa przebiegi renderingu).

Mapowanie normalnych (Normal/DOT3 bump mapping)

Mapowanie wytłoczeń wpływa jedynie na zmianę wysokości położenia teksela tekstury względem jej standardowej powierzchni. Nie mamy natomiast wpływu na zmianę kąta położenia płaszczyzny teksela względem powierzchni tekstury. W celu realizacji takiego efektu zamiast mapowania wytłoczeń stosujemy mapowanie normalnych. A czym są normalne? Precyzyjniej ujmując temat – wektory normalne, czyli wektory prostopadłe do danej powierzchni. Każdy z polygonów tworzonej sceny 3D posiada dwa wektory normalne – jeden wyznaczony od przedniej ściany wielokąta, a drugi od tylnej ściany wielokąta. Badając kierunek, a przede wszystkim zwrot wektora normalnego możemy określić czy dany wielokąt jest widoczny przez obserwatora, a jeśli tak, to którą z jego ścian należy skierować do renderingu. Za pomocą mapy normalnych możemy modyfikować wektory normalne dla każdego z tekseli tekstury, które następnie zostaną wykorzystane przy oświetlaniu obiektu. Mapa normalnych ma postać kolorowego obrazu (RGB) gdzie wartości składowych kolorów odpowiadają współrzędnych x,y,z wektora normalnego dla danego teksela. Pewnym problemem z zastosowaniem mapowania normalnych na konsolach szóstej generacji jest fakt, że ówczesne metody kompresji tekstur uniemożliwiały zapisywanie z kompresją tego typu map (kompresja mocno zakłócała wygląd mapy). Stosując tę technikę musimy pamiętać o tym, że nie zmieniamy geometrii mapowanego obiektu, i patrząc pod kątem powierzchnia nadal będzie płaska.

Mapowanie odblaskowości (Specular map)

W połączeniu z mapowaniem normalnych możemy użyć dodatkowej mapy odblaskowości podkreślając właściwości symulowanego materiału w zakresie możliwości odbicia światła.

Mapowanie środowiska (Environment map)

Konsola Nintendo 64 umożliwiała (bardzo prymitywny) efekt mapowania środowiska, realizowany za pomocą kiepskiej jakości (rozmiar 32×32 teksele) tekstury środowiskowej. Konsole szóstej generacji oferują trzy metody mapowania środowiska o nieporównywalnie lepszej jakości. Wszystkie opierają się na wyrenderowaniu tekstury (lub tekstur) z punktu widzenia odbijającego środowisko obiektu, a następnie nałożenia jej na obiekt i/lub jego teksturę.

Sferyczne mapowanie środowiska

Tworzenie sferycznej mapy środowiskowej przypomina fotografię 360stopni opisaną na kole umieszczonym w kwadratowej teksturze.

Tego typu mapowanie środowiska charakteryzuje się bardzo szybkim niewymagającym dużej mocy obliczeniowej procesem renderingu. Natomiast stwarza bardzo dużo problemy w generowaniu mapy. Dlatego też najczęściej stosuje się przygotowane wcześniej mapy – a w odbijającym środowisku obiekcie nie możemy zaobserwować poruszających się obiektów. Oczywiście dysponując odpowiednim zapasem mocy obliczeniowej, oraz umiejętnościami możemy generować sferyczne mapy środowiskowe uwzględniające zmiany w otoczeniu. Kolejnymi problemami mapowania sferycznego jest niewykorzystanie pełnej powierzchni tekstury do zapisu informacji (koło na kwadratowej teksturze), oraz zaburzenie odbijanego środowiska w miejscu łącznia krawędzi mapy.

Paraboidalne mapowanie środowiska

Ten typ mapy jest bardzo podobny do poprzedniego, z tym że wynikiem renderowania są 2 mapy w kształcie koła, odpowiadające za dwie półkule odbijanego środowiska. Zaletą tego rodzaju mapowanie jest niewiele większe zapotrzebowanie na moc obliczeniową, przy eliminacji niepożądanych zakłóceń w miejscu łącznia się map.

Wadami nadal pozostają trudności w wygenerowaniu map, oraz niewykorzystanie całej powierzchni tym razem dwóch map. W przypadku mapowania paraboidalnego nadal zazwyczaj stosuje się przygotowane wcześniej mapy. Oczywiście dysponując odpowiednią mocą obliczeniową możemy mapy generować uwzględniając dynamicznie zmiany w odbijanym środowisku.

Sześcienne mapowanie środowiska

Podstawowym założeniem tego rodzaju mapowania środowiskowego była łatwość w generowaniu map dynamicznie zmieniającego się otoczenia. W tym przypadku generujemy sześć kwadratowych map środowiska, po jednej dla każdego z sześciu kierunków. Łatwość generowanie map okupiona jest wzrostem zapotrzebowania na moc obliczeniową przy nakładaniu tekstur na obiekt. Mapowania sześciennego możemy oczywiście używać w stałych środowiskach uzyskują rezultat tożsamy z mapowaniem paraboidalnym:

Albo w środowiskach z ruchomymi obiektami, renderując na raz wszystkie sześć map, lub tylko te z kierunku, których nastąpiły zmiany:

Środowiskowe mapowanie wybojów

Efekt powstały z połączenia mapowania wybojów z mapowaniem środowiska. Pierwszym urządzeniem obsługującym ten efekt (nie ma możliwości symulacji tego efektu za pomocą procesora głównego) była karta graficzna Matrox G400. Niestety z powodu braku zainteresowania efektem ze strony producenta układów graficznych Nvidia nie zyskał on dużej popularności. W późniejszym czasie środowiskowe mapy wybojów były obsługiwane przez karty Ati Radeon oraz ST Micro KYRO. Powszechne stosowanie efektu nastąpiło dopiero wraz z pojawieniem się układów graficznych z programowalnymi jednostkami Vertex Shader i Pixel Shader.

Projekcja tekstur

Technika polegająca na takim mapowaniu tekstury na obiekty znajdujące się na scenie 3D jakby była ona wyświetlana przez projektor. Efektu możemy użyć na przykład do symulacji obrazu rzucanego na scenę przez oświetlony kolorowy witraż lub szablon.

Dynamiczne cienie

Cienie rzucane przez obiekty lub bohaterów gier na konsolach piątej generacji najczęściej sprowadzały się do ciemnych kółek rysowanych pod modelem 3D. Konsole szóstej generacji dostały już odpowiednie funkcje pozwalające tworzyć realistyczne dynamiczne cienie.

– metoda cieni bryłowych, polega na wirtualnym wytworzeniu bryły symulującej oświetlenie danego obiektu, dla którego chcemy wygenerować cień. Następnie w obrębie tej bryły dokonywana jest analiza przeszkód, na jakie natrafia światło, wyniki analizy zapisywane są w specjalnym buforze zwanym „szablonowym” (stencil buffer). Ostateczna zawartość bufora jest wyświetlana, jako cień rzucany przez dany obiekt.

metoda projekcji tekstur, w tym przypadku wszystkie obiekty renderujemy z punktu widzenia światła, jako czarne tektury, które następnie są wyświetlane na zasadzie projekcji za oświetlanymi obiektami.

Refrakcja

Efekt ten pozwala symulować załamanie światła przy przechodzeniu przez środowiska o różnej gęstości. Realizowany jest przez odpowiednią mapę modyfikującą obraz znajdujący się za obiektem generującym efekt. Popularnym zastosowaniem efektu jest symulacja środowiska znajdującego się pod wodą z punktu widzenia z nad powierzchni wody.

Efekty cząsteczkowe

Czyli symulacja zjawisk takich jak opady deszczu, opady śniegu, dymu, ognia itp. Za pomocą dużych ilości niewielkich (często mających rozmiar od jednego do kilku pikseli) obiektów 2D. Obiekty te zwyczaj charakteryzują się krótkim czasem (do kilku sekund) istnienia w środowisku, cechującym się często szybko zwiększającym się stopniem przezroczystości.

Mapowanie przesunięć

Ostatni efekt można potraktować, jako ciekawostkę – nie jest sprzętowo wspierany przez żadną z konsol szóstej generacji. Pierwszą kartą graficzną używającą tego typu mapowania była Matrox Parhelia z 2002r. A następnie karty graficzne ATI począwszy od modelu 9500. Jest to kolejny efekt, który nie upowszechnił się w momencie premiery (brak zainteresowania ze strony Nvidia) , a jego rozwój przypada na pojawienie się interfejsu Direct X11. Wspominam o nim natomiast ze względu na informacje znalezione w dokumencie firmy ATI prezentującej mapowanie przesunięć, mówiącej o możliwości realizacji efektu na konsolach PlayStation 2, Gamecube oraz Xbox. Technika ta polega na wykorzystaniu mapy z obrazem w skali szarości do modyfikacji siatki wielokątów danego obiektu. Dzięki czemu oszczędzamy mocy obliczeniowej na przeliczeniach wierzchołków bardziej skomplikowanej siatki obiektu. Oświetlenie zmodyfikowanej powierzchni jest natomiast realizowane za pomocą mapowania normalnych.

Poniższe video przedstawiające postać rybaka nad jeziorem. Drzewa, trawa oraz motylki są animowane, poruszane oraz oświetlane za pomocą programowalnych jednostek Vertex Shader. Ruchy postaci rybaka realizowane są techniką morfowania również przy użyciu jednostek Veretx Shader. Do generowania powierzchni jeziora wykorzystano programowalne jednostki Vertex Shader, Pixel Shader oraz sześcienną mapę środowiska używając w sumie czterech warstw tekstur. Do renderowania krajobrazu, rzeki, domu, mostku użyto dwóch warstw tekstur (tekstura bazowa, oraz mapa oświetlenia). Obiekty takie jak liście, trawa, rybak renderowane są z jedną warstwą tekstury.

Autor

Komentarze

  1. Ciekawy wpis. Dobrze wiedzieć jak wiele złożonych technik graficznych kryje się za pięknymi obrazami ze współczesnych gier. Czekam na dalszy ciąg.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.