diff --git a/projects/wobble_bobble/shaders/init_particle_volumes.comp b/projects/wobble_bobble/shaders/init_particle_volumes.comp
index 8ab9f05babe183a460610b4171992843927da4be..8f0eaf78eb1d68a0695909b5640f2210cb351341 100644
--- a/projects/wobble_bobble/shaders/init_particle_volumes.comp
+++ b/projects/wobble_bobble/shaders/init_particle_volumes.comp
@@ -5,7 +5,7 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) restrict buffer particleBuffer {
     Particle particles [];
 };
 
@@ -13,9 +13,6 @@ layout(set=0, binding=1) uniform texture3D gridImage;
 layout(set=0, binding=2) uniform sampler gridSampler;
 
 void main()	{
-    memoryBarrierBuffer();
-    memoryBarrierImage();
-
     if (gl_GlobalInvocationID.x < particles.length()) {
         ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal;
 
@@ -52,6 +49,4 @@ void main()	{
         particles[gl_GlobalInvocationID.x].minimal.size = sphere_radius(volume);
         particles[gl_GlobalInvocationID.x].minimal.mass = mass;
     }
-
-    memoryBarrierBuffer();
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/particle.vert b/projects/wobble_bobble/shaders/particle.vert
index bebf21436b85aea9d376974bc008e54f6d56f46c..a8f697e79eacba361d80b5858405add675e761bb 100644
--- a/projects/wobble_bobble/shaders/particle.vert
+++ b/projects/wobble_bobble/shaders/particle.vert
@@ -3,7 +3,7 @@
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) readonly buffer particleBuffer {
     Particle particles [];
 };
 
diff --git a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp
index 581bd667fdf81bcddec292aa10d48ef01ac68c36..0ccc6eb2294b898ecbaad73404e2dd9e523ddcb3 100644
--- a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp
+++ b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp
@@ -5,12 +5,11 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) readonly buffer particleBuffer {
     Particle particles [];
 };
 
 layout(set=0, binding=1, rgba32f) restrict writeonly uniform image3D gridImage;
-layout(set=0, binding=2, rgba32f) restrict writeonly uniform image3D gridCopyImage;
 
 #define SHARED_PARTICLES_BATCH_SIZE 64
 
@@ -23,8 +22,6 @@ void main()	{
 
     uint offset = 0;
 
-    memoryBarrierBuffer();
-
     for (offset = 0; offset < particles.length(); offset += SHARED_PARTICLES_BATCH_SIZE) {
         uint localOffset = offset + gl_LocalInvocationIndex;
 
@@ -50,6 +47,7 @@ void main()	{
             );
         }
 
+        barrier();
         memoryBarrierShared();
     }
 
@@ -62,12 +60,4 @@ void main()	{
         ivec3(gl_GlobalInvocationID),
         gridValue
     );
-
-    imageStore(
-        gridCopyImage,
-        ivec3(gl_GlobalInvocationID),
-        gridValue
-    );
-
-    memoryBarrierImage();
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/update_grid_forces.comp b/projects/wobble_bobble/shaders/update_grid_forces.comp
index 6d9434c45ff0d954a8bd5636d0cb62b12a3ac1d9..3277986450fb9d571a5f362e7ed1692252fb39ef 100644
--- a/projects/wobble_bobble/shaders/update_grid_forces.comp
+++ b/projects/wobble_bobble/shaders/update_grid_forces.comp
@@ -7,7 +7,7 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
 
 layout(set=0, binding=0, rgba32f) restrict readonly uniform image3D gridImage;
 layout(set=0, binding=1, rgba32f) restrict writeonly uniform image3D gridForceImage;
-layout(set=0, binding=2, std430) buffer particleBuffer {
+layout(set=0, binding=2, std430) readonly buffer particleBuffer {
     Particle particles [];
 };
 
@@ -40,6 +40,7 @@ void main()	{
         poisson /= (6.0f * K);
     }
 
+    barrier();
     memoryBarrierImage();
 
     const vec3 gridResolution = vec3(imageSize(gridImage));
@@ -57,6 +58,7 @@ void main()	{
     vec3 force = vec3(0.0f);
     uint offset = 0;
 
+    barrier();
     memoryBarrierBuffer();
 
     for (offset = 0; offset < particles.length(); offset += SHARED_PARTICLES_BATCH_SIZE) {
@@ -72,6 +74,7 @@ void main()	{
             shared_particles[gl_LocalInvocationIndex].deformation = mat4(0.0f);
         }
 
+        barrier();
         memoryBarrierShared();
 
         for (uint i = 0; i < SHARED_PARTICLES_BATCH_SIZE; i++) {
@@ -101,6 +104,7 @@ void main()	{
             }
         }
 
+        barrier();
         memoryBarrierShared();
     }
 
@@ -129,6 +133,4 @@ void main()	{
         ivec3(gl_GlobalInvocationID),
         vec4(velocity, mass)
     );
-
-    memoryBarrierImage();
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/update_particle_deformation.comp b/projects/wobble_bobble/shaders/update_particle_deformation.comp
index 3cf9d2b9385de55f57f3f37feee3e0fbd8d77844..2fe634451fe85c8582085348b4cbc6fb40cd79de 100644
--- a/projects/wobble_bobble/shaders/update_particle_deformation.comp
+++ b/projects/wobble_bobble/shaders/update_particle_deformation.comp
@@ -5,7 +5,7 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) restrict buffer particleBuffer {
     Particle particles [];
 };
 
@@ -20,9 +20,6 @@ layout( push_constant ) uniform constants {
 };
 
 void main()	{
-    memoryBarrierBuffer();
-    memoryBarrierImage();
-
     if (gl_GlobalInvocationID.x < particles.length()) {
         ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal;
         mat3 deformation = mat3(particles[gl_GlobalInvocationID.x].deformation);
@@ -60,6 +57,4 @@ void main()	{
 
         particles[gl_GlobalInvocationID.x].deformation = mat4(deformation_elastic);
     }
-
-    memoryBarrierBuffer();
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/update_particle_positions.comp b/projects/wobble_bobble/shaders/update_particle_positions.comp
index bd01b40286835cb50277c5100dbc9270377061e0..6351cdde0e5ee20c6c1c1bd1f42caf4a2e524273 100644
--- a/projects/wobble_bobble/shaders/update_particle_positions.comp
+++ b/projects/wobble_bobble/shaders/update_particle_positions.comp
@@ -5,7 +5,7 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) restrict buffer particleBuffer {
     Particle particles [];
 };
 
diff --git a/projects/wobble_bobble/shaders/update_particle_velocities.comp b/projects/wobble_bobble/shaders/update_particle_velocities.comp
index ecc3682e18e1fc16756d58a6788ae0fc3798d2d9..4a5bbff8e3d985c9c4fc880e20d1172e06107743 100644
--- a/projects/wobble_bobble/shaders/update_particle_velocities.comp
+++ b/projects/wobble_bobble/shaders/update_particle_velocities.comp
@@ -6,7 +6,7 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
 #include "particle.inc"
 
-layout(set=0, binding=0, std430) buffer particleBuffer {
+layout(set=0, binding=0, std430) restrict buffer particleBuffer {
     Particle particles [];
 };
 
diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp
index 23d3c90c9b9752ff76a6c5b6cb9ff9edfe75e9b6..a65e93256aaad3ab12d17144a0c1f7c38d0d4d80 100644
--- a/projects/wobble_bobble/src/main.cpp
+++ b/projects/wobble_bobble/src/main.cpp
@@ -229,8 +229,7 @@ int main(int argc, const char **argv) {
 	{
 		vkcv::DescriptorWrites writes;
 		writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle()));
-		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, grid.getHandle()));
-		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(2, gridCopy.getHandle()));
+		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, gridCopy.getHandle()));
 		core.writeDescriptorSet(transformParticlesToGridSets[0], writes);
 	}
 	
@@ -244,7 +243,7 @@ int main(int argc, const char **argv) {
 	{
 		vkcv::DescriptorWrites writes;
 		writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle()));
-		writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(1, grid.getHandle()));
+		writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(1, gridCopy.getHandle()));
 		writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(2, gridSampler));
 		core.writeDescriptorSet(initParticleVolumesSets[0], writes);
 	}
@@ -626,7 +625,7 @@ int main(int argc, const char **argv) {
 		const uint32_t dispatchSizeParticles [3] = { static_cast<uint32_t>(particles.getCount() + 63) / 64, 1, 1 };
 		
 		core.recordBeginDebugLabel(cmdStream, "TRANSFORM PARTICLES TO GRID", { 0.47f, 0.77f, 0.85f, 1.0f });
-		core.prepareImageForStorage(cmdStream, grid.getHandle());
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 		core.prepareImageForStorage(cmdStream, gridCopy.getHandle());
 		
 		core.recordComputeDispatchToCmdStream(
@@ -639,13 +638,13 @@ int main(int argc, const char **argv) {
 				vkcv::PushConstants(0)
 		);
 		
-		core.recordImageMemoryBarrier(cmdStream, grid.getHandle());
 		core.recordImageMemoryBarrier(cmdStream, gridCopy.getHandle());
 		core.recordEndDebugLabel(cmdStream);
 		
 		if (!initializedParticleVolumes) {
 			core.recordBeginDebugLabel(cmdStream, "INIT PARTICLE VOLUMES", { 0.78f, 0.89f, 0.94f, 1.0f });
-			core.prepareImageForSampling(cmdStream, grid.getHandle());
+			core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
+			core.prepareImageForSampling(cmdStream, gridCopy.getHandle());
 			
 			core.recordComputeDispatchToCmdStream(
 					cmdStream,
@@ -659,11 +658,14 @@ int main(int argc, const char **argv) {
 			
 			core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 			core.recordEndDebugLabel(cmdStream);
+			
 			initializedParticleVolumes = true;
 		}
 		
 		core.recordBeginDebugLabel(cmdStream, "UPDATE GRID FORCES", { 0.47f, 0.77f, 0.85f, 1.0f });
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 		core.prepareImageForStorage(cmdStream, grid.getHandle());
+		core.prepareImageForStorage(cmdStream, gridCopy.getHandle());
 		
 		core.recordComputeDispatchToCmdStream(
 				cmdStream,
@@ -679,6 +681,7 @@ int main(int argc, const char **argv) {
 		core.recordEndDebugLabel(cmdStream);
 		
 		core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE DEFORMATION", { 0.78f, 0.89f, 0.94f, 1.0f });
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 		core.prepareImageForSampling(cmdStream, grid.getHandle());
 		
 		core.recordComputeDispatchToCmdStream(
@@ -695,6 +698,8 @@ int main(int argc, const char **argv) {
 		core.recordEndDebugLabel(cmdStream);
 		
 		core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE VELOCITIES", { 0.78f, 0.89f, 0.94f, 1.0f });
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
+		core.prepareImageForSampling(cmdStream, grid.getHandle());
 		core.prepareImageForSampling(cmdStream, gridCopy.getHandle());
 		
 		core.recordComputeDispatchToCmdStream(
@@ -711,6 +716,8 @@ int main(int argc, const char **argv) {
 		core.recordEndDebugLabel(cmdStream);
 		
 		core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE POSITIONS", { 0.78f, 0.89f, 0.94f, 1.0f });
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
+		
 		core.recordComputeDispatchToCmdStream(
 				cmdStream,
 				updateParticlePositionsPipeline,
@@ -731,6 +738,7 @@ int main(int argc, const char **argv) {
 		
 		if (renderGrid) {
 			core.recordBeginDebugLabel(cmdStream, "RENDER GRID", { 0.13f, 0.20f, 0.22f, 1.0f });
+			core.prepareImageForSampling(cmdStream, grid.getHandle());
 			
 			core.recordDrawcallsToCmdStream(
 					cmdStream,
@@ -745,6 +753,7 @@ int main(int argc, const char **argv) {
 			core.recordEndDebugLabel(cmdStream);
 		} else {
 			core.recordBeginDebugLabel(cmdStream, "RENDER PARTICLES", { 0.13f, 0.20f, 0.22f, 1.0f });
+			core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 			
 			core.recordDrawcallsToCmdStream(
 					cmdStream,