7193


Zaawansowane i efektywne systemy cząsteczkowe w grach komputerowych.

Michał Mocarski

Politechnika Wrocławska

Streszczenie

Referat opisuje systemy cząsteczkowe jako narzędzie do generowania efektów specjalnych w grach komputerowych. Omówione zostaną zastosowania, sposoby przedstawienia reprezentacji graficznej i fizycznej cząstek, techniki animacji cząstek i nietypowe podejścia do systemów cząsteczkowych.

- ogień

- dym

- wystrzały

- śnieg

- deszcz

- wybuchy

- gwiazdy

itp.

Poszczególne cząsteczki mogą być bardzo zróżnicowane - zwykły punkt jest przeważnie niewystarczający, jednak przeważnie są stosunkowo małe i płaskie. Możemy je zatem wyświetlać za pomocą zbioru quadów (Rys 3.1) umieszczonych w vertex buforach. Rozwiązanie takie jest stosunkowo proste i bardzo elastyczne.

0x01 graphic

Niestety w jego przypadku musimy skupić się na pozycji wierzchołków - muszą one być za każdym razem aktualizowane by znajdowały się w takiej samej odległości od środka cząsteczki i żeby leżały na płaszczyźnie, która jest prostopadła do kierunku patrzenia kamery.

Innym sposobem jest użycie tzw. Point sprite'ów. Są one bardzo wygodnym i dosyć optymalnym spodobem na renderowanie cząstek, gdyż umożliwiają nam łatwe renderowanie cząsteczki przy pomocy jednego oteksturowanego punktu - karta graficzna zajmuje się wygenerowaniem dodatkowych wierzchołków, skopiowaniem wartości koloru i przypisaniem im koordynat teksturowania tak, by można było osiągnąć efekt taki jak przy renderowaniu zwykłego quadu. Wydaje się to świetnym rozwiązaniem, jednak okazuje się iż ma pewne wady - wszystkie wartości wierzchołka źródłowego są kopiowane do nowo utworzonych przez co nie mamy wpływu na informacje o kolorze poszczególnych rogów punktu i wierzchołki są nierozróżnialne. Ponadto koordynaty teksturowania i pozycje nowych wierzchołków są generowane dynamicznie, bez naszego wpływu na nie. Powoduje to, iż na samym starcie część bardziej zaawansowanych technik jak obrót cząsteczek czy uzyskanie specjalnych cech dla każdego wierzchołka jest niemożliwe. Dochodzą do tego dodatkowe problemy - teoretycznie nie każdy sprzęt musi obsługiwać point sprite'y (a część urządzeń realizuje je w sterownikach mimo iż zgłaszają, że wspierają je) a ponadto maksymalna wielkość cząsteczek określana jest przez kartę graficzną i może się różnić między modelami. Kolejną niedogodnością jest różnica między PointSprites w DirectX, a rozszerzeniem arb_point_sprites w OpenGL. Windows DDK nakazuje nadmienić koordynaty teksturowania liniowo generowanymi współrzędnymi (lewy górny róg [0,0] a prawy dolny [1,1]) jednak nie opisuje on które współrzędne mają być nadpisane, ponadto DirectX nie umożliwia ich wskazania, przez co nadpisywane są profilaktycznie wszystkie. Uniemozliwia to zastosowanie bardziej zaawansowanych technik, gdyż na drodze między Vertex Shaderem a Pixel Shaderem zostają nadpisane wszystkie współrzędne teksturowania. Nieco lepiej sytuacja wygląda w OpenGL - rozszerzenie arb_point_sprites używa flag do oznaczenia współrzędnych teksturowania. Druga różnica między OpenGL'em a DirectX'em to sposób odrzucania niewidocznych punktów. Tutaj lepiej wypada DirectX, gdyż WindowsDDK nakazuje odrzucać karcie punkty których wszystkie wierzchołki wypadają poza viewport. OpenGL przycina według środka punktu, więc może on nagle zniknąć.

Vendor

Device

MaxPointSize

3Dfx

Voodoo3

1.0

Ati

Mobility Radon X800GT

256.0

Ati

Radon 9600

256.0

Ati

Radon 9000

256.0

Intel

i815

256.0

Matrox

G550

128.0

Nvidia

GeForce 6800

8,192.0

Nvidia

GeForce FX 5200

8,192.0

Nvidia

GeForce4 MX 440

64.0

Nvidia

GeForce2 MX 400

64.0

Nvidia

Riva TNT2 M64

1.0

S3

ViRGE DX

1.0

Tabela 3.1 - porównanie MaxPointSize

W układzie tym renderujemy najpierw nasz heightfield do tekstury, zachowując wartość wektora normalnego w każdym z wyrenderowanych punktów i współrzędną z, która będzie odpowiadała po przetransformowanie przez macierz kamery, odległości danego punktu od kamery(R,G,B -> współrzędne wektora normlnego, A-> z). Mając te dane możemy teraz wyrenderować nasze punkty - każdy z nich transformujemy do naszego układu. Zauważmy, że współrzędne x,y będą odpowiadały pozycji na płaszyźnie, co możemy użyc jako współrzędne teksturowania, a współrzędna z jak poprzednio będzie odpowiadała odległości od kamery. Gdy będzie ona mniejsza od odczytanej z tekstury, to musimy „odbić” nasz wektor prędkości względem wektora normalnego odczytanego z tekstury. Oczywiście opisany algorytm jest bardzo skomplikowaną, ogólną wersją i w zależności od potrzeb można zastosować wiele uproszczeń (np. korzystać z gotowego heightfielda i tekstury z normalnymi dla niego i po prostu rzutować wierzchołki na płaszczyznę go opisującą, jednak opisany przeze mnie sposób będzie wykorzystany w daleszej części prezentacji). Nie jest to rozwiązanie elastyczne w 100%, ale stosunkowo optymalne i co więcej - w całości wykonywane na karcie graficznej.

Kolejną kwestią jest sortowanie cząsteczek. Gdy używamy alpha blendingu, to wymagane jest, by cząsteczki były narysowane w kolejności od najbardziej odległej w stosunku do kamery, do tej najbliższej. Często, gdy nie korzystamy z alpha blendingu, bądź fragmenty przezroczyste są znikome i nie będzie widać błędów alpha-blendingu, sytuację możemy zignorować. W przeciwnym wypadku pozostaje nam implementacja particle systemu na CPU, lub… Sortowanie przy pomocy GPU. Istnieje algorytm bitonic sort, umożliwiający GPU sortowanie równoległe. Niestey odbija się to dodatkowo na wydajności i komplikuje sytuację.

analogicznie w płaszczyznach y i z. Ponadto aby uatrakcyjnić wygląd parametry są w pewnym zakresie losowe, a równanie modulowane jest funkcją sinus. Nasuwa się pytanie - w jaki sposób utrzymać ciągłość spadania cząsteczek? Odpowiedź jest prosta możemy modyfikować bufor wierzchołków, by zmienić parametry początkowe co jakiś czas, albo użyć funkcji okresowej. W mojej implementacji używam operacji dzielenia modulo przez okres funkcji - czyli średni czas potrzebny cząsteczce na przebycie drogi od stanu początkowego do końcowego (tutaj do najniższego punktu na levelu). Istotną kwestią jest też odpowiednie rozrzucenie cząsteczek w pionie(przykładowo dodanie każdej cząsteczce losowego offsetu z zakresu [0,T], gdzie T jest okresem i dodanie powyższego offsetu do aktualnej różnicy czasu) i zróżnicowanie parametrów prędkości, by cząsteczki nie spadały jednostajnymi falami tylko w sposób ciągły wizualnie. Taki system umożliwia uzyskanie wydajności rzędu setek tysięcy cząsteczek, więc można go stosować na dużych przestrzeniach i symulować nim efekty atmosferyczne. Jednak należy uciec się do pewnej sztuczki - kamera powinna przy każdym zbliżeniu/oddaleniu obejmować obszar na którym występują nasze cząsteczki, wtedy można dokonywać ich translacji przez macierz obrotu kamery. Jak uzyskać złudzenie ruchu względem cząsteczek? Najprościej wyznaczyć wektor ruchu kamery i dodać wektor odwrotny do niego, do wektorów opisujących równanie ruchu cząsteczek. Rozwiązanie takie daje naprawdę przy wysokiej wydajności w stosunku do klasycznych systemów cząsteczkowych.

Dodatkowo bezstanowy system cząsteczkowy można wyposażyć w podstawową detekcję kolizji (np. żeby śnieg nie padał w domu). Polegałoby to na wykorzystaniu techniki detekcji kolizji podobnej do tej zaprezentowanej przy stanowym systemie cząsteczkowym. Musimy wyznaczyć prostą najlepszego dopasowania, która interpolować będzie ruch we wszystkich 3 płaszczyznach. Posłuży ona jako kierunek kamery renderującej głębokość całej sceny z jej punktu widzenia. Teraz wystarczy że przy renderowaniu cząsteczek ich pozycję przeniesiemy do układu współrzędnych naszej „depth” kamery i odczytamy wartość głębokości z tekstury (w jednostce vertex shader w sprzęcie >SM3.0 lub pixel shader w jednostce >SM2.0). Jeśli będzie ona mniejsza od głębokości aktualnej cząsteczki, to cząsteczka nie jest rysowana.

Cząsteczki “twarde” przenikają przez geometrię tworząc twarde krawędzie które psują wrażenie objętości cząstek. Rozwiązaniem może być zmniejszenie wielkości cząstek, jednak to wprowadza konieczność proceduralnego opisywania skomplikowanych kształtów i zwiększa obciążenie. Lepszym rozwiązaniem jest więc próba wygładzenia miejsca styku cząsteczek z otoczeniem. Jeśli wyrenderujemy głębokości sceny z punktu widzenia kamery, to będziemy mogli porównywać wartość głębokości sceny, z głębokością którą miałby dany piksel cząsteczki. Porównując je i używając drobnej histerezy możemy modyfikować przezroczystość cząsteczki gdy głębokości te będą podobne (wtedy następuje kolizja cząsteczki ze sceną). Efekt renderingu jest o wiele lepszy od tego dawanego przez twarde cząsteczki.

  1. Microsoft Windows DDK, http://www.osronline.com/ddkx/ddk2.htm

  2. Microsoft DiectX SDK, http://msdn.microsoft.com/directx, Luty 2007

  3. ARB_point_sprite,

http://oss.sgi.com/projects/ogl-sample/registry/ARB/point_sprite.txt

  1. Natalya Tatarchuk, “ATI ToyShop Revealed(Eurographics Animation Festival)”

  2. Lutz Latta, “Building a Million Particle System (Games Developer Conference 2004)”

Abstract

Paper focuses on particie systems as a source of special effects in computer games. It describes applications, methods of presenting graphical and physical representation of particles, techniques of animation and unusual approaches to particle systems.

Michał Mocarski

Zaawansowane I efektywne systemy cząsteczkowe w grach komputerowych

IV Ogólnopolska Konferencja Inżynierii Gier Komputerowych, Siedlce 2007

10

9



Wyszukiwarka