diff --git a/.gitmodules b/.gitmodules
index b44e47387fc30a41c3f5c8d09b5ad525b354f233..323286b592292b798a8b6ca03dde3651dd36239e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "lib/glfw"]
 	path = lib/glfw
 	url = https://github.com/glfw/glfw.git
+[submodule "lib/SPIRV-Cross"]
+	path = lib/SPIRV-Cross
+	url = https://github.com/KhronosGroup/SPIRV-Cross.git
diff --git a/config/Libraries.cmake b/config/Libraries.cmake
index 13667936dd100be91ab43b73e6774e7db3da876c..e04aa3575a34632eb75c929bf4640305cd93e298 100644
--- a/config/Libraries.cmake
+++ b/config/Libraries.cmake
@@ -16,6 +16,7 @@ set(vkcv_config_msg " - Library: ")
 # load dependencies via separate cmake file
 include(${vkcv_config_lib}/GLFW.cmake)    # glfw-x11 / glfw-wayland					# libglfw3-dev
 include(${vkcv_config_lib}/Vulkan.cmake)  # vulkan-intel / vulkan-radeon / nvidia	# libvulkan-dev
+include(${vkcv_config_lib}/SPIRV_Cross.cmake)  # SPIRV-Cross	                    # libspirv_cross_c_shared
 
 # cleanup of compiler flags
 if (vkcv_flags)
diff --git a/config/Sources.cmake b/config/Sources.cmake
index cb73f57c2ca7278765ef0c8d01989c09a445c7b5..998c26723940788dc2ddd427dc1a18b979ab6967 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -61,4 +61,7 @@ set(vkcv_sources
 
 		${vkcv_include}/vkcv/DescriptorConfig.hpp
 		${vkcv_source}/vkcv/DescriptorConfig.cpp
+
+		${vkcv_include}/vkcv/VertexLayout.hpp
+		${vkcv_source}/vkcv/VertexLayout.cpp
 )
diff --git a/config/lib/SPIRV_Cross.cmake b/config/lib/SPIRV_Cross.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..751ee883c47e0eab081a13e5805ced6f2daa7e30
--- /dev/null
+++ b/config/lib/SPIRV_Cross.cmake
@@ -0,0 +1,22 @@
+find_package(spirv_cross_c_shared QUIET)
+
+if (spirv-cross_FOUND)
+    list(APPEND vkcv_libraries spirv-cross-cpp)
+
+    message(${vkcv_config_msg} " SPIRV Cross    - " ${SPIRV_CROSS_VERSION})
+else()
+    if (EXISTS "${vkcv_lib_path}/SPIRV-Cross")
+        set(SPIRV_CROSS_CLI OFF CACHE INTERNAL "")
+        set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE INTERNAL "")
+        set(SPIRV_CROSS_ENABLE_C_API OFF CACHE INTERNAL "")
+        set(SPIRV_CROSS_SKIP_INSTALL ON CACHE INTERNAL "")
+    
+        add_subdirectory(${vkcv_lib}/SPIRV-Cross)
+
+        list(APPEND vkcv_libraries spirv-cross-cpp)
+
+        message(${vkcv_config_msg} " SPIRV Cross    - " ${SPIRV_CROSS_VERSION})
+    else()
+        message(WARNING "SPIRV-Cross is required..! Update the submodules!")
+    endif ()
+endif ()
\ No newline at end of file
diff --git a/include/vkcv/ShaderProgram.hpp b/include/vkcv/ShaderProgram.hpp
index 172e906fca457c6245855639275054514958b69d..af60f9fb7af196ec8576320742fc86893ddc7b8e 100644
--- a/include/vkcv/ShaderProgram.hpp
+++ b/include/vkcv/ShaderProgram.hpp
@@ -10,6 +10,8 @@
 #include <iostream>
 #include <filesystem>
 #include <vulkan/vulkan.hpp>
+#include <spirv_cross.hpp>
+#include "vkcv/VertexLayout.hpp"
 
 namespace vkcv {
 
@@ -53,8 +55,13 @@ namespace vkcv {
 
         bool existsShader(ShaderStage shaderStage) const;
 
+        void reflectShader(ShaderStage shaderStage);
+
+        VertexLayout& getVertexLayout();
+
 	private:
         std::unordered_map<ShaderStage, Shader> m_Shaders;
 
+        VertexLayout m_VertexLayout;
 	};
 }
diff --git a/include/vkcv/VertexLayout.hpp b/include/vkcv/VertexLayout.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9579b5d7dfa8127d592532f55fd569cacb505c9
--- /dev/null
+++ b/include/vkcv/VertexLayout.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <unordered_map>
+#include <vector>
+#include <iostream>
+
+namespace vkcv{
+    enum class VertexFormat{
+        FLOAT,
+        FLOAT2,
+        FLOAT3,
+        FLOAT4,
+        INT,
+        INT2,
+        INT3,
+        INT4
+    };
+
+    struct VertexInputAttachment{
+        VertexInputAttachment() = delete;
+        VertexInputAttachment(uint32_t location, uint32_t binding, VertexFormat format, uint32_t offset) noexcept;
+
+        uint32_t location;
+        uint32_t binding;
+        VertexFormat format;
+        uint32_t offset;
+    };
+
+    struct VertexLayout{
+        VertexLayout() noexcept;
+        VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept;
+        std::unordered_map<uint32_t, VertexInputAttachment> attachmentMap;
+        uint32_t stride;
+    };
+
+
+}
\ No newline at end of file
diff --git a/lib/SPIRV-Cross b/lib/SPIRV-Cross
new file mode 160000
index 0000000000000000000000000000000000000000..ff61890722a91e97c44940494be5b6eed0d5ff5b
--- /dev/null
+++ b/lib/SPIRV-Cross
@@ -0,0 +1 @@
+Subproject commit ff61890722a91e97c44940494be5b6eed0d5ff5b
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 07da9506c5546985d4852e5d7d87ecbbcfe5e788..a515005e18ddaee99959a5c97b6978a0054ee574 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -86,6 +86,8 @@ int main(int argc, const char** argv) {
 	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"));
+	triangleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX);
+    triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT);
 
 	const vkcv::PipelineConfig trianglePipelineDefinition(triangleShaderProgram, windowWidth, windowHeight, trianglePass);
 	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp
index 87ccdefbfec0b4891d3152d30aa6c9f6c8c0d5ea..69ad7c3188d3dd0ae940b8bdd1c628d4fc702c7f 100644
--- a/src/vkcv/ShaderProgram.cpp
+++ b/src/vkcv/ShaderProgram.cpp
@@ -27,8 +27,46 @@ namespace vkcv {
         return buffer;
 	}
 
+	VertexFormat convertFormat(spirv_cross::SPIRType::BaseType basetype, uint32_t vecsize){
+        switch (basetype) {
+            case spirv_cross::SPIRType::Int:
+                switch (vecsize) {
+                    case 1:
+                        return VertexFormat::INT;
+                    case 2:
+                        return VertexFormat::INT2;
+                    case 3:
+                        return VertexFormat::INT3;
+                    case 4:
+                        return VertexFormat::INT4;
+                    default:
+                        break;
+                }
+                break;
+            case spirv_cross::SPIRType::Float:
+                switch (vecsize) {
+                    case 1:
+                        return VertexFormat::FLOAT;
+                    case 2:
+                        return VertexFormat::FLOAT2;
+                    case 3:
+                        return VertexFormat::FLOAT3;
+                    case 4:
+                        return VertexFormat::FLOAT4;
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+        std::cout << "Shader Program Reflection: unknown Vertex Format" << std::endl;
+        return VertexFormat::FLOAT;
+	}
+
 	ShaderProgram::ShaderProgram() noexcept :
-	m_Shaders{}
+	m_Shaders{},
+    m_VertexLayout{}
 	{}
 
 	bool ShaderProgram::addShader(ShaderStage shaderStage, const std::filesystem::path &shaderPath)
@@ -59,4 +97,38 @@ namespace vkcv {
 	    else
 	        return true;
     }
+
+    void ShaderProgram::reflectShader(ShaderStage shaderStage)
+    {
+        auto shaderCodeChar = m_Shaders.at(shaderStage).shaderCode;
+        std::vector<uint32_t> shaderCode;
+
+        for (uint32_t i = 0; i < shaderCodeChar.size()/4; i++) {
+            shaderCode.push_back(((uint32_t*) shaderCodeChar.data())[i]);
+        }
+
+        spirv_cross::Compiler comp(move(shaderCode));
+        spirv_cross::ShaderResources resources = comp.get_shader_resources();
+
+        std::vector<VertexInputAttachment> inputVec;
+        uint32_t offset = 0;
+
+        for (uint32_t i = 0; i < resources.stage_inputs.size() ; i++){
+            auto &u = resources.stage_inputs[i];
+            const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id);
+
+            VertexInputAttachment input = VertexInputAttachment(comp.get_decoration(u.id,spv::DecorationLocation),
+                                                                0,
+                                                                convertFormat(base_type.basetype, base_type.vecsize),
+                                                                offset);
+            inputVec.push_back(input);
+            offset += base_type.vecsize * base_type.width/8;
+        }
+
+        m_VertexLayout = VertexLayout(inputVec);
+    }
+
+    VertexLayout& ShaderProgram::getVertexLayout(){
+        return m_VertexLayout;
+	}
 }
diff --git a/src/vkcv/VertexLayout.cpp b/src/vkcv/VertexLayout.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..88c9406bc321a76b48df60dae51486e39a4160de
--- /dev/null
+++ b/src/vkcv/VertexLayout.cpp
@@ -0,0 +1,53 @@
+//
+// Created by Charlotte on 28.05.2021.
+//
+
+#include "vkcv/VertexLayout.hpp"
+
+namespace vkcv {
+    uint32_t static getFormatSize(VertexFormat format) {
+        switch (format) {
+            case VertexFormat::FLOAT:
+                return 4;
+            case VertexFormat::FLOAT2:
+                return 8;
+            case VertexFormat::FLOAT3:
+                return 12;
+            case VertexFormat::FLOAT4:
+                return 16;
+            case VertexFormat::INT:
+                return 4;
+            case VertexFormat::INT2:
+                return 8;
+            case VertexFormat::INT3:
+                return 12;
+            case VertexFormat::INT4:
+                return 16;
+            default:
+                break;
+        }
+        std::cout << "VertexLayout: No format given" << std::endl;
+        return 0;
+    }
+
+    VertexInputAttachment::VertexInputAttachment(uint32_t location, uint32_t binding, VertexFormat format, uint32_t offset) noexcept:
+            location{location},
+            binding{binding},
+            format{format},
+            offset{offset}
+            {}
+
+    VertexLayout::VertexLayout() noexcept :
+    stride{0},
+    attachmentMap()
+    {}
+
+    VertexLayout::VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept {
+        stride = 0;
+        for (const auto &input : inputs) {
+            attachmentMap.insert(std::make_pair(input.location, input));
+            stride += getFormatSize(input.format);
+        }
+    }
+
+}
\ No newline at end of file