• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[Projekt] Particle system - fizyka na GPU

Object Storage Arubacloud
+2 głosów
325 wizyt
pytanie zadane 5 stycznia 2018 w Nasze projekty przez criss Mędrzec (172,590 p.)

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.

komentarz 5 stycznia 2018 przez Eryk Andrzejewski Mędrzec (164,260 p.)

Później zobaczę i może się uda skompilować smiley

komentarz 5 stycznia 2018 przez criss Mędrzec (172,590 p.)
Dzięki, byłoby super sprawdzić chociaż czy działa :P
komentarz 5 stycznia 2018 przez CzikaCarry Szeryf (75,340 p.)
Tak poza programowaniem (niskopoziomowcem nie jestem), zamiast przereklamowanego actiona, który w dodatku dość dużo kosztuje (aby nie mieć watermarka) możesz używać OBS (Open Broadcaster Software). Raz, że jest openSource, a dwa, że jest bardzo rozbudowany, w miarę potrzeby możesz dopisać swoje ficzery :)
komentarz 5 stycznia 2018 przez criss Mędrzec (172,590 p.)
@CzikaCarry
Dzięki, zobacze i pewnie będę korzystał (chociaż rzadko potrzebuje) :)
A Action spisuje się całkiem nieźle (tak myśle.. nie żebym się znał i potrzebował jakiejś specjalnej jakości) przynajmniej pod względem obciążenia. No a w końcu polski produkt to niech sobie leży watermark :D

1 odpowiedź

0 głosów
odpowiedź 5 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)
Na szybko bo odchodzę od komputera teraz...

tga.c używa funkcji nieprzenośnych ( fopen_s ). *_s'ów nie ma w standardzie. To rozszerzenie MS.

Jest trochę poprawek związanych z wykrywaniem GLFW w cmake.

Drobny błąd w particles/gl/OpenGlLoader.cpp okolice 73, typ zwracany fptr_t a nie fptr.

Brak rzutowania w particles/gl/OpenGlLoader.cpp w okolicach 75'tej.

Trochę błędów dynamicznego loadera libdl oraz statycznych asercji (głównie porównania enum'ów).

Fedora 27 x86_64
komentarz 5 stycznia 2018 przez criss Mędrzec (172,590 p.)
edycja 5 stycznia 2018 przez criss

tga.c używa funkcji nieprzenośnych ( fopen_s ). *_s'ów nie ma w standardzie. 

A to sam edytowałem jakiś czas temu, żeby mi się na msvc kompilowało. Tak, wiem, że można dodać jakiśtam #define żeby jednak przepuścił, ale nie wiem dlaczego zrobiłem to tak i zapomniałem zmienić. Zaraz poprawie.

Jest trochę poprawek związanych z wykrywaniem GLFW w cmake.

Nie miałem jak sprawdzić jak to działa na Linuksie. Jeśli ci się chce, to możesz poprawić (PR/tutaj wrzucić fragment kodu).

 Drobny błąd w particles/gl/OpenGlLoader.cpp okolice 73, typ zwracany fptr_t a nie fptr.

Dzięki. Zaraz poprawie.

 Trochę błędów dynamicznego loadera libdl oraz statycznych asercji (głównie porównania enum'ów).

Tu musiałbyś doprecyzować co dokładnie. Dzięki za te uwagi i jak będziesz miał jeszcze troche czasu to rzuć okiem jeszcze. 

edit: Ok, to co wymieniłeś naprawione.

komentarz 5 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)

Ok, masz takie "radosne coś":

[ 10%] Building CXX object CMakeFiles/particle-system.dir/particles/main.cpp.o
[ 20%] Building CXX object CMakeFiles/particle-system.dir/particles/Camera.cpp.o
In file included from /tmp/cos/GPU-particle-system/particles/Camera.cpp:3:0:
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h: In instantiation of ‘constexpr typename fhl::VectorTypeForSize<sizeof... (Dims), typename VecT::valueType>::Type fhl::swizzle::get(const VecT&) [with fhl::swizzle::VecDim ...Dims = {(fhl::swizzle::VecDim)0, (fhl::swizzle::VecDim)1, (fhl::swizzle::VecDim)2}; VecT = fhl::Vec4<float>; typename fhl::VectorTypeForSize<sizeof... (Dims), typename VecT::valueType>::Type = fhl::Vec3<float>]’:
/tmp/cos/GPU-particle-system/particles/Camera.cpp:10:52:   required from here
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
   static_assert(impl::AllTrue<(Dims < VecT::Dimensions)...>::value, "Not enough vector dimensions to get the one(s) demanded");
                               ~~~~~~^~~~~~~~~~~~~~~~~~~
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
[ 30%] Building CXX object CMakeFiles/particle-system.dir/particles/CameraController.cpp.o
[ 40%] Building C object CMakeFiles/particle-system.dir/particles/tga/tga.c.o
[ 50%] Building CXX object CMakeFiles/particle-system.dir/particles/utility/Clock.cpp.o
[ 60%] Building CXX object CMakeFiles/particle-system.dir/particles/maths/Quaternion.cpp.o
In file included from /tmp/cos/GPU-particle-system/particles/maths/Quaternion.cpp:3:0:
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h: In instantiation of ‘constexpr typename fhl::VectorTypeForSize<sizeof... (Dims), typename VecT::valueType>::Type fhl::swizzle::get(const VecT&) [with fhl::swizzle::VecDim ...Dims = {(fhl::swizzle::VecDim)0, (fhl::swizzle::VecDim)1, (fhl::swizzle::VecDim)2}; VecT = fhl::Vec4<float>; typename fhl::VectorTypeForSize<sizeof... (Dims), typename VecT::valueType>::Type = fhl::Vec3<float>]’:
/tmp/cos/GPU-particle-system/particles/maths/Quaternion.cpp:61:29:   required from here
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
   static_assert(impl::AllTrue<(Dims < VecT::Dimensions)...>::value, "Not enough vector dimensions to get the one(s) demanded");
                               ~~~~~~^~~~~~~~~~~~~~~~~~~
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
/tmp/cos/GPU-particle-system/particles/maths/swizzle.h:39:37: warning: comparison between ‘enum fhl::swizzle::VecDim’ and ‘enum fhl::Vec4<float>::<unnamed>’ [-Wenum-compare]
[ 70%] Building CXX object CMakeFiles/particle-system.dir/particles/gl/OpenGlLoader.cpp.o
[ 80%] Building CXX object CMakeFiles/particle-system.dir/particles/gl/flextGLInit.cpp.o
[ 90%] Building CXX object CMakeFiles/particle-system.dir/particles/gl/flextGL.cpp.o
[100%] Linking CXX executable particle-system
/usr/bin/ld: CMakeFiles/particle-system.dir/particles/gl/OpenGlLoader.cpp.o: undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
//usr/lib64/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/particle-system.dir/build.make:307: particle-system] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/particle-system.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

 

komentarz 5 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)
diff -Naur GPU-particle-system.orig/cmake-modules/FindGLFW.cmake GPU-particle-system/cmake-modules/FindGLFW.cmake
--- GPU-particle-system.orig/cmake-modules/FindGLFW.cmake	2018-01-05 15:12:27.757417023 +0100
+++ GPU-particle-system/cmake-modules/FindGLFW.cmake	2018-01-05 17:35:24.082444547 +0100
@@ -50,7 +50,7 @@
 	# Find include files
 	find_path(
 		GLFW_INCLUDE_DIR
-		NAMES GLFW/glfw3.h
+		NAMES GLFW/glfw.h
 		PATHS
 		/usr/include
 		/usr/local/include
@@ -62,7 +62,7 @@
 	# Try to use static libraries
 	find_library(
 		GLFW_LIBRARY
-		NAMES glfw
+		NAMES glfw3
 		PATHS
 		/usr/lib64
 		/usr/lib

 

komentarz 5 stycznia 2018 przez criss Mędrzec (172,590 p.)
Dopisałem do cmake-a, zeby linkował dl w przypadku Unixów. Sprawdź teraz.
Co do FindGLFW, to... właśnie tak on wygląda jak po zmianach wg twojego diffa. Troche nie rozumiem..
komentarz 5 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)

Ok.. Tu masz diff'a wyłącznie 1 pliku detekcji obecności GLFW:

--- FindGLFW.cmake.orig	2018-01-05 20:28:53.369478957 +0100
+++ FindGLFW.cmake	2018-01-05 20:29:14.306420351 +0100
@@ -50,7 +50,7 @@
 	# Find include files
 	find_path(
 		GLFW_INCLUDE_DIR
-		NAMES GLFW/glfw.h
+		NAMES GLFW/glfw3.h
 		PATHS
 		/usr/include
 		/usr/local/include
@@ -62,7 +62,7 @@
 	# Try to use static libraries
 	find_library(
 		GLFW_LIBRARY
-		NAMES glfw3
+		NAMES glfw
 		PATHS
 		/usr/lib64
 		/usr/lib

Mam nadzieję że teraz jest jasne "co na co poprawić".

Z dobrych wiadomości, buduje się :-)

Ze złych, uruchomienie kończy się:

$ ./particle-system
terminate called after throwing an instance of 'std::runtime_error'
  what():  FHL: Failed loading OpenGL
Aborted (zrzut pamięci)

 

komentarz 5 stycznia 2018 przez criss Mędrzec (172,590 p.)

Z dobrych wiadomości, buduje się :-)

O, super. Dzięki!

Co do tego wyjątku... Pushnąłem taki testowy kod. Może zadziała, spróbuj. I jeszcze raz dzięki za pomoc :) 

Podobne pytania

0 głosów
0 odpowiedzi 109 wizyt
pytanie zadane 13 marca 2019 w C i C++ przez Maciej Złotorowicz Gaduła (4,230 p.)
0 głosów
0 odpowiedzi 939 wizyt
+2 głosów
1 odpowiedź 600 wizyt
pytanie zadane 21 stycznia 2022 w Python przez Marak123 Stary wyjadacz (11,190 p.)

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...