From 736ec0a829672894d393d262936f6c3e80b42862 Mon Sep 17 00:00:00 2001
From: Simeon Hermann <shermann04@uni-koblenz.de>
Date: Sun, 12 Sep 2021 18:38:18 +0200
Subject: [PATCH] [#111] add new compute shaders/pipelines and adapt Particle
 class

---
 projects/sph/CMakeLists.txt             |  2 -
 projects/sph/shaders/flip.comp          | 34 ++++++++++
 projects/sph/shaders/force.comp         | 77 ++++++++++++++++++++++
 projects/sph/shaders/pressure.comp      | 64 +++++++++++++++++++
 projects/sph/shaders/shader_water1.comp | 85 -------------------------
 projects/sph/shaders/shader_water2.comp | 74 ---------------------
 projects/sph/shaders/updateData.comp    | 52 +++++++++++++++
 projects/sph/src/Particle.cpp           | 29 ++++-----
 projects/sph/src/Particle.hpp           | 18 +++---
 projects/sph/src/ParticleSystem.cpp     | 60 -----------------
 projects/sph/src/ParticleSystem.hpp     | 32 ----------
 projects/sph/src/main.cpp               | 83 ++++++++++++++++--------
 12 files changed, 306 insertions(+), 304 deletions(-)
 create mode 100644 projects/sph/shaders/flip.comp
 create mode 100644 projects/sph/shaders/force.comp
 create mode 100644 projects/sph/shaders/pressure.comp
 delete mode 100644 projects/sph/shaders/shader_water1.comp
 delete mode 100644 projects/sph/shaders/shader_water2.comp
 create mode 100644 projects/sph/shaders/updateData.comp
 delete mode 100644 projects/sph/src/ParticleSystem.cpp
 delete mode 100644 projects/sph/src/ParticleSystem.hpp

diff --git a/projects/sph/CMakeLists.txt b/projects/sph/CMakeLists.txt
index 0ddc0409..592aa440 100644
--- a/projects/sph/CMakeLists.txt
+++ b/projects/sph/CMakeLists.txt
@@ -11,8 +11,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 # adding source files to the project
 add_executable(sph
 		src/main.cpp
-		src/ParticleSystem.hpp 
-		src/ParticleSystem.cpp
 		src/Particle.hpp 
 		src/Particle.cpp
 		src/BloomAndFlares.hpp
diff --git a/projects/sph/shaders/flip.comp b/projects/sph/shaders/flip.comp
new file mode 100644
index 00000000..96f3e992
--- /dev/null
+++ b/projects/sph/shaders/flip.comp
@@ -0,0 +1,34 @@
+#version 450 core
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(local_size_x = 256) in;
+
+struct Particle
+{
+    vec3 position;
+    float padding;
+    vec3 velocity;
+    float density;
+    vec3 force;
+    float pressure;
+};
+
+layout(std430, binding = 1) readonly buffer buffer_inParticle
+{
+    Particle inParticle[];
+};
+
+layout(std430, binding = 0) writeonly buffer buffer_outParticle
+{
+    Particle outParticle[];
+};
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+    
+    outParticle[id].force = inParticle[id].force;
+    outParticle[id].density = inParticle[id].density;
+    outParticle[id].pressure = inParticle[id].pressure;
+    outParticle[id].position =  inParticle[id].position;
+    outParticle[id].velocity =  inParticle[id].velocity;
+}
diff --git a/projects/sph/shaders/force.comp b/projects/sph/shaders/force.comp
new file mode 100644
index 00000000..865d6be5
--- /dev/null
+++ b/projects/sph/shaders/force.comp
@@ -0,0 +1,77 @@
+#version 450 core
+#extension GL_ARB_separate_shader_objects : enable
+
+const float PI = 3.1415926535897932384626433832795;
+
+#define h 0.045
+#define gravity 9.81
+#define mass 0.1
+#define viscosity 1500
+
+layout(local_size_x = 256) in;
+
+struct Particle
+{
+    vec3 position;
+    float padding;
+    vec3 velocity;
+    float density;
+    vec3 force;
+    float pressure;
+    
+};
+
+layout(std430, binding = 1) readonly buffer buffer_inParticle
+{
+    Particle inParticle[];
+};
+
+layout(std430, binding = 0) writeonly buffer buffer_outParticle
+{
+    Particle outParticle[];
+};
+
+layout( push_constant ) uniform constants{
+    float deltaTime;
+    float particleCount;
+};
+
+float spiky(float r)    
+{
+    return 15 / (PI * pow(h, 6)) * pow((h-r), 3) * int(0<=r && r<=h);
+}
+
+float laplacian(float r)
+{
+    return 45 / (PI * pow(h,6)) * (h - r) * int(0<=r && r<=h);
+}
+
+vec3 pressureForce = vec3(0, 0, 0);
+vec3 viscosityForce = vec3(0, 0, 0); 
+vec3 externalForce = vec3(0, 0, 0);
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if(id >= int(particleCount))
+    {
+        return;
+    }
+
+    externalForce = vec3(0, inParticle[id].density * gravity, 0);
+
+    for(uint i = 0; i < inParticle.length(); i++)  
+    {
+        vec3 dir = inParticle[id].position - inParticle[i].position;
+        float dist = length(dir);
+        pressureForce += mass * -(inParticle[id].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * spiky(dist) * normalize(dir);
+        viscosityForce += mass * (inParticle[id].velocity - inParticle[i].velocity)/inParticle[i].density * laplacian(dist);
+    }
+    viscosityForce *= viscosity;
+
+    outParticle[id].force = externalForce + pressureForce + viscosityForce;
+    outParticle[id].density = inParticle[id].density;
+    outParticle[id].pressure = inParticle[id].pressure;
+    outParticle[id].position = inParticle[id].position;
+    outParticle[id].velocity = inParticle[id].velocity;
+}
diff --git a/projects/sph/shaders/pressure.comp b/projects/sph/shaders/pressure.comp
new file mode 100644
index 00000000..c9216163
--- /dev/null
+++ b/projects/sph/shaders/pressure.comp
@@ -0,0 +1,64 @@
+#version 450 core
+#extension GL_ARB_separate_shader_objects : enable
+
+const float PI = 3.1415926535897932384626433832795;
+
+#define h 0.045
+#define mass 0.1
+#define gasConstant 300
+#define offset 1800
+
+layout(local_size_x = 256) in;
+
+struct Particle
+{
+    vec3 position;
+    float padding;
+    vec3 velocity;
+    float density;
+    vec3 force;
+    float pressure;
+    
+};
+
+layout(std430, binding = 0) readonly buffer buffer_inParticle
+{
+    Particle inParticle[];
+};
+
+layout(std430, binding = 1) writeonly buffer buffer_outParticle
+{
+    Particle outParticle[];
+};
+
+layout( push_constant ) uniform constants{
+    float deltaTime;
+    float particleCount;
+};
+
+float poly6(float r)    
+{
+    return 315/(64*PI*pow(h, 9)) * pow((h-r), 3) * int(0<=r && r<=h);
+}
+
+float densitySum = 0.f;
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if(id >= int(particleCount))
+    {
+        return;
+    }
+
+    for(uint i = 0; i < inParticle.length(); i++)   
+    {
+        float dist = distance(inParticle[id].position, inParticle[i].position);
+        densitySum += mass * poly6(dist);
+    }
+    outParticle[id].density = densitySum;
+    outParticle[id].pressure = max((densitySum - offset), 0) * gasConstant;
+    outParticle[id].position = inParticle[id].position;
+    outParticle[id].velocity = inParticle[id].velocity;
+    outParticle[id].force = inParticle[id].force;
+}
diff --git a/projects/sph/shaders/shader_water1.comp b/projects/sph/shaders/shader_water1.comp
deleted file mode 100644
index 80b1e8cc..00000000
--- a/projects/sph/shaders/shader_water1.comp
+++ /dev/null
@@ -1,85 +0,0 @@
-#version 450 core
-#extension GL_ARB_separate_shader_objects : enable
-
-layout(local_size_x = 256) in;
-
-struct Particle
-{
-    vec3 position;
-    float lifeTime;
-    vec3 velocity;
-    float padding_2;
-    vec3 reset_velocity;
-    float padding_3;
-};
-
-layout(std430, binding = 0) readonly buffer buffer_inParticle
-{
-    Particle inParticle[];
-};
-
-layout(std430, binding = 1) writeonly buffer buffer_outParticle
-{
-    Particle outParticle[];
-};
-
-layout( push_constant ) uniform constants{
-    float deltaTime;
-    float particleCount;
-};
-
-vec3 attraction(vec3 pos, vec3 attractPos)
-{
-    vec3 delta = attractPos - pos;
-    const float damp = 0.5;
-    float dDampedDot = dot(delta, delta) + damp;
-    float invDist = 1.0f / sqrt(dDampedDot);
-    float invDistCubed = invDist*invDist*invDist;
-    return delta * invDistCubed * 0.0035;
-}
-
-vec3 repulsion(vec3 pos, vec3 attractPos)
-{
-    vec3 delta = attractPos - pos;
-    float targetDistance = sqrt(dot(delta, delta));
-    return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035;
-}
-
-
-const int n = 3;
-vec3 gravity = vec3(0,-9.8,0);
-vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0),vec3(0.5, 0.5, 0),vec3(0, -0.5, 0));
-//vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0));
-void main() {
-    uint id = gl_GlobalInvocationID.x;
-
-    if(id >= int(particleCount))
-    {
-        return;
-    }
-
-    outParticle[id] = inParticle[id];
-
-    outParticle[id].lifeTime = inParticle[id].lifeTime - deltaTime;
-    vec3 pos = inParticle[id].position;
-    vec3 vel = inParticle[id].velocity;
-    if(inParticle[id].lifeTime < 0.f)
-    {
-        outParticle[id].lifeTime = 7.f;
-        pos = vec3(0);
-        vel = inParticle[id].reset_velocity;
-        outParticle[id].velocity = inParticle[id].reset_velocity;
-    }
-
-    for(int i = 0; i < n; i++)
-    {
-        vel += deltaTime * deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos);
-    }
-
-    vel = (-vel * 0.01);
-    pos += normalize(vel) * deltaTime;
-    outParticle[id].position = pos;
-
-    float weight = 1.0;
-    outParticle[id].velocity = vel;
-}
diff --git a/projects/sph/shaders/shader_water2.comp b/projects/sph/shaders/shader_water2.comp
deleted file mode 100644
index 32599a64..00000000
--- a/projects/sph/shaders/shader_water2.comp
+++ /dev/null
@@ -1,74 +0,0 @@
-#version 450 core
-#extension GL_ARB_separate_shader_objects : enable
-
-layout(local_size_x = 256) in;
-
-struct Particle
-{
-    vec3 position;
-    float lifeTime;
-    vec3 velocity;
-    float padding_2;
-    vec3 reset_velocity;
-    float padding_3;
-};
-
-layout(std430, binding = 1) readonly buffer buffer_inParticle
-{
-    Particle inParticle[];
-};
-
-layout(std430, binding = 0) writeonly buffer buffer_outParticle
-{
-    Particle outParticle[];
-};
-
-layout( push_constant ) uniform constants{
-    float deltaTime;
-    float particleCount;
-};
-
-const ivec4 gridSize = ivec4(4);
-const ivec4 origin = ivec4(1);
-const float energyloss = 0.0;
-
-void main() {
-    uint id = gl_GlobalInvocationID.x;
-
-    if(id >= int(particleCount))
-    {
-        return;
-    }
-
-    outParticle[id] = inParticle[id];
-    //collisition X-Axis
-//    if(inParticle[id].position.x >= gridSize.x - origin.x)
-//    {
-//        outParticle[id].position.x = gridSize.x  - origin.x - 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(-1.f,0.f,0.f))* energyloss;
-//    }else if(inParticle[id].position.x < origin.x)
-//    {
-//        outParticle[id].position.x = origin.x + 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(1.f,0.f,0.f)) * energyloss;
-//    }
-//    //collisition Y-Axis
-//    if(inParticle[id].position.y >= gridSize.y - origin.y)
-//    {
-//        outParticle[id].position.y = gridSize.y - origin.y - 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(0.f,-1.f,0.f)) * energyloss;
-//    }else if(inParticle[id].position.y < origin.y)
-//    {
-//        outParticle[id].position.y = origin.y + 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(0.f,1.f,0.f)) * energyloss;
-//    }
-//    //collisition Z-Axis
-//    if(inParticle[id].position.z >= gridSize.z - origin.z)
-//    {
-//        outParticle[id].position.z = gridSize.z - origin.z - 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(0.f,0.f,-1.f)) * energyloss;
-//    }else if(inParticle[id].position.z < origin.z)
-//    {
-//        outParticle[id].position.z = origin.z + 0.001f;
-//        outParticle[id].velocity = reflect(inParticle[id].velocity.xyz,vec3(0.f,0.f,1.f)) * energyloss;
-//    }
-}
diff --git a/projects/sph/shaders/updateData.comp b/projects/sph/shaders/updateData.comp
new file mode 100644
index 00000000..c80b1e1a
--- /dev/null
+++ b/projects/sph/shaders/updateData.comp
@@ -0,0 +1,52 @@
+#version 450 core
+#extension GL_ARB_separate_shader_objects : enable
+
+#define absorbtion 0.9
+#define dt 0.0003
+
+layout(local_size_x = 256) in;
+
+struct Particle
+{
+    vec3 position;
+    float padding;
+    vec3 velocity;
+    float density;
+    vec3 force;
+    float pressure;
+    
+};
+
+layout(std430, binding = 0) readonly buffer buffer_inParticle
+{
+    Particle inParticle[];
+};
+
+layout(std430, binding = 1) writeonly buffer buffer_outParticle
+{
+    Particle outParticle[];
+};
+
+layout( push_constant ) uniform constants{
+    float deltaTime;
+    float particleCount;
+};
+
+void main() {
+    uint id = gl_GlobalInvocationID.x;
+
+    if(id >= int(particleCount))
+    {
+        return;
+    }
+
+    vec3 accel = inParticle[id].force / inParticle[id].density;
+    vec3 vel_new = inParticle[id].velocity + dt * accel;
+    vec3 pos_new = inParticle[id].position + dt * vel_new;
+
+    outParticle[id].force = inParticle[id].force;
+    outParticle[id].density = inParticle[id].density;
+    outParticle[id].pressure = inParticle[id].pressure;
+    outParticle[id].position = pos_new;
+    outParticle[id].velocity = vel_new;
+}
diff --git a/projects/sph/src/Particle.cpp b/projects/sph/src/Particle.cpp
index b80d063d..32923698 100644
--- a/projects/sph/src/Particle.cpp
+++ b/projects/sph/src/Particle.cpp
@@ -1,22 +1,19 @@
 
 #include "Particle.hpp"
 
-Particle::Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime)
+Particle::Particle(glm::vec3 position, glm::vec3 velocity)
 : m_position(position),
-  m_lifeTime(lifeTime),
-  m_velocity(velocity),
-  m_mass(1.0f),
-  m_reset_velocity(velocity)
-{}
+  m_velocity(velocity)
+{
+    m_density = 0.f;
+    m_force = glm::vec3(0.f);
+    m_pressure = 0.f;
+}
 
 const glm::vec3& Particle::getPosition()const{
     return m_position;
 }
 
-bool Particle::isAlive()const{
-    return m_lifeTime > 0.f;
-}
-
 void Particle::setPosition( const glm::vec3 pos ){
     m_position = pos;
 }
@@ -29,14 +26,14 @@ void Particle::setVelocity( const glm::vec3 vel ){
     m_velocity = vel;
 }
 
-void Particle::update( const float delta ){
-    m_position += m_velocity * delta;
+const float& Particle::getDensity()const {
+    return m_density;
 }
 
-void Particle::setLifeTime( const float lifeTime ){
-    m_lifeTime = lifeTime;
+const glm::vec3& Particle::getForce()const {
+    return m_force;
 }
 
-const float& Particle::getLifeTime()const{
-    return m_lifeTime;
+const float& Particle::getPressure()const {
+    return m_pressure;
 }
\ No newline at end of file
diff --git a/projects/sph/src/Particle.hpp b/projects/sph/src/Particle.hpp
index 73e7cbf5..6c4ab50b 100644
--- a/projects/sph/src/Particle.hpp
+++ b/projects/sph/src/Particle.hpp
@@ -5,7 +5,7 @@
 class Particle {
 
 public:
-    Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime = 1.f);
+    Particle(glm::vec3 position, glm::vec3 velocity);
 
     const glm::vec3& getPosition()const;
 
@@ -15,20 +15,20 @@ public:
 
     void setVelocity( const glm::vec3 vel );
 
-    void update( const float delta );
+    const float& getDensity()const;
 
-    bool isAlive()const;
+    const glm::vec3& getForce()const;
+
+    const float& getPressure()const;
 
-    void setLifeTime( const float lifeTime );
 
-    const float& getLifeTime()const;
 
 private:
     // all properties of the Particle
     glm::vec3 m_position;
-    float m_lifeTime;
+    float m_padding1;
     glm::vec3 m_velocity;
-    float m_mass;
-    glm::vec3 m_reset_velocity;
-    float padding_3;
+    float m_density;
+    glm::vec3 m_force;
+    float m_pressure;
 };
diff --git a/projects/sph/src/ParticleSystem.cpp b/projects/sph/src/ParticleSystem.cpp
deleted file mode 100644
index b3162d6b..00000000
--- a/projects/sph/src/ParticleSystem.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "ParticleSystem.hpp"
-
-ParticleSystem::ParticleSystem(uint32_t particleCount ,glm::vec3 minVelocity , glm::vec3 maxVelocity , glm::vec2 lifeTime )
-{
-    m_rdmVel.resize(3);
-    m_rdmVel[0] = std::uniform_real_distribution<float>(minVelocity.x, maxVelocity.x);
-    m_rdmVel[1] = std::uniform_real_distribution<float>(minVelocity.y, maxVelocity.y);
-    m_rdmVel[2] = std::uniform_real_distribution<float>(minVelocity.z, maxVelocity.z);
-    m_rdmLifeTime = std::uniform_real_distribution<float>(lifeTime.x, lifeTime.y);
-
-    for(uint32_t i = 0; i < particleCount ;i++ ){
-        addParticle(Particle(m_respawnPos, getRandomVelocity(), getRandomLifeTime()));
-    }
-}
-
-const std::vector<Particle>& ParticleSystem::getParticles() const{
-    return m_particles;
-}
-
-void ParticleSystem::addParticle( const Particle particle ){
-    m_particles.push_back(particle);
-}
-void ParticleSystem::addParticles( const std::vector<Particle> particles ){
-    m_particles.insert(m_particles.end(), particles.begin(), particles.end());
-}
-
-void ParticleSystem::updateParticles( const float deltaTime ){
-    for(Particle& particle :m_particles){
-        bool alive = particle.isAlive();
-        particle.setPosition( particle.getPosition() * static_cast<float>(alive) + static_cast<float>(!alive) * m_respawnPos );
-        particle.setVelocity( particle.getVelocity() * static_cast<float>(alive) + static_cast<float>(!alive) *  getRandomVelocity());
-        particle.setLifeTime( (particle.getLifeTime() * alive + !alive * getRandomLifeTime() ) - deltaTime );
-        particle.update(deltaTime);
-    }
-}
-
-glm::vec3 ParticleSystem::getRandomVelocity(){
-    return glm::vec3(m_rdmVel[0](m_rdmEngine), m_rdmVel[1](m_rdmEngine),m_rdmVel[2](m_rdmEngine));
-}
-
-float ParticleSystem::getRandomLifeTime(){
-    return m_rdmLifeTime(m_rdmEngine);
-}
-
-void ParticleSystem::setRespawnPos( const glm::vec3 respawnPos){
-    m_respawnPos = respawnPos;
-}
-void ParticleSystem::setRdmLifeTime( const glm::vec2 lifeTime ){
-    m_rdmLifeTime = std::uniform_real_distribution<float> (lifeTime.x,lifeTime.y);
-}
-
-void ParticleSystem::setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity ){
-    m_rdmVel[0] = std::uniform_real_distribution<float> (minVelocity.x,maxVelocity.x);
-    m_rdmVel[1] = std::uniform_real_distribution<float> (minVelocity.y,maxVelocity.y);
-    m_rdmVel[2] = std::uniform_real_distribution<float> (minVelocity.z,maxVelocity.z);
-}
-
-const glm::vec3 ParticleSystem::getRespawnPos() const{
-    return m_respawnPos;
-}
diff --git a/projects/sph/src/ParticleSystem.hpp b/projects/sph/src/ParticleSystem.hpp
deleted file mode 100644
index fe5c99f9..00000000
--- a/projects/sph/src/ParticleSystem.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <vector>
-#include "Particle.hpp"
-#include <random>
-#include "vkcv/Buffer.hpp"
-
-class ParticleSystem {
-
-public:
-    ParticleSystem(uint32_t particleCount , glm::vec3 minVelocity = glm::vec3(0.f,0.f,0.f), glm::vec3 maxVelocity = glm::vec3(1.f,1.f,0.f), glm::vec2 lifeTime = glm::vec2(2.f,3.f));
-    const std::vector<Particle> &getParticles() const;
-    void updateParticles( const float deltaTime );
-    void setRespawnPos( const glm::vec3 respawnPos );
-    void setRdmLifeTime( const glm::vec2 lifeTime );
-    void setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity );
-    const glm::vec3 getRespawnPos() const;
-
-private:
-
-    void addParticle( const Particle particle );
-    void addParticles( const std::vector<Particle> particles );
-    glm::vec3 getRandomVelocity();
-    float getRandomLifeTime();
-
-    std::vector<Particle> m_particles;
-    glm::vec3 m_respawnPos = glm::vec3(0.f);
-
-    std::vector<std::uniform_real_distribution<float>> m_rdmVel;
-    std::uniform_real_distribution<float> m_rdmLifeTime;
-    std::default_random_engine m_rdmEngine;
-};
\ No newline at end of file
diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp
index 2248746b..54228b43 100644
--- a/projects/sph/src/main.cpp
+++ b/projects/sph/src/main.cpp
@@ -3,13 +3,13 @@
 #include <GLFW/glfw3.h>
 #include <vkcv/camera/CameraManager.hpp>
 #include <chrono>
-#include "ParticleSystem.hpp"
 #include <random>
 #include <glm/gtc/matrix_access.hpp>
 #include <time.h>
 #include <vkcv/shader/GLSLCompiler.hpp>
 #include "BloomAndFlares.hpp"
 #include "PipelineInit.hpp"
+#include "Particle.hpp"
 
 int main(int argc, const char **argv) {
     const char *applicationName = "SPH";
@@ -60,11 +60,21 @@ int main(int argc, const char **argv) {
 // comp shader 1
     vkcv::PipelineHandle computePipeline1;
     vkcv::DescriptorSetHandle computeDescriptorSet1 = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE,
-                                                                          "shaders/shader_water1.comp", computePipeline1);
+                                                                          "shaders/pressure.comp", computePipeline1);
 // comp shader 2
     vkcv::PipelineHandle computePipeline2;
     vkcv::DescriptorSetHandle computeDescriptorSet2 = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE,
-                                                                                        "shaders/shader_water2.comp", computePipeline2);
+                                                                          "shaders/force.comp", computePipeline2);
+
+//comp shader 3
+    vkcv::PipelineHandle computePipeline3;
+    vkcv::DescriptorSetHandle computeDescriptorSet3 = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE,
+                                                                           "shaders/updateData.comp", computePipeline3);
+
+//comp shader 4
+    vkcv::PipelineHandle computePipeline4;
+    vkcv::DescriptorSetHandle computeDescriptorSet4 = PipelineInit::ComputePipelineInit(&core, vkcv::ShaderStage::COMPUTE,
+                                                                            "shaders/flip.comp", computePipeline4);
 
 // shader
     vkcv::ShaderProgram particleShaderProgram{};
@@ -123,23 +133,30 @@ int main(int argc, const char **argv) {
             1
     );
 
-    glm::vec3 minVelocity = glm::vec3(-0.1f,-0.1f,-0.1f);
-    glm::vec3 maxVelocity = glm::vec3(0.1f,0.1f,0.1f);
-    glm::vec2 lifeTime = glm::vec2(-1.f,8.f);
-    ParticleSystem particleSystem = ParticleSystem( 100000 , minVelocity, maxVelocity, lifeTime);
+    int numberParticles = 10000;
+    std::vector<Particle> particles;
+    for (int i = 0; i < numberParticles; i++) {
+        float randPos = (float)std::rand() / (float)RAND_MAX;
+        glm::vec3 pos = glm::vec3(0.f);
+        float randVel = (float)std::rand() / (float)RAND_MAX;
+        glm::vec3 vel = glm::vec3(0.f);
+
+        particles.push_back(Particle(pos, vel));
+    }
 
     vkcv::Buffer<Particle> particleBuffer1 = core.createBuffer<Particle>(
             vkcv::BufferType::STORAGE,
-            particleSystem.getParticles().size()
+            numberParticles * sizeof(glm::vec4) * 3
+
     );
 
-	vkcv::Buffer<Particle> particleBuffer2 = core.createBuffer<Particle>(
-			vkcv::BufferType::STORAGE,
-			particleSystem.getParticles().size()
-	);
+    vkcv::Buffer<Particle> particleBuffer2 = core.createBuffer<Particle>(
+        vkcv::BufferType::STORAGE,
+        numberParticles * sizeof(glm::vec4) * 3
+    );
 
-    particleBuffer1.fill(particleSystem.getParticles());
-	particleBuffer2.fill(particleSystem.getParticles());
+    particleBuffer1.fill(particles);
+	particleBuffer2.fill(particles);
 
     vkcv::DescriptorWrites setWrites;
     setWrites.uniformBufferWrites = {vkcv::BufferDescriptorWrite(0,color.getHandle()),
@@ -154,7 +171,7 @@ int main(int argc, const char **argv) {
     core.writeDescriptorSet(computeDescriptorSet1, computeWrites);
 	core.writeDescriptorSet(computeDescriptorSet2, computeWrites);
 
-    if (!particlePipeline || !computePipeline1 || !computePipeline2)
+    if (!particlePipeline || !computePipeline1 || !computePipeline2 || !computePipeline3 || !computePipeline4)
     {
         std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
         return EXIT_FAILURE;
@@ -169,17 +186,9 @@ int main(int argc, const char **argv) {
     auto pos = glm::vec2(0.f);
     auto spawnPosition = glm::vec3(0.f);
 
-    window.e_mouseMove.add([&](double offsetX, double offsetY) {
-        pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY));
-        pos.x = (-2 * pos.x + static_cast<float>(window.getWidth())) / static_cast<float>(window.getWidth());
-        pos.y = (-2 * pos.y + static_cast<float>(window.getHeight())) / static_cast<float>(window.getHeight());
-        spawnPosition = glm::vec3(pos.x, pos.y, 0.f);
-        particleSystem.setRespawnPos(glm::vec3(-spawnPosition.x, spawnPosition.y, spawnPosition.z));
-    });
-
     std::vector<glm::mat4> modelMatrices;
     std::vector<vkcv::DrawcallInfo> drawcalls;
-    drawcalls.push_back(vkcv::DrawcallInfo(renderMesh, {descriptorUsage}, particleSystem.getParticles().size()));
+    drawcalls.push_back(vkcv::DrawcallInfo(renderMesh, {descriptorUsage}, numberParticles * sizeof(glm::vec4) * 3));
 
     auto start = std::chrono::system_clock::now();
 
@@ -249,12 +258,14 @@ int main(int argc, const char **argv) {
         renderingMatrices.projection = cameraManager.getActiveCamera().getProjection();
 
         auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
-        glm::vec2 pushData = glm::vec2(deltatime, static_cast<float>(particleSystem.getParticles().size()));
+
+        //deltatime wird noch nicht genutzt
+        glm::vec2 pushData = glm::vec2(deltatime, (float)numberParticles);
 
         vkcv::PushConstants pushConstantsCompute (sizeof(glm::vec2));
         pushConstantsCompute.appendDrawcall(pushData);
         
-        uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/256.f)),1,1};
+        uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(numberParticles/256.f)),1,1};
         core.recordComputeDispatchToCmdStream(cmdStream,
                                               computePipeline1,
                                               computeDispatchCount,
@@ -273,6 +284,26 @@ int main(int argc, const char **argv) {
 		core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle());
 		core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle());
 
+        core.recordComputeDispatchToCmdStream(cmdStream,
+            computePipeline3,
+            computeDispatchCount,
+            { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet3).vulkanHandle) },
+            pushConstantsCompute);
+
+        core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle());
+        core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle());
+
+        core.recordComputeDispatchToCmdStream(cmdStream,
+            computePipeline4,
+            computeDispatchCount,
+            { vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet4).vulkanHandle) },
+            pushConstantsCompute);
+
+        core.recordBufferMemoryBarrier(cmdStream, particleBuffer1.getHandle());
+        core.recordBufferMemoryBarrier(cmdStream, particleBuffer2.getHandle());
+
+
+        //bloomAndFlares & tonemapping
         vkcv::PushConstants pushConstantsDraw (sizeof(renderingMatrices));
         pushConstantsDraw.appendDrawcall(renderingMatrices);
         
-- 
GitLab