diff --git a/projects/wobble_bobble/shaders/particle.vert b/projects/wobble_bobble/shaders/particle.vert
index bb864e07ee39ed1d04a44c00e5c75f24d1be1baf..bebf21436b85aea9d376974bc008e54f6d56f46c 100644
--- a/projects/wobble_bobble/shaders/particle.vert
+++ b/projects/wobble_bobble/shaders/particle.vert
@@ -12,6 +12,10 @@ layout(location = 0) in vec2 vertexPos;
 layout(location = 0) out vec2 passPos;
 layout(location = 1) out float passMass;
 
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
 void main()	{
     vec3 position = particles[gl_InstanceIndex].minimal.position;
     float size = particles[gl_InstanceIndex].minimal.size;
@@ -20,5 +24,8 @@ void main()	{
 
     passPos = vertexPos;
     passMass = mass;
-    gl_Position = vec4(position + vec3(vertexPos * size * 2.0f, 0), 1);
+
+    // align particle to face camera
+    gl_Position = mvp * vec4(position, 1);      // transform position into projected view space
+    gl_Position.xy += vertexPos * size * 2.0f;  // move position directly in view space
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp
index e40005441d9234a52ac4e628b57361bbfa9285f4..a9df518714ecedb2a0ad2f87b0262f10a8b634c1 100644
--- a/projects/wobble_bobble/src/main.cpp
+++ b/projects/wobble_bobble/src/main.cpp
@@ -384,7 +384,11 @@ int main(int argc, const char **argv) {
 		timePushConstants.appendDrawcall(static_cast<float>(dt));
 		
 		cameraManager.update(dt);
-		
+
+		glm::mat4 mvp = cameraManager.getActiveCamera().getMVP();
+		vkcv::PushConstants cameraPushConstants (sizeof(glm::mat4));
+		cameraPushConstants.appendDrawcall(mvp);
+
 		auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
 		
 		const uint32_t dispatchSizeGrid [3] = { 16, 16, 16 };
@@ -496,7 +500,7 @@ int main(int argc, const char **argv) {
 				cmdStream,
 				gfxPass,
 				gfxPipeline,
-				vkcv::PushConstants(0),
+				cameraPushConstants,
 				drawcalls,
 				renderTargets,
 				windowHandle