system do animacji postaci w grach komputerowych Rafał Rudnicki Vertex 2010
plan prezentacji ważne pytania cele systemu animacji obliczanie klatki interpolacja graf animacji zapętlanie animacji przejścia wyzwalacze wdrażanie animacji i przykładowe rozwiązanie
ważne pytania czy będziemy korzystać z motion capture? czy tylko animacje tworzone ręcznie? czy interesuje nas fizyka animacji / efekty IK? czy postać będzie składała się z kilku siatek? czy chcemy mieć jej bounding-boxa i czy ma być to AABB czy OBB? czy chcemy mieć ładne przejścia między animacjami? czy sami je zrobimy? czy chcemy mieć animacje proceduralne (np. postać chodzi ale mierzy ręką w stronę wroga)?
cele systemu animacji animacja oparta o animację kości oddzielenie wyglądu siatki od jej animacji łatwe dodawanie obsługi animacji postaci do istniejącego kodu gry 3D oddzielenie animacji od logiki animacji umieszczene animacji i logiki animacji w zasobach tak, by unikać potrzeby rekompilacji kodu gry proste sterowanie animacją Rafał Rudnicki Vertex 2010
cele systemu animacji (2) płynna animacja (maksymalne) wykorzystanie GPU
animacja animowane modele = model + animacja dla podejścia mesh skinning (w tym SSD) kluczowy jest szkielet szkielet = pozycje i orientacje kości + hierarhia kości
obliczanie klatki animacji w pliku - jak trzymać kości? w przestrzeni rodzica w przestrzeni modelu przestrzeń rodzica: lepsza interpolacja międzyklatkowa w przypadku łańcuchów kości (uwzględnia obrót rodzica) szkelet przetwarzany BFS/DFS od korzenia słabe zrównoleglanie przestrzeń modelu można przetwarzać równolegle nie umożliwia efektów typu IK liczonych realtime jeżeli nie potrzebne nam IK to oszczędzimy sporo mocy
obliczanie klatki animacji (2) skąd pochodzą dane: z pliku z modułu fizyki / AI z mixu różnych źródeł liczy się aby co klatę otrzymać zestaw macierzy dobry system animacji nie rysuje niczego zestaw końcowych macierzy (+ inne dane) wystarcza = przenośność i elastyczność
obliczanie klatki animacji (3) geometria dopasowuje się do szkieletu SSD (Skeletal Subspace Deformation) uwaga na błędy na łokciu / kolanie
obliczanie klatki animacji (4) w praktyce wystarczają max. 4 kości na wierzchołek (tak zrobił ID Software w MD5) co bardzo cieszy GPU animacja dzieje się w Vertex Shaderze np. GLSL: skinned_position += weights.x * (bonematrices[int(matrixindices.x)] * gl_vertex); skinned_position += weights.y * (bonematrices[int(matrixindices.y)] * gl_vertex);...
interpolacja klatek dane animacji mają skończoną dokładność mając dane dot. klatki m i n musimy: obliczyć chwile t n i t m odpowiadające tym klatkom obliczyć w jakim stopniu (0 1) zmiksować dane potrzeba przechowywać dane m i n wraz ze zmianą klatki obliczać tylko te, które nie są jeszcze wyliczone/które się zmieniły być może m i n będą dotyczyć różnych animacji Rafał Rudnicki Vertex 2010
0,00 0,10 0,20 0,30 0,40 0,50 0,60 0,70 0,80 0,90 1,00 1,10 1,20 1,30 1,40 1,50 1,60 1,70 1,80 1,90 2,00 2,10 2,20 2,30 2,40 2,50 2,61 2,70 2,80 2,91 3,00 3,11 3,21 3,30 3,41 3,51 3,61 3,71 3,80 3,91 4,01 4,11 4,21 4,31 4,41 4,51 4,61 4,71 4,81 4,91 interpolacja klatek (2) 6 łączna różnica położeń i kątów kości - jakość pierwotna; 25 fps 5 4 dpos dort błędne zapętlenia animacji 3 2 1 0
0,02 0,10 0,20 0,30 0,41 0,52 0,61 0,71 0,82 0,91 1,02 1,12 1,21 1,32 1,42 1,52 1,62 1,72 1,82 1,92 2,02 2,12 2,22 2,32 2,42 2,52 2,62 2,72 2,82 2,92 3,02 3,12 3,22 3,32 3,42 3,52 3,62 3,72 3,82 3,92 4,02 4,12 4,22 4,32 4,42 4,52 4,62 4,72 4,82 4,92 interpolacja klatek (3) 6 łączna różnica położeń i kątów kości - jakość 1/8; 3,125 fps 5 dpos dort błędne zapętlenie danych 4 3 2 1 0
0,00 0,10 0,20 0,30 0,40 0,50 0,60 0,70 0,80 0,90 1,00 1,10 1,20 1,30 1,40 1,50 1,61 1,70 1,80 1,91 2,00 2,11 2,21 2,30 2,41 2,51 2,61 2,71 2,80 2,91 3,01 3,11 3,21 3,31 3,41 3,51 3,61 3,71 3,81 3,91 4,01 4,11 4,21 4,31 4,41 4,51 4,61 4,71 4,81 4,91 interpolacja klatek (4) 6 łączna różnica położeń i kątów kości - jakość 1/8; 3,125 fps; interpolacja 5 4 dpos dort błędne zapętlenia animacji 3 2 1 0
interpolacja klatek (5) efekt interpolacji międzyklatkowej: płynniej mniejsza ilość danych (do 8x niezauważalna) mniejsza szczegółowość animacji
interpolacja klatek (6) macierze czy inne reprezentacje? (w SSD) przed wysłaniem należy przemnożyć przez odwrotną macierz kości w rest pose
interpolacja klatek (7) macierze: 3x4 lub 4x4 dobre dla GPU słabo się intepolują (liniowo wzór jest skomplikowany, w praktyce nie da się bez konwersji na inne typy) wektor pozycji + wektor Eulerowski / axis-angle: dobre dla GPU słabo interpolowane (błędy) wektor + kwaternion przed wysłaniem do GPU należy przerobić na macierz bardzo dobrze interpolowane (lerp + slerp)
interpolacja klatek (8) pozycja interpolowana liniowo (lerp, mix) zachowanie prędkości liniowej orientacja interpolowana sferycznie (slerp, mix) zachowanie prędkości kątowej
grafy animacji typowa gra akcji: stanie, bieg do przodu, odskok do tyłu, chodzenie do przodu, skakanie, pochylenie się, chodzenie pochylonym, krok w prawo / lewo, atak bronią palną, atak bronią krótką, zmiana broni, radość po zabiciu, przeżywanie bólu, śmierć dla gracza liczy się zarówno jakość animacji jak i czas trwania przejścia wojny o to, by w FPP przejścia były krótkie zmiana broni w Quake III to 0.6s
grafy animacji (2) prosty przykład: ile trwa oryginalna animacja walk/stand_cycle? ile może trwać?
zapętlanie animacji (cykle) w zależności od źródła danych: jeżeli animację tworzymy ręcznie to mamy szansę ją idelanie zapętlić jeżeli źródłem jest motion capture to nie tak samo przy animacjach proceduralnych
zapętlanie animacji (cykle) (2) rozwiązanie self fading (wygładzanie) musimy je robić od pierwszego przejścia przez koniec pętli (podczas pierwszego przejścia przez początek pętli jest dobrze) parametr - długość
0,00 0,10 0,20 0,30 0,40 0,50 0,60 0,70 0,80 0,90 1,00 1,10 1,20 1,30 1,40 1,50 1,60 1,70 1,80 1,90 2,00 2,10 2,20 2,30 2,40 2,50 2,61 2,70 2,80 2,91 3,00 3,11 3,21 3,30 3,41 3,51 3,61 3,71 3,80 3,91 4,01 4,11 4,21 4,31 4,41 4,51 4,61 4,71 4,81 4,91 zapętlanie animacji (cykle) (3) 6 łączna różnica położeń i kątów kości - jakość 1/8; 3,125 fps; interpolacja; wygładzanie 3 klatki 5 4 dpos dort 3 wygładzone zapętlenia animacji 2 1 0
przejścia gracz naciska klawisz (wyzwalacz) animacja dochodzi do pewnego momentu (może być natychmiast) (opcjonalnie) odgrywane jest przejście do nowego stanu animacji odtwarzana jest nowa animacja
przejścia (2) automatyczne wyznaczanie przejść w systemach opartych o motion capture skomplikowane.. ;/
przejścia (3) problem: ile to trwa? czy jest grywalne? po podzieleniu cyklu na kilka części można szybciej dojść do przejścia np. prawa-lewa noga, lewa-prawa noga dla chodzenia idealnie pozwolić na natychmiastowe odtwarzanie przejścia ale w wielu przypadkach źle to wygląda skomplikowanie (ilość animacji/przejść) ~ 1/jakość
przejścia (4) problem 2: nie da się natychmiast przejść z animacji leżenia do animacji biegania problem 3: nie da się z biegu natychmiast zatrzymać
przejścia (5) cześć przejść można wyliczyć, część trzeba samemu stworzyć dla animacji mocap można je łatwo zdobyć efekt: przejść jest duuużo animacje cykli muszą być porozdzielane na wiele kawałków należy stworzyć graf legalnych przejść pomiędzy węzłami (logika animacji) ciężko to utrzymać i sporo się trzeba napracować
przejścia (6) parametry: długość (czasem definiuje początek i koniec) charakterystyka czasowa
przejścia (7) 12 łączna różnica położeń kości dla różnych funkcji przejścia - jakość 1/8; 3,125 fps 10 8 linear quad in quad out quad-inout 6 4 2 0
wyzwalacze kiedy przejść? input od gracza fizyka AI koniec animacji funkcja bool fun(void) wyzwalacz rejestracja wyzwalaczy mapa <string, callback>
wyzwalacze (2) kiedy przejść? zaraz po naciśnięciu odczekać do przejścia co jeżeli wyzwalacz został uruchomiony po idealnym momencie? przejść z mniejszą długością czekać na następny
wdrażanie animacji do gry np. Blender: stworzenie modelu / animacji być może skorzystanie z animacji mocapowych eksport do wybranych formatów (opcjonalny edytor:) stworzenie przejść stworzenie logiki przejść (grafu) silnik gry / kod gry: uaktualnianie pozy wyświetlanie
wdrażanie animacji do gry (2) przykładowy eksporter
wdrażanie animacji do gry (3) edytor
wdrażanie animacji do gry (4) psmodeldata md = loadmodeldatafromfile("ludwig.model"); model = createmodelfrommodeldata(md); psgraphdata gd = loadgraphdatafromfile("ludwig_walkrun_lowres_2.graph"); psgraph graph = creategraphfromgraphdata(gd); psanimation animation = createnullanimation(); setanimationgraph(animation, graph); setanimationsource(animation, AnimationSource::GRAPH); setanimationstartnd(animation, "walk_passing P-L"); registertransitiontrigger("keyup_a", checkkeyupa); registertransitiontrigger("keydown_a", checkkeydowna);... setanimationstate(animation, AnimationState::PLAY);
wdrażanie animacji do gry (5) // kod w pętli czasu... advanceanimation(animation, time - lasttime); updatemodel(animation, model);... // kod w funkcji wyświetlającej... glloadidentity(); drawanim(model, transformmatrix);...