W przerwie świąteczno-sylwestrowej zrobiłem sobie projekcik wykorzystujący coś, co stosunkowo niedawno zacząłem poznawać, a konkretnie compute shader z OpenGL 4.3. Już nie taka nowość bo z 2012r., ale wciąż chyba najnowszy większy, szeroko dostępny feature oferowany przez OpenGL.
Projekt to stosunkowo oczywista możliwość wykorzystania zrównoleglania czyli obliczenia ruchu niezależnych od sieie cząstek (particli). Gameplay polega tym, że mamy dwa miliony cząsteczek w przestrzeni 3D i "punkt grawitacyjny" będący zawsze pewną odległość od kamery na środku ekranu. Kamerę możemy dowolnie przemieszczać i obracać (i tym samym zmieniać położenie punktu), a sama grawitacja w punkcie jest aktywna tylko gdy wciśnięty jest lewy przycisk myszy. Dodatkowo cząsteczki zmieniają kolor zależnie od prędkości (od bardzo-jasno-błękitnego do różowego). Umiejętnie "majtany" punkt grawitacyjny potrafi dać śliczne wyniki :D
Krótko od strony technicznej:
Każda cząsteczka jest reprezentowana w pamięci przez pojedynczy punkt 3D (właściwie, to 4 floaty dla odpowiedniego wyrównania). Są dwa bufory: pozycji i prędkości. Obydwa są cały czas nadpisywane przez równoległe obliczenia fizyki realizowane przez compute shader. Z zawartości buforów korzysta vertex shader - tam jest wyliczany kolor cząsteczki i pozycja cząsteczki w "view space" (mnożona przez view matrix). To idzie do geometry shader-a gdzie dynamicznie tworzone są dodatkowe wierzchołki (przypomnijmy, że każda cząsteczka jest reprezentowana w buforze przez jeden wierzchołek) tak, żebyśmy zamiast punktu mogli renderować sprite-a. Dopiero wtedy wierzchołki są mnożone przez projection matrix (pozycja w "clip space") - dzięki temu sprite zawsze jest zwrócony w stronę kamery (tzw. billboard). Geometry shader przekazuje też koordynaty do teksturowanie do fragment shader. A fragment shader właśnie to robi (oteksturowuje sprite-a) dzięki czemu cząsteczki wygladają na małe okrągłe światełka a nie po prostu kwadraty.
Pochwalę się też, że cała matma na CPU (macierze, operacje na wektorach... algebra liniowa) jest robiona w całości od zera przeze mnie. Funkcje OpenGL-a też są ładowane moim kodem, więc chciałbym potwierdzenia, że działa też na Linuksie (patrz prośba na dole).
Krótki filmik jak sobie maziam wrzuciłem na YT: https://www.youtube.com/watch?v=TvJGFqh-pmM
Kod dostępny tutaj: https://github.com/Crisspl/GPU-particle-system
Kompilacja na Windowsa tutaj: https://www.dropbox.com/s/0op7m4ma7d26eqr/particles.rar?dl=0
Wszystko jest wkompilowane w exe, więc żadne dodatkowe dll-ki nie powinny być potrzebne. Polecam jednak samemu skompilować (w repo jest projekt VS2017 i skrypt CMake jeśli korzystacie z innego IDE), żeby mieć pewność, że nic wam nie grozi, bo niektóre antywirusy coś płaczą na temat mojej kompilacji (virustotal).
Tutaj też miałbym prośbę. Mógłby ktoś skompilować to na Linuksa? Powinno to zająć dosłownie chwile - specjalnie przygotowałem CMake-a, a nawet bez tego plików jest na tyle mało, że samodzielne skompilowanie nie powinno być problemem.