web analytics

«

»

Game’s Anatomy 2: Hej, pokażesz mi swoją bazę?

Witam w części drugiej, mocno spóźnionej, naszego przewodnika po anatomii gier. Tym razem będzie trochę strasznie. Nie, poważnie, będzie matematycznie. Nie, nie, zostańcie, nie uciekajcie, nie jest tak źle… to może ja wyjaśnię po co i dlaczego.

Najpierw jednak muszę napisać, że to jest bodaj trzecia inkarnacja tego konkretnego tekstu — dwie wcześniejsze zostały anihilowane. Dlaczego? Ano, jak pewnie pamiętacie, w poprzedniej odsłonie obiecałem, że następnym razem zajmiemy się tematem oświetlenia. Kiedy jednak zacząłem o tym pisać, okazało się że zwyczajnie nie da się tego zrobić z sensem, nie opisując całego procesu pojawiania się obrazu na ekranie. Te artykuły nie mają przecież na celu wyłącznie zapchania miejsca na serwisie i poprawienia moich lichych statystyk tekstowej płodności na tle pozostałych ordynatorów – ich celem jest przede wszystkim sprawienie, byście choć trochę z tego owianego aurą tajemniczości programistyczno-matematycznego świata zrozumieli. Dlatego usunąłem kupę tekstu i postanowiłem zacząć od zera. Ponownie jednak czegoś brakowało.

Matematyka -- trochę szpetna, trochę straszna, ale w sumie piękna. I, wbrew pozorom, ma też ludzką twarz.

Grafika komputerowa to matematyka. Głównie algebra liniowa i geometria. Nie da się (a przynajmniej tak wynika z moich prób) pisać o tym jak działa grafika, nie odwołując się do przynajmniej kilku pojęć z algebry liniowej. To oczywiście nie oznacza, że potrzeba Wam wiedzieć co znaczy homomorfizm przestrzeni liniowych nad ustalonym ciałem. Absolutnie i kategorycznie nie. Ja nie mam bladego pojęcia co za czarna magia kryje się pod pojęciem homomorfizmu (choć, jak znam matematykę, jest to w gruncie rzeczy bardzo proste), ale kompletnie w niczym mi to nie przeszkadza. I poniekąd właśnie o tym nieprzeszkadzaniu jest ten cykl – ma Wam przybliżyć minimum tego, co jest konieczne, byście faktycznie rozumieli co dzieje się na ekranie i pokazać, że skomplikowanie tych wszystkich rzeczy jest w dużej mierze pozorne.

Kiedy więc zacząłem pisać o renderingu natychmiast okazało się, że jeśli powyższy cel ma mieć szansę realizacji, to bez algebry ani rusz. Dlatego właśnie ten tekst przybliży Wam kilka pojęć, którymi chcąc nie chcąc będę musiał operować w kolejnych (o ile po tym pozwolicie mi jeszcze coś napisać, haha). Obiecuję jednocześnie, że całe tłumaczenie obędzie się bez wzorów i liczenia (no, prawie). Wymagana jest tylko wyobraźnia. Najlepiej, oczywiście, przestrzenna… pun intended.

Zanim jednak przejdziemy do algebry zacznijmy od czegoś na rozgrzewkę, czyli od podstawowych części składowych świata egzystującego na karcie graficznej – wierzchołków i prymitywów.

Atomy wirtualnego świata

Wierzchołki — początek wszystkiego

Wierzchołki inaczej zwie się z angielska werteksami. Zwykle poświęca się im mniej uwagi niż trójkątom, które z nich powstają, ale niesłusznie. Owszem, najczęściej to właśnie trójkąty (w ilościach przemysłowych) podziwiamy w grach, ale to wierzchołki są cząstkami elementarnymi wirtualnego świata na Twoim monitorze. Czym więc jest wierzchołek? Po prostu punktem w trójwymiarowej przestrzeni (liniowej), do którego można przypisać określone parametry.

Tych parametrów może być dowolna ilość, a ich wartościami są zawsze wektory (dwu-, trzy- lub czterowymiarowe) lub skalary (w razie gdyby ktoś nie pamiętał z liceum, nie chodzi o rybki akwariowe a o zwykłe liczby). Co można upchać w takich parametrach? Obowiązkowo każdy werteks musi, naturalnie, mieć parametr określający jego współrzędne X, Y i Z.

Inne powszechnie pojawiające się parametry to kolor (jako RGBA), koordynaty tekstur (tzw. texcoord) oraz trzy bardzo istotne wektory, bez których nie ma nowoczesnego oświetlania — normalna, styczna i binormalna. Szczerze mówiąc, osobiście nie wyobrażam sobie nazywania ich w ten sposób, więc przejdźmy w tej materii na jedyny słuszny język, czyli angielski – normal, tangent, binormal. Do czego służą? Otóż stanowią one (nie przestraszcie się) bazę przestrzeni tangentowej. Co to jest przestrzeń i baza przestrzeni dowiecie się za dosłownie kilka chwil. Co to jest konkretnie przestrzeń tangentowa oraz do czego i dlaczego jest potrzebna opiszę natomiast w jednym z kolejnych artykułów. Póki co powiem na jej temat tylko tyle, że jest ona podstawą normal mappingu (a więc mapowania wypukłości) i bez niej byłby on, przynajmniej w grach, całkowicie niemożliwy, co byłoby ogromną stratą — przecież to właśnie on odpowiada za dużą część detali obecnych w naszych wirtualnych światach.

Prymitywy, czyli najprostsze co da się pokazać

Kiedy już mamy grupkę zdefiniowanych werteksów wraz z całą menażerią parametrów, to możemy zacząć je konstruktywnie wykorzystywać, a więc zbudować z nich tzw. prymitywy. Są to swego rodzaju pojemniki na werteksy, które to pojemniki umożliwiają wyświetlanie wierzchołków w konkretny sposób i w konkretnych konfiguracjach.

Punkty, linie i trójkąty

Najprostsza kategoria prymitywów wyświetla pojedyncze, niepowiązane ze sobą punkty — wierzchołki “luzem”. W ten sposób wyświetlane są najczęściej werteksy w programach do edycji grafiki 3D – żeby można je było zaznaczać i nimi poruszać. Po prostu każdy wierzchołek, niezależnie od pozostałych, otrzymuje swoją graficzną reprezentację (najczęściej) w postaci kwadratu, którego rozmiar na ekranie jest niezależny od odległości kamery od tego wierzchołka (nawet jeśli używamy kamery z perspektywą).

Druga kategoria to odcinki, czyli zestawy dwóch połączonych wierzchołków. Podobnie jak w wypadku punktów, odcinki mają ustaloną grubość, która jest niezależna od perspektywy — odcinek o grubości 10 pikseli zawsze ma 10 pikseli na ekranie, niezależnie czy kamera jest od niego oddalona o 2 centymetry czy 2 kilometry — perspektywie podlega natomiast jego długość. Z tego względu zastosowania takich odcinków są raczej ograniczone, bo nie ma sensu np. budować z nich lin, co inaczej wydawałoby się logicznym zastosowaniem. Chyba, że w grze typu 2.5D.

Tutaj jedna uwaga: Jeśli dokopiecie się do jakiejś konsoli (inaczej terminala) wbudowanego w grę dla potrzeb developerów, to często znajdziecie tam możliwość włączenia tzw. widoku wireframe. Taki sam widok można włączyć w każdym edytorze 3D czy edytorze map (jak UDK czy Unity3D). Być może po przeczytaniu powyższego opisu taki widok przyszedł Wam na myśl, ale to, co wtedy widzicie to zwykle nie są odcinki takie, jak rozumie je silnik (renderer), a jedynie trójkąty z wyłączonym wypełnieniem.

Trzecia grupa to ta najbardziej powszechna, czyli trójkąty. Każdy trójkąt zbudowany jest z 3 wierzchołków (O rly?! – pomyślał Czytelnik), a przestrzeń między tymi wierzchołkami jest zwykle wypełniona wyznaczonym przez nie wycinkiem płaszczyzny. Do wyznaczenia płaszczyzny w przestrzeni 3D potrzebujemy bowiem dokładnie 3 punktów. Każdy kolejny będzie nadmiarowy i będzie wyznaczał z pozostałymi kolejne płaszczyzny, ale wcale nie musi leżeć na tej samej, co pierwsze trzy. Jeśli zaś mamy dokładnie trzy punkty, to mamy też pewność, że zawsze wyznaczą nam one wspólną dla nich wszystkich płaszczyznę — niezależnie od ich wzajemnego położenia! Jedynym wyjątkiem, naturalnie, jest sytuacja, w której wszystkie trzy leżą na tej samej prostej. To właśnie dlatego trójkątów używa się jako podstawowego budulca modeli 3D, których powierzchnie składają się wszak z wycinków płaszczyzn.

To, że obecnie korzysta się z powyższych rozwiązań nie oznacza, że są to jedyne możliwe cegiełki, z jakich można budować modele 3D. Z zupełnie innego rozwiązania korzystała, na przykład, pierwsza karta graficzna NVidii — nie będę go opisywał, bo mimo teoretycznych zalet okazało się kompletną klapą i niewielkie są szanse, by ktokolwiek do niego wrócił. Przyszłość będzie prawdopodobnie należeć do SVO, czyli sparse voxel octree, ale o tym porozmawiamy pod koniec niniejszego cyklu.

Algebra liniowa – oswajamy bestię

Algebra liniowa, przynajmniej z utylitarnego punktu widzenia, to po prostu pewne rzeczy, które da się robić w i z przestrzeniami (liniowymi, a jakże), dlatego w tym rozdziale postaram się prostym językiem opisać jak działa przestrzeń, jak się ją wyznacza i co to właściwie jest wymiar przestrzeni.

Przestrzeń i wymiar przestrzeni

Zacznijmy od tego ostatniego, bo tak wydaje się najprościej. Obrazowo, nieprecyzyjnie, błędnie i za razem całkowicie wystarczająco poprawnie (jak na nasze potrzeby) mówiąc, jest to ilość prostych jakie można poprowadzić przez jeden punkt tak, że te proste się nie pokrywają i wszystkie są do siebie wzajemnie prostopadłe. To chyba najbardziej odpowiednia “popularnonaukowa” definicja jaka przychodzi mi go głowy. Jeśli pomyśleliście o narysowanym na tablicy układzie współrzędnych, to właśnie o coś takiego chodzi. Jeżeli w przestrzeni takich prostych da się poprowadzić 2, to przestrzeń jest 2D, jeśli 3, to 3D, jeśli 1984, to jest to przestrzeń 1984-wymiarowa.

Baza przestrzeni 3D (kolory oznaczają osie: RGB = XYZ)

Teraz jak działa przestrzeń? Nieformalna definicja przestrzeni brzmi tak: Przestrzeń liniowa (inaczej wektorowa) to zbiór wektorów wraz ze zdefiniowanymi dwoma działaniami – dodawaniem i mnożeniem. Jak zapewne rozumiecie, to zwykle oznacza również obecność odejmowania i dzielenia, bo to pierwsze to po prostu dodawanie liczby ujemnej, a to drugie to mnożenie przez ułamek. Captain obvious returns. W każdym razie, wprowadziliśmy sobie wektory.

Wektory – przypomnienie lub wprowadzenie

Ze szkoły pewnie kojarzycie je jako kreski ze strzałką na końcu, które przyprawiały Was o ból głowy, i które rysowało się w określonych wzajemnych konfiguracjach. Oczywiście nikomu nie zabronię tak o nich myśleć, ale dla własnego dobra przestańcie. Wektor to po prostu zestaw liczb, z którym można robić określone rzeczy. Jakie rzeczy? Dodawać oraz mnożyć przez skalary lub przez inne wektory.

Tutaj uwaga względem nazewnictwa – mnożenie wektora przez liczbę nazywa się mnożeniem przez skalar, podczas gdy mnożenie wektora przez inny wektor nazywa się iloczynem skalarnym. Tak oto matematycy ułatwiają sobie życie i unikają nieporozumień… Z powyższego względu, polecam korzystać z angielskiej nazwy tego ostatniego: dot product. Jest ładniejsza, krótsza i mniej myląca. Tak więc mamy dodawanie wektorów, mnożenie przez skalar (liczbę) oraz dot product. Wyglądają one tak:

  1. Dodawanie wektorów: (0, 1, 2) + (3, 4, 5) = (3, 5, 7)
  2. Mnożenie przez skalar: (1, 2, 3) * 5 = (5, 10, 15)
  3. Dot product (iloczyn skalarny): (0, 1, 2) * (3, 4, 5) = 0 * 3 + 1 * 4 + 2 * 5 = 0 + 4 + 10 = 14

Jak widzicie, produktem dodawania dwóch wektorów lub pomnożenia jednego przez liczbę są wektory, podczas gdy dot product daje nam skalar. To ważne ze względu na zastosowania tych działań, o których później. W tym tekście pojawi się tylko jedno z zastosowań pierwszych dwóch działań, podczas gdy dot product doczeka się swoich 5 minut w blasku fleszy w kolejnych artykułach.

Zasadniczo należałoby to wyjaśnić na literkach, ale niektórzy mogą mieć z tym związane złe wspomnienia, więc myślę, że taki przykład powinien być wystarczający.

Baza przestrzeni, czyli skąd wziąć wszystkie jej punkty

Anyway, wyobraźcie sobie, że na wspomnianych wcześniej prostych ustawiacie wektory jednostkowe (czyli długości jednej jednostki) – na każdej prostej po jednym, a każdy z początkiem w tym samym punkcie (jak na ilustracji powyżej). Ten punkt staje się punktem (0, 0, 0) naszej przestrzeni, czyli jej początkiem, a wektory mają współrzędne (1, 0, 0), (0, 1, 0) oraz (0, 0, 1).

Te 3 wektory nazywane są bazą przestrzeni i wyznaczają nam naszą przestrzeń liniową. To znaczy, że jeśli pomnożycie sobie te wektory przez skalary (liczby), a następnie dodacie do siebie wektory wynikłe z tego mnożenia, to możecie w ten sposób wyznaczyć (inaczej znaleźć) dowolny inny wektor (i dowolny punkt) w przestrzeni. To jest w zasadzie matematyczny odpowiednik zapisania wektora na kartce — w ten sposób algebra wypełnia sobie wektor współrzędnymi. Przykładowo, załóżmy że chcę aby moja przestrzeń odnalazła w sobie punkt (7, 10, 3). Zapisanie go to nie problem — podobnie jak jego “skonstruowanie” z wektorów bazowych. Popatrzcie (pamiętajcie o kolejności wykonywania działań — tu też obowiązuje ;) ):

(1, 0, 0) * 7 + (0, 1, 0) * 10 + (0, 0, 1) * 3 = (7, 0, 0) + (0, 10, 0) + (0, 0, 3) = (7, 10, 3)

Oczywiście możecie zapytać po co tyle zachodu, skoro współrzędne można po prostu zapisać i wsio. Jest to ważne, bo z wektorami bazowymi można robić różne ciekawe rzeczy, które powinny przekształcać (zapamiętajcie to słowo) całą przestrzeń, którą te wektory wyznaczają (względem innej przestrzeni). To znaczy, że kiedy je zmodyfikujemy, to wszystkie wierzchołki, jakie sobie w tej przestrzeni zbudowaliśmy (oraz trójkąty z nich powstałe) też muszą się zmienić. Kiedy mamy bazę i dwa proste działania, dzieje się to automatycznie — obracamy wektorami bazowymi, a wszystko inne w ich przestrzeni obraca się wokół nich.

Mógłbym tu dodać (doprecyzowując tym samym definicję), że wektory bazowe są liniowo niezależne, czyli żadnego z nich nie da się wyznaczyć za pomocą 2 pozostałych. Jasne jest, że choćby nie wiem jak mnożyć i dodawać do siebie (1, 0, 0) i (0, 1, 0), nie da się uzyskać (0, 0, 1), bo jedynka w trzeciej składowej wektora musiałaby wziąć się z powietrza (mnożenia przez zero pan nie oszukasz). Jednak już każdy inny wektor, jak pokazaliśmy powyżej, da się uzyskać z tych trzech, więc tworzyłby on zależność z pozostałymi. Na tym z grubsza polega liniowa niezależność i liniowa zależność. Dlatego też w przestrzeni 3D liniowo niezależnych wektorów będzie maksymalnie 3, zaś w przestrzeni 25D – 25.

Jeśli coś z tego zrozumieliście, to powinniście też pojąć definicję wymiaru przestrzeni bliższą definicji formalnej: Wymiar przestrzeni to maksymalna ilość wektorów liniowo niezależnych w tej przestrzeni.

Przekształcenia, czyli z przestrzeni do przestrzeni przechodzenia kurs przyspieszony

No dobra, wyznaczyliśmy sobie przestrzeń i wiemy jakie działania można wykonywać na jej składowych (wektorach). To jest pierwsza przestrzeń, jaką wyznaczamy, a więc nasza przestrzeń globalna. To jest sprawa czysto umowna – po prostu na potrzeby ograniczenia “dymienia czachy” programisty umawiamy się, że ta konkretna przestrzeń wyznacza nam nasz cały Wszechświat. Dzięki temu mamy chociaż jeden zestaw kierunków i wymiarów, który możemy uznać za absolut.

Ale to nie znaczy, że wszechświat ma monopol na przestrzenie. Swoją przestrzeń lokalną posiada każdy obiekt, a zależności między tymi przestrzeniami nazywamy przekształceniami. To one sprawiają, że obiekty w grze można ustawiać w różnych konfiguracjach, animować je, a nawet zwyczajnie wyświetlać.

Zanim przejdziemy do przekształceń, drobna uwaga (dzięki za zwrócenie na to mojej, nomen omen, uwagi, Polo_tuc!). Nie utożsamiajcie obiektu (w sensie modelu 3D) z jego przestrzenią lokalną (czy też odwrotnie). Każda przestrzeń obejmuje swoim zasięgiem cały wszechświat gry i nie kończy się na obrębie obiektu, do którego jest przypisana. Z tego względu nie można powiedzieć, że jakaś przestrzeń się kończy a inna się zaczyna — one się w sobie wzajemnie zawierają. Wszystkie zawierają też dokładnie te same punkty (w sensie, powiedzmy, fizycznym), ale te punkty są inaczej podpisane — czyli mają w każdej przestrzeni inne współrzędne. Bierze się to stąd, że wektory bazowe różnych przestrzeni są względem siebie poprzesuwane i poobracane (i często również porozciągane), co oznacza że trzeba ich różne ilości, żeby dojść od punktu (0, 0, 0) danej przestrzeni do wybranego przez nas innego punktu. Pamiętajcie, że wszystkie przestrzenie obejmują sobą wszystko, a współrzędne to nic innego jak odpowiedź na pytanie “przez jakie liczby muszę pomnożyć wektory bazowe, żeby dojść w dane miejsce?”

Przekształcenie to przede wszystkim względność. Pozwala ono na “przetłumaczenie” współrzędnych punktów i wektorów z jednej przestrzeni na współrzędne drugiej, a więc poznanie współrzędnych względem dowolnego obiektu (a dokładniej, względem bazy jego przestrzeni). To ważniejsze niż się wydaje – na tym opiera się nie tylko animacja, ale nawet samo wyświetlanie świata na ekranie. Kamera musi wiedzieć co widzi i jak to wygląda, a więc musi znać położenie punktów względem jej samej. I właśnie po to istnieją przestrzenie lokalne – żeby można było mówić o względności. Każda z nich ma swój początek oraz swoje wektory bazowe — wyznaczające kierunki i jednostki długości. Tym niemniej, bez przekształceń wszystkie przestrzenie wyglądałyby tak samo — miałyby początek w tym samym miejscu, te same kierunki i te same jednostki długości. Przekształcenia pozwalają nam zobaczyć punkty “oczami” danego obiektu.

Tak więc jeśli mamy punkt, który w jakiejś przestrzeni ma współrzędne (0, 2, 0), to w innej może mieć współrzędne (-1, 3, 1), pod warunkiem, że punkt (0, 0, 0) tej drugiej przestrzeni będzie względem tej pierwszej znajdował się w punkcie (1, -1, -1), a ich wektory bazowe nie będą względem siebie obrócone ani rozciągnięte. Jak zapewne widzicie, w takiej sytuacji przekształcenie z jednej przestrzeni do drugiej będzie bardzo proste — trudniej robi się kiedy wchodzą obroty i skale.

Niezależnie jednak co zrobimy z przestrzenią względem innej przestrzeni, ona względem samej siebie nigdy się nie zmieni. Inaczej mówiąc, przestrzeń może ulec przekształceniu tylko względem innej przestrzeni. Żeby mieć tłumaczenie, trzeba mieć co i na co tłumaczyć. To ważne, bo dzięki temu wprowadzamy sobie kolejny absolut i doprowadzamy do sytuacji, w której pudełko odwrócone do góry nogami nadal wie, gdzie znajduje się jego faktyczna górna ściana, a nie musi sobie powtarzać “góra na dole, góra na dole, góra na dole”, żeby się nie pomylić. Względem pudełka jego własna górna ściana zawsze jest na górze, tak jak moja głowa zawsze jest na górze względem mojego ciała, nawet jeśli właśnie na niej stoję.

Żeby jednak pudełko wiedziało, że jest do góry dnem, a czasem może mu się ta wiedza przydać, potrzebujemy przekształcenia. Zależność tę zapisuje się przy pomocy macierzy — w gruncie rzeczy bardzo prostego matematycznego tworu, który dźwiękiem swej nazwy wywołuje popłoch u studentów.

Skąd się ją bierze nie będę tłumaczył, ale jest to zwierz o tyle ciekawy, że jeśli nasze pudełko dostanie odpowiednią macierz i wykona na niej proste mnożenie, to będzie wiedziało nie tylko to, co już wie – czyli gdzie, względem niego samego, przyklejono na nim naklejkę this way up, ale również że jego obecne położenie względem przewożącej je ciężarówki (oraz np. asfaltu, po którym się ona porusza), przeczy napisowi na naklejce. Jeśli dostanie tych macierzy jeszcze kilka, to będzie mogło nawet obliczyć swoje położenie względem pana Mietka, co nie jest wcale takie oczywiste, bo pan Mietek jest po fajrancie i jego przestrzeń lokalna jest obrócona, względem okolicznych budynków, nie tylko w osi pionowej…

Hierarchia, czyli jak przekształceniem ułatwić sobie życie

Zostawiając jednak pudełko, ciężarówkę i pana Mietka dodam, że przestrzenie lokalne, jak zapewne już się domyślacie, umożliwiają tworzenie łańcuchów połączonych obiektów. Mogę na przykład powiedzieć silnikowi gry, że obiekt A ma znajdować się na prawo od B. I choćby nie wiem co działo się z B względem C, to A względem B zawsze będzie po jego prawicy. To tak, jak z dłonią człowieka. Niezależnie jak poruszam ramieniem w barku, albo przedramieniem w łokciu, moja dłoń nadal wie, że ma się znajdować na końcu przedramienia. Orientacja przedramienia względem ramienia, czy ramienia względem reszty ciała, kompletnie jej nie interesuje – ona wie, że ma się trzymać przedramienia i kropka. Gdyby musiała cały czas martwić się swoim położeniem względem reszty ciała, to pewnie szybko by się zmęczyła i odpadła.

W rzeczywistości takie przeliczenia wykonujemy każdego dnia, kompletnie o nich nie myśląc – jesteśmy do nich ewolucyjnie przystosowani, można by rzec. Np. kiedy mówimy, że sklep jest 20 metrów na lewo ode mnie, to operujemy swoją przestrzenią lokalną i przekształcamy (bezwiednie) kierunki świata (czy, chociażby, rozmówcy) na nasze lokalne kierunki, które zmienią się kompletnie kiedy tylko się obrócimy – wtedy sklep może być przed nami, po prawej lub z tyłu. Jednocześnie czasem z operowania różnymi przestrzeniami i przekształceniami pomiędzy nimi wynikają problemy – nie wiem jak Wy, ale ja nigdy nie mogę trafić w odpowiednie miejsce kiedy ktoś na swojej twarzy pokazuje mi, gdzie się upaćkałem. Po prostu nigdy nie wiem, czy ta osoba operuje w tej chwili swoją przestrzenią, czy moją. W tym wypadku najgorsze co może się stać w razie niewłaściwego doboru przekształcenia to wytarcie niewłaściwego policzka. W grze, gdzie na przekształceniach opiera się wyświetlenie gotowego świata, problem jest znacznie istotniejszy, bo w razie pomyłki rezultat może wyglądać znacznie bardziej dziwnie niż najbardziej pomysłowe obrazy kubistów.

Podsumujmy więc ten krótki wykład z algebry liniowej (przeprowadzony, o dziwo, przy bardzo ograniczonym udziale formalnych zapisów algebry liniowej). Przestrzeń to zbiór wektorów ze zdefiniowanym dodawaniem i mnożeniem. Wyznaczają ją wektory jednostkowe prostopadłe do siebie, zwane bazą przestrzeni. Każdy obiekt ma swoją przestrzeń lokalną, a przestrzeń wszechświata gry nazywamy przestrzenią globalną. Przestrzenie lokalne i przekształcenia są ważne, bo wprowadzają względność współrzędnych i upraszczają tworzenie oraz manipulowanie połączonymi obiektami.

Dziękuję za dzisiaj i zapraszam po więcej

Mam nadzieję, że po przeczytaniu tego wszystkiego nie boli Was jeszcze głowa. Mam też nadzieje, że ograniczenia mojej wiedzy nie spowodowały wprowadzenia Was w błąd — jeśli tak, to przepraszam i mam nadzieję, że ktoś mnie poprawi. Tak czy siak, najtrudniejszą część mamy za sobą, teraz czeka nas część bardziej praktyczna, bo zaprzęgniemy przytoczone pojęcia do zrozumienia co karta graficzna, nagięta do woli programisty (i marketingowców…), robi z tymi wszystkimi matematycznymi wynalazkami. Oczywiście zostało jeszcze kilka pojęć, ale wynikają one z powyższych w sposób tak bezpośredni, że będę je po prostu wplatał w kolejne teksty — jeśli zrozumieliście dzisiejszy wykład, to z kolejnymi też nie powinniście mieć problemu.

Czym więc zajmiemy się w dalszej kolejności? Przede wszystkim będziemy kontynuować temat trójkątów i zobaczymy jak przy pomocy atrybutów przypisanych do wierzchołków pokolorować trójkąt, nałożyć teksturę na obiekt, a także dowiemy się jak wyświetlić owe trójkąty na ekranie i, co ważniejsze, jak to zrobić żeby się nie narobić. Do zobaczenia (oby szybciej tym razem).

Czy są jakieś pytania?

  • http://www.alchemyarts.pl/ digital_cormac

    Świetnie napisane, prościej już chyba się nie da. A teraz słowa otuchy, dla wszystkich, którzy uciekli na koniec tekstu zaraz po przeczytaniu słowa “matematyka” -  to matma ze szkoły średniej, w dodatku chyba najprostsza część materiału. Dodawać i mnożyć chyba każdy potrafi nie? :)

  • Siergiej

    Będziemy kontynuować temat trójkątów – to mi się podoba ;)

    • Coppertop

      Rotfl

  • kornick

    Ja do tego tekstu podszedłem z pewną taką nieśmiałością, ale rozbroił mnie pan Mietek i ciężarówka. Jestem lajkonikiem a załapałem sporo. 

    Naprawdę fajne. Kolejny udany cykl na Grastroskopii który koniecznie musi być kontynuowany. W ogóle macie jaką dobrą rękę do cykli artykułów. Co nie wymyślicie to jest udane :)

  • Gant

    Przeczytałem choć się też bałem. WERY NAJZ !!!! KONTINJU PLIZ !

  • polo_tuc

    Kurcze dopiero teraz miałem czas to na spokojnie przeczytać. Świetny tekst, otworzył mi parę klapek w mózgu lajkonika :) Np. kwestia przekształceń.
    Jeżeli spodziewałeś się coppertop merytorycznej dyskusji, to ja ci powiem to czego większość się boi: mam pytania o to co napisałeś, ale obawiam sie, że sformułuję je w sposób krytycznie ignorancki.

    Robisz za profesora na oddziale. Kiedy następny wykład,p.profesorze?

    • Coppertop

      To się nie bój, bo nie ma czego — nie ważne jak głupie Ci się wydaje pytanie, ja się będę śmiać tylko ze szczęścia, że pytania SĄ.

      Krótko mówiąc, nie jesteśmy w liceum czy na studiach — tu z pytania wyniknie fajna dyskusja, a nie powtarzanie klasy. Co za pożytek z tego tekstu jeśli w głowie zostanie Ci dziura, którą boisz się zapełnić? Nie chciałbym, żeby jakiś drobny czy nie brak tego tekstu sprawił, że klocki Ci w głowie nie wpadną na miejsce.

      A jak Ci brakuje słów na opisanie pytania, to machnij obrazek w paincie albo zrób interpretive dance ;) NIKT Cię krytykować nie będzie — ja na pewno tego nie zrobię, a za wyśmiewanie niezawinionej przecież niewiedzy będzie autoban.

      Sam tekst też nie jest przecież napisany akademickim, formalnym językiem. Zresztą, pewnie nie potrafiłbym go tak napisać, bo mam do matematyki stosunek czysto praktyczny — interesuje mnie to, co potrzebuję wiedzieć i znajduję to wtedy, kiedy tego potrzebuję. Dla mnie matma jest jak samochód — jak działa i dlaczego mniej więcej wiem, ale przede wszystkim interesuje mnie gdzie jest kierownica i który pedał do czego.Ja chcę Wam pokazać, że choć nomenklatura i skomplikowane zapisy mają swoje miejsce i wartość (gigantyczną, bo bez nich nie mielibyśmy całej masy fajnych gadżetów, z LHC na czele lol), to na pewno nie tutaj i na pewno nie są konieczne do wykorzystywania matematyki w sposób twórczy i zabawny za pomocą komputera. Learning curve matematyki i tematu “jak komputer to robi” nie jest pionowe.

      Taki mój niebywale skromny wkład w naprawę szkód jakie, zwłaszcza właśnie w materii nauk ścisłych, masowo wyrządza ludziom ten intelektualny holokaust zwany systemem edukacji i szkolnictwa wyższego. Rzekłem ;)

      • polo_tuc

        Ok, zastanawia mnie kwestia liczenia kolizji obiektów. Zakładam, że przestrz. lok. to jeden, widoczny w grze obiekt, np. piłka czy skrzynka. Zakładam też, że w grze można przestrzeniom lok. przypisać oprócz x,y,z jeszcze prędkość.
        Jeżeli zderzymy dwie kuliste przestrzenie lokalne to dość łatwo i efektywnie możemy policzyć wektory ich ruchu, (może zostanie nawet trochę mocy na uwzględnienie sprężystości :) W takim modelu punkt zderzenia obiektów jest jeden i łatwo(?) wyznaczyć moment, w którym należy wektory przeliczyć. Natomiast nie bardzo sobie wyobrażam efektywne przeliczanie np, dwóch prostopadłościennych przestrzeni – ale, kurde, pudełko na pudełko można było już układać w Thiefie :)
        Zatem, jak przypisuje się do przestrzeni lokalnej jej prędkość ? A ciężar?
        (może ciężar jako funkcję prędkości w przestrzeni globalnej?)

        No nie wiem, czy udało mi się wyrazić precyzyjnie. Ale. ostatecznie tylko Królowa jest naprawdę precyzyjna..

        • Coppertop

          Kurwa, napisałem za długi koment i mi go Disqus spieprzył… Jak za starych czasów… lol

        • Coppertop

          Hm, jeden misunderstanding na start. Obiekt != przestrzeń. Do każdego obiektu przypisana jest jego własna przestrzeń, ale to nie znaczy, że obiekt jest przestrzenią.

          W sumie obawiałem się, czytając po raz n-ty ten tekst, że ktoś może wyprowadzić z niego takie wnioski. To powinno stać się jaśniejsze po następnym tekście — szkoda, że w tym nie bardzo wiedziałem jak opisać to jaśniej.

          Przestrzeń to zbiór punktów, który sam w sobie jest nieskończony i rozłazi się po całym wszechświecie gry. I to dotyczy każdej przestrzeni, tak globalnej jak i każdej przestrzeni lokalnej.

          Tzn. że przestrzeń nie kończy się na obrębie obiektu. Przestrzeń nie może też być kulista czy jakkolwiek inaczej kształtna, bo jest po prostu nieskończona w każdym wymiarze (no, w kompie z tą nieskończonością to nie do końca, ale matematycznie tak to wygląda).

          To znaczy, że przestrzenie się nakładają i zawierają w sobie. Każda obejmuje dokładnie ten sam obszar — cały obszar gry.Tak więc przestrzeń nie jest zjawiskiem fizycznym a, powiedzmy, abstrakcyjnym. Chodzi w niej li tylko o układ wektorów bazowych, a więc osi układu współrzędnych, względem innych przestrzeni. Dlatego A) mamy przestrzeń globalną, która wyznacza nam choć jeden układ, do którego zawsze się możemy odwołać jako do nieruchomego wyznacznika i B) dlatego przestrzenie lokalne nie mają sensu bez przekształceń.

          Pkt. A oznacza, że przestrzeń globalna jest jak poziomica — jeśli wektory bazowe i początek (punkt (0, 0, 0)) danej przestrzeni pokrywają się ze swoimi odpowiednikami w przestrzeni globalnej, to mówimy że obiekt nie jest ruszony, przesunięty, obrócony itd.

          Pkt B natomiast oznacza, że jeśli nie zastosujemy odpowiedniego przekształcenia, to wszystkie przestrzenie będą identyczne — takie, jak nasza przestrzeń globalna.

          Inna ważna rzecz to to, że każda przestrzeń zawiera w gruncie rzeczy te same punkty — po prostu mają one inne współrzędne w każdej z nich. Współrzędne to bowiem nic innego jak odpowiedź na pytanie “przez jakie liczby muszę pomnożyć każdy wektor bazowy żeby dojść w dane miejsce”. A ponieważ każda przestrzeń zawiera wszystkie punkty i się nie kończy, to mogę powiedzieć, że mgławica w andromedzie ma środek w punkcie jakimś-tam mojej przestrzeni lokalnej. I mogę ten punkt wyznaczyć (teoretycznie, praktycznie nie zamierzam, lol), tyle że jego współrzędne będą się zmieniać jak tylko się obrócę albo przesunę kawałek — bo wtedy, parząc z mojego punktu widzenia, Andromeda przesunie się i obróci wokół mnie. Tak jak jadąc autobusem mogę mówić, że ja się nie ruszam, a asfalt tak — i z punktu widzenia względności będzie to prawda.

          W rzeczywistości takimi absurdami posługujemy się codziennie, tylko nie zauważamy tego — np. mówimy, że słońce jest na górze. Nie jest — to my jesteśmy na orbicie wokół słońca. Ale ta druga wersja to wersja względem przestrzeni lokalnej słońca — w naszej, to słońce jest na górze (albo na dole, kiedy jest noc).

          Zdajesz się myśleć, że przeliczenia z przestrzeni do przestrzeni wymagają ogromnych nakładów mocy obliczeniowej, a to nie prawda. To jest proste mnożenie i dodawanie kilku liczb, czyli mnożenie wektorów przez matryce (albo odwrotnie, nie pamiętam — a tutaj to akurat ma znaczenie).

        • Coppertop

          Nawiasem mówiąc, mylisz się sądząc, że punkt zderzenia dwóch kul jest jeden. Nie zapominaj, że przestrzeń i czas w grze nie są analogowe (w rzeczywistości z resztą też nie, ale mniejsza z tym). Istnieją tu klatki, których jest relatywnie mało. Szybko poruszająca się kula znajdzie się poza obrębem innej w jednej klatce, a w następnej znajdzie się już wewnątrz tej drugiej kuli. Dlatego punktów przecięcia tych kul będzie nie jeden, a nieskończenie wiele (okrąg wyznaczony przez płaszczyznę, a nie punkt, styku).

          Dlatego w przypadku kul sprawa jest prosta — jeśli wektor poprowadzony od środka jednej do środka drugiej jest krótszy niż r1 + r2 (promienie kul razem), to mamy tzw. penetrację (bez skojarzeń!!), której głębokość wyznacza różnica (r1 + r2) – długość-wspomnianego-wektora.

          Z innymi bryłami rzeczywiście jest trudniej, ale tak naprawdę nadal nieskończenie wiele punktów mamy tylko w teorii. W praktyce jest masa sposobów na ograniczenie tego do dosłownie kilku punktów.

          A jak przypisuje się wartości fizyczne? To jest temat zupełnie odrębny od detekcji kolizji i renderingu. Tak jak wyświetlana bryła ma niewiele wspólnego z bryłą używaną do detekcji kolizji, tak kształt obiektu, czy jednego czy drugiego, nie ma związku z jego fizyką. Tak, zupełnie inaczej niż w rzeczywistości.

          Masa to de facto prosta wartość, nawet nie wektorowa. Oczywiście ma ona jakiś kształt, ale często kompletnie oderwany od tego, co widać na ekranie, a służący tylko opisaniu jak masa rozkłada się po obiekcie w symulacji.

          Tak czy siak, nie ma sensu zajmować się masą i kolizjami kiedy mowa o renderingu, bo te dwie rzeczy leżą cholernie daleko od siebie :). Są ze sobą niemal całkowicie niepowiązane. No dobra, trochę są, ale w bardzo ograniczonym stopniu i zajmują się tym zupełnie odrębne kawałki kodu — dlatego każdy silnik fizyki czy detekcji kolizji można wykorzystać z każdym silnikiem grafiki 3D. One są po prostu od siebie całkowicie niezależne.

          Mam nadzieję, że nie zagmatwałem ;D

          • polo_tuc

            Dzięki za odpowiedź. Jak dla mnie całkiem zrozumiałą. Co jest pewnym osiągnięciem ze względu na stopień zwapnienia mojego mózgu :)

            A z (tylko trochę) innej beczki: Kojarzysz taki hype’owy projekt – niestety nie mogę znaleźć linka – polegający na jakimś nowym sposobie renderowania grafiki, że no “mega turbo hiper dokładnie całą kulę ziemską raz dwa na Celeronie”
            Wiem to żaden namiar, ale miało to dużo cech medialnej wrzuty czy wręcz miejskiego mitu. Pamiętam te flejmy “czy to wogóle możliwe” itd?
            Pamiętasz coś, jak to się nazywało? 12-18 miesięcy temu?

          • polo_tuc

            ha! mam!: http://unlimiteddetailtechnology.com/home.html

            Sądząc po marwej, prawie-wordowskiejstronie internetowej już po wszystkim:)
            Ciekaw jednak jestem jaki był ich pomysł na otumanienie publiki:

            showed a tree base from one of today’s games with 3 flat sides, Fig 1.3 shows a tree base made on Unlimited Detail with 300,000 flat sides, the polygon tree needs special high powered graphics cards and multi-core computers to run it.  The Unlimited Detail tree will run on anything from a PC to a mobile phone and no special graphics cards are needed.

            cieeekaweee…. :)

            przepraszam, że nie zrobiłem editu jak człowiek ale w pracy mam IE7 arghh….

          • Coppertop

            Tak, Unlimited Detail to jest właśnie Sparse Voxel Octree wspomniane w tekście.

            Tutaj masz Carmacka mówiącego na ten temat.http://www.youtube.com/watch?feature=player_detailpage&v=hapCuhAs1nA#t=1034s

            W tekście napisałem, że prawdopodobnie właśnie do SVO będzie należeć przyszłość, ale choć osobiście mam jakąś słabość do voxeli to powinienem to doprecyzować — przyszłość będzie należeć do SVO jeśli odejdziemy od polygonów. I, tak jak mówi Carmack, na pewno będą w tym kierunku czynione coraz śmielsze próby wraz z rozwojem technologii. Czy okaże się to drogą do przyszłości, czy ślepą uliczką? Nie wiem, ale jak mówię, mam słabość do SVO — chyba po prostu lubię kiedy w technologii coś się dzieje, bez względu na rezultaty. Osobiście uważam, że gdyby udało się połączyć ray tracing w svo z rasteryzacją albo klasycznym ray tracingiem, to ten pierwszy mógłby dać trochę przewagi w organicznych kształtach, w których fakt, że jest to rodzaj stratnej kompresji zwykle nie ma większego znaczenia pod warunkiem, że nie jest zbyt stratna i twarze postaci nie zaczynają się rozkładać.

  • Bariczello

    uhm całkiem spoko art. naprawdę dobrze się czyta choć nie sądzę abym zrozumiał wszystko w 100% :)

    Zachęcony do zadawania pytań i sugestii to miałbym taką, że możnaby w kolejnych odsłonach Ga przybliżyć coś z technikaliów kart graficznych albo coś o Directx No nie wiem coś w ten deseniek.

    • Coppertop

      Oczywiście w tym kierunku zmierza cykl :). W kolejnych tekstach będzie o rasteryzacji, o shaderach itd.

      Po prostu musiałem napisać jeden tekst teorii, żebym później nie musiał wplatać definicji w kolejne teksty. Jak napisałem, chodzi mi o faktyczne wyjaśnienie całego procesu, a to wymaga operowania tymi kilkoma dosłownie pojęciami z algebry liniowej (wektor, punkt, przestrzeń, przekształcenie). Wcześniej próbowałem pisać bez tego lub wplatać w tłumaczenie tych bardziej znajomych rzeczy (znajomych ze słyszenia, jak shader, kamera itd), ale wychodziło to kulawo. Teraz będzie mi znacznie łatwiej.

      Temat shaderów będzie poruszony, do pewnego stopnia, już w kolejnym tekście. Nie wiem czy zmieści się tam temat różnic między kolejnymi wersjami shaderów, ale z pewnością będę miał to na pewno na uwadze.

      Mam nadzieję, że dobrze zrozumiałem intencję pytania :)

  • kornick

    No tak za rok okaże się, że Copper odkrył przekaźniki Masy w galaktyce i wraz z ekipą wyruszył na bój ze Żniwiarzami. Bronią Ziemian była matematyka, której paskudy z kosmosu ni w ząb nie rozumiały.
     
     
    To wcale nie żart bo Kosmici już dokonują w Polsce Indoktrynacji zamieniając maturę z matematyki w bzdurę. Nawet mój koń zdałby maturę z matmy.
     
    http://wiadomosci.gazeta.pl/wiadomosci/1,114883,11697173,Zadania_na_maturze_z_matematyki_tak_proste__ze_kraza.html
     
     
    Poważnie mówiąc fajno że spełniacie deklarację z zerowego ObchoduT o różnorodności artykułów na G.

    Siedzę na koniu!