diff --git a/projects/first_triangle/shaders/comp.spv b/projects/first_triangle/shaders/comp.spv
new file mode 100644
index 0000000000000000000000000000000000000000..622ced351097932ea7f7eb1451e9433bc017812d
Binary files /dev/null and b/projects/first_triangle/shaders/comp.spv differ
diff --git a/projects/first_triangle/shaders/shader.comp b/projects/first_triangle/shaders/shader.comp
new file mode 100644
index 0000000000000000000000000000000000000000..c63870daa744a7a8d533ad27d2ef18978e527093
--- /dev/null
+++ b/projects/first_triangle/shaders/shader.comp
@@ -0,0 +1,21 @@
+#version 440
+
+layout(local_size_x_id = 0, local_size_y_id = 1) in; // workgroup size defined with specialization constants. On cpp side there is associated SpecializationInfo entry in PipelineShaderStageCreateInfo
+layout(push_constant) uniform Parameters {           // specify push constants. on cpp side its layout is fixed at PipelineLayout, and values are provided via vk::CommandBuffer::pushConstants()
+    uint Width;
+    uint Height;
+    float a;
+} params;
+
+layout(std430, binding = 0) buffer lay0 { float arr_y[]; };
+layout(std430, binding = 1) buffer lay1 { float arr_x[]; };
+
+void main(){
+    // drop threads outside the buffer dimensions.
+    if(params.Width <= gl_GlobalInvocationID.x || params.Height <= gl_GlobalInvocationID.y){
+        return;
+    }
+    const uint id = params.Width*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x; // current offset
+
+    arr_y[id] += params.a*arr_x[id]; // saxpy
+}
\ No newline at end of file
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 2ede653ff98e19159e0155b282cab1b309a13816..648118a667caa9b0c155ec4ecc58a4b5b90d9b5c 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -92,6 +92,7 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
+	// Graphics Pipeline
 	vkcv::ShaderProgram triangleShaderProgram{};
 	triangleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/vert.spv"));
 	triangleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("shaders/frag.spv"));
@@ -115,6 +116,12 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
+	// Compute Pipeline
+	vkcv::ShaderProgram computeShaderProgram{};
+	computeShaderProgram.addShader(vkcv::ShaderStage::COMPUTE, std::filesystem::path("shaders/comp.spv"));
+
+	vkcv::PipelineHandle computePipeline = core.createComputePipeline(computeShaderProgram);
+
 	/*
 	 * BufferHandle triangleVertices = core.createBuffer(vertices);
 	 * BufferHandle triangleIndices = core.createBuffer(indices);