diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 065c21d225810f465f0909cb8c1479c1031aba8f..a3016f911fbade226f3a7d2b39764e9e409c837e 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -164,7 +164,7 @@ namespace vkcv
 		 * @brief render a beautiful triangle
 		*/
 		void renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle,
-			const int width, const int height);
+			const int width, const int height, const size_t pushConstantSize, const void* pushConstantData);
 
 		/**
 		 * @brief end recording and present image
diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp
index 90a2b003c9381093e7d83678d99a55e17d16eb24..64d8770e01e28d0cac212348919a33ba4a1e46dc 100644
--- a/modules/camera/include/vkcv/camera/Camera.hpp
+++ b/modules/camera/include/vkcv/camera/Camera.hpp
@@ -8,15 +8,22 @@ namespace vkcv {
 
     class Camera {
     protected:
-        glm::mat4 m_view, m_projection;
-
-        int m_width, m_height;
-
-        float m_oldX, m_oldY,
-                m_near, m_far,
-                m_fov, m_ratio;
-
-        glm::vec3 m_position, m_direction, m_up;
+		glm::mat4 m_view;
+		glm::mat4 m_projection;
+
+		int m_width;
+		int m_height;
+
+		float m_oldX;
+		float m_oldY;
+		float m_near;
+		float m_far;
+		float m_fov;
+		float m_ratio;
+
+		glm::vec3 m_position;
+		glm::vec3 m_direction;
+		glm::vec3 m_up;
 
     public:
         Camera();
diff --git a/projects/first_triangle/shaders/shader.vert b/projects/first_triangle/shaders/shader.vert
index 1d278d5f41f803bb657a303dcc95ffcd2a92fd6e..e129186a4f9b9f8ceca180391210ccaf2953c08e 100644
--- a/projects/first_triangle/shaders/shader.vert
+++ b/projects/first_triangle/shaders/shader.vert
@@ -3,11 +3,15 @@
 
 layout(location = 0) out vec3 fragColor;
 
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
 void main()	{
     vec3 positions[3] = {
-        vec3(-0.5, 0.5, 0),
-        vec3( 0.5, 0.5, 0),
-        vec3(0, -0.5, 0)
+        vec3(-0.5, 0.5, -1),
+        vec3( 0.5, 0.5, -1),
+        vec3(0, -0.5, -1)
     };
     
     vec3 colors[3] = {
@@ -16,6 +20,6 @@ void main()	{
         vec3(0, 0, 1)
     };
 
-	gl_Position = vec4(positions[gl_VertexIndex], 1.0);
+	gl_Position = mvp * vec4(positions[gl_VertexIndex], 1.0);
 	fragColor = colors[gl_VertexIndex];
 }
\ No newline at end of file
diff --git a/projects/first_triangle/shaders/vert.spv b/projects/first_triangle/shaders/vert.spv
index bd1e0e682c52e6e38a5f5aba4eeaf8e73a70d741..03af5758ffff1b5b6505fe98b02044849026832d 100644
Binary files a/projects/first_triangle/shaders/vert.spv and b/projects/first_triangle/shaders/vert.spv differ
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 5ff33793856123649e2f2ea5f2286b5ebc4c84fb..d9c16d57143bfe32c30c3db0d2f79755e28fea68 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -24,7 +24,7 @@ int main(int argc, const char** argv) {
     std::shared_ptr<vkcv::TrackballCamera> trackball;
     camera.setPerspective( glm::radians(60.0f), windowWidth / (float)windowHeight, 0.1f, 10.f);
     glm::vec3 up(0.0f, 1.0f, 0.0f);
-    glm::vec3 position(1.0f, 0.0f, 0.0f);
+    glm::vec3 position(0.0f, 0.0f, 0.0f);
     glm::vec3 front(0.0f, 0.0f, -1.0f);
     glm::vec3 center = position + front;
     camera.lookAt(position, center, up);
@@ -41,7 +41,7 @@ int main(int argc, const char** argv) {
 
     // showing basic usage lambda events of window
     window.e_mouseMove.add([&](double x, double y) {
-        std::cout << "movement: " << x << " , " << y << std::endl;
+        //std::cout << "movement: " << x << " , " << y << std::endl;
 
         if (firstMouse) {
             lastX = x;
@@ -77,7 +77,7 @@ int main(int argc, const char** argv) {
         center = position + front;
         camera.lookAt(position, center, up);
 
-        std::cout << "New center: " << center.x << ", " << center.y << ", " << center.z << std::endl;
+		//std::cout << "New center: " << center.x << ", " << center.y << ", " << center.z << std::endl;
     });
 
     window.e_mouseScroll.add([&](double xoffset, double yoffset) {
@@ -90,37 +90,37 @@ int main(int argc, const char** argv) {
             fov = 45.0f;
         }
         camera.setFov(fov);
-        std::cout << "New FOV: " << fov << std::endl;
+		//std::cout << "New FOV: " << fov << std::endl;
     });
 
     window.e_key.add([&](int key, int scancode, int action, int mods) {
         switch (key) {
             case GLFW_KEY_W:
-                std::cout << "Move forward" << std::endl;
+				//std::cout << "Move forward" << std::endl;
                 position += cameraSpeed * front;
                 center = position + front;
                 camera.lookAt(position, center, up);
                 break;
             case GLFW_KEY_S:
-                std::cout << "Move left" << std::endl;
+				//std::cout << "Move left" << std::endl;
                 position -= cameraSpeed * front;
                 center = position + front;
                 camera.lookAt(position, center, up);
                 break;
             case GLFW_KEY_A:
-                std::cout << "Move backward" << std::endl;
+				//std::cout << "Move backward" << std::endl;
                 position -= glm::normalize(glm::cross(front, up)) * cameraSpeed;
                 center = position + front;
                 camera.lookAt(position, center, up);
                 break;
             case GLFW_KEY_D:
-                std::cout << "Move right" << std::endl;
+				//std::cout << "Move right" << std::endl;
                 position += glm::normalize(glm::cross(front, up)) * cameraSpeed;
                 center = position + front;
                 camera.lookAt(position, center, up);
                 break;
             default:
-                std::cout << "this key is not supported yet: " << std::endl;
+				__nop;//std::cout << "this key is not supported yet: " << std::endl;
         }
     });
 
@@ -211,7 +211,10 @@ int main(int argc, const char** argv) {
 	while (window.isWindowOpen())
 	{
 		core.beginFrame();
-	    core.renderTriangle(trianglePass, trianglePipeline, windowWidth, windowHeight);
+
+		const glm::mat4 mvp = camera.getProjection() * camera.getView();
+
+	    core.renderTriangle(trianglePass, trianglePipeline, windowWidth, windowHeight, sizeof(mvp), &mvp);
 	    core.endFrame();
 	}
 	return 0;
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 488715116cbb3b978dfab79e1e0e3d8e05c0f4dc..2a8dddfc57f767089079aa17cc28bae5dcb3e555 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -167,7 +167,8 @@ namespace vkcv
 	}
 
 	void Core::renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, 
-		const int width, const int height) {
+		const int width, const int height, const size_t pushConstantSize, const void *pushConstantData) {
+
 		if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) {
 			return;
 		}
@@ -184,7 +185,9 @@ namespace vkcv
 		m_CommandResources.commandBuffer.beginRenderPass(beginInfo, subpassContents, {});
 
 		const vk::Pipeline pipeline = m_PipelineManager->getVkPipeline(pipelineHandle);
+		const vk::PipelineLayout pipelineLayout = m_PipelineManager->getVkPipelineLayout(pipelineHandle);
 		m_CommandResources.commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {});
+		m_CommandResources.commandBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData);
 		m_CommandResources.commandBuffer.draw(3, 1, 0, 0, {});
 		m_CommandResources.commandBuffer.endRenderPass();
 	}
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index e6d6beea463f17c86d958c9080f34eb61e9076c2..576cb47397a29184160423fdba6d1a09104a5566 100644
--- a/src/vkcv/PipelineManager.cpp
+++ b/src/vkcv/PipelineManager.cpp
@@ -140,14 +140,14 @@ namespace vkcv
                 { 1.f,1.f,1.f,1.f }
         );
 
+		const size_t matrixPushConstantSize = 4 * 4 * sizeof(float);
+		const vk::PushConstantRange pushConstantRange(vk::ShaderStageFlagBits::eAll, 0, matrixPushConstantSize);
+
         // pipeline layout
         vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo(
-                {},
-                0,
-                {},
-                0,
-                {}
-        );
+			{},
+			{},
+			(pushConstantRange));
         vk::PipelineLayout vkPipelineLayout{};
         if (m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &vkPipelineLayout) != vk::Result::eSuccess)
         {