diff --git a/projects/particle_simulation/shaders/comp1.spv b/projects/particle_simulation/shaders/comp1.spv
index c82562d6735289dd7f7ba2dbeb2243817034d47d..386bd33749f3e09b1fa3bf76fff23812fd7f87c1 100644
Binary files a/projects/particle_simulation/shaders/comp1.spv and b/projects/particle_simulation/shaders/comp1.spv differ
diff --git a/projects/particle_simulation/shaders/shader1.comp b/projects/particle_simulation/shaders/shader1.comp
index eea7fe7beb1c6796ce8b0accc2f634ea5174f423..7b58b55fbca9841caea7ec5e606cfc79f220bcd1 100644
--- a/projects/particle_simulation/shaders/shader1.comp
+++ b/projects/particle_simulation/shaders/shader1.comp
@@ -1,7 +1,7 @@
 #version 450 core
 #extension GL_ARB_separate_shader_objects : enable
 
-layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
+layout(local_size_x = 256) in;
 
 struct Particle
 {
@@ -21,14 +21,54 @@ layout( push_constant ) uniform constants{
     float deltaTime;
 };
 
+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));
+
 void main() {
     uint id = gl_GlobalInvocationID.x;
     inParticle[id].lifeTime -= deltaTime;
+    vec3 pos = inParticle[id].position;
+    vec3 vel = inParticle[id].velocity;
     if(inParticle[id].lifeTime < 0.f)
     {
         inParticle[id].lifeTime = 3.f;
-        inParticle[id].position = respawnPos;
+        pos = vec3(0);
     }
+//    inParticle[id].position += deltaTime * -normalize(max(2 - distance(inParticle[id].position,respawnPos),0.0) * respawnPos - inParticle[id].position);
+
+    for(int i = 0; i < n; i++)
+    {
+        pos += deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos);
+    }
+
+//    vec3 delta = respawnPos - pos;
+//    float targetDistane = sqrt(dot(delta,delta));
+//    vel += repulsion(pos, respawnPos) * 0.05;
+
+
+    if((pos.x < -1.0) || (pos.x > 1.0) || (pos.y < -1.0) || (pos.y > 1.0)|| (pos.z < -1.0) || (pos.z > 1.0))
+        vel = (-vel * 0.1) + attraction(pos, respawnPos) * 12;
+
+    pos += normalize(vel) * deltaTime;
+    inParticle[id].position = pos;
 
-    inParticle[id].position = (inParticle[id].position + deltaTime * inParticle[id].velocity);
+    inParticle[id].velocity = vel;
 }
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index e4c4bc9a32eeffc538f8c5edb35c7546820734c9..17104ddf94bf26012f1735243e7701c894d58fca 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -201,8 +201,8 @@ int main(int argc, const char **argv) {
     uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
 
     cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -2));
-    cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, 0.0f));
-    cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, -1.0f));
+    cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, -2.0f));
+    cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f));
 
     while (window.isWindowOpen()) {
         window.pollEvents();
@@ -218,19 +218,19 @@ int main(int argc, const char **argv) {
         auto end = std::chrono::system_clock::now();
         float deltatime = 0.000001 * static_cast<float>( std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() );
         start = end;
-        particleSystem.updateParticles(deltatime);
+//        particleSystem.updateParticles(deltatime);
 
         cameraManager.update(deltatime);
         std::vector<glm::mat4> mvp;
         mvp.clear();
-        mvp.push_back( cameraManager.getCamera(0).getMVP());
+        mvp.push_back( cameraManager.getCamera(1).getMVP());
 
         auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
 
         glm::vec4 pushData = glm::vec4(particleSystem.getRespawnPos(),deltatime);
 
         vkcv::PushConstantData pushConstantDataCompute( &pushData, sizeof(glm::vec4));
-        uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/64.f)),1,1};
+        uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/256.f)),1,1};
         core.recordComputeDispatchToCmdStream(cmdStream,
                                               computePipeline,
                                               computeDispatchCount,