diff --git a/include/vkcv/Sampler.hpp b/include/vkcv/Sampler.hpp
index 891a96f869c03f5f4a064116bff603acbf2d47e3..141c4511b344f2a6d5e26de0c8ff42b63b9372e1 100644
--- a/include/vkcv/Sampler.hpp
+++ b/include/vkcv/Sampler.hpp
@@ -7,16 +7,25 @@
 
 namespace vkcv {
 
+    /**
+     * Enum class to specify a samplers type to filter during access.
+     */
 	enum class SamplerFilterType {
 		NEAREST = 1,
 		LINEAR = 2
 	};
-	
+
+    /**
+     * Enum class to specify a samplers mode to access mipmaps.
+     */
 	enum class SamplerMipmapMode {
 		NEAREST = 1,
 		LINEAR = 2
 	};
-	
+
+    /**
+     * Enum class to specify a samplers mode to access via address space.
+     */
 	enum class SamplerAddressMode {
 		REPEAT = 1,
 		MIRRORED_REPEAT = 2,
@@ -24,7 +33,10 @@ namespace vkcv {
 		MIRROR_CLAMP_TO_EDGE = 4,
 		CLAMP_TO_BORDER = 5
 	};
-	
+
+    /**
+     * Enum class to specify a samplers color beyond a textures border.
+     */
 	enum class SamplerBorderColor {
 		INT_ZERO_OPAQUE = 1,
 		INT_ZERO_TRANSPARENT = 2,
diff --git a/include/vkcv/ShaderProgram.hpp b/include/vkcv/ShaderProgram.hpp
index 0c2dbdfb8f55bb9f537760428a0c3aa1e7102c46..a45394dcffd594faf1c448b8d4b0a0300e579520 100644
--- a/include/vkcv/ShaderProgram.hpp
+++ b/include/vkcv/ShaderProgram.hpp
@@ -19,12 +19,6 @@
 
 namespace vkcv {
 
-    struct Shader
-    {
-        std::vector<char> shaderCode;
-        ShaderStage shaderStage;
-    };
-
 	class ShaderProgram
 	{
     public:
@@ -48,14 +42,13 @@ namespace vkcv {
         bool addShader(ShaderStage stage, const std::filesystem::path &path);
 
         /**
-         * @brief Returns the shader of a specified stage from the program.
+         * @brief Returns the shader binary of a specified stage from the program.
          * Needed for the transfer to the pipeline.
          *
          * @param[in] stage The stage of the shader
-         * @return Shader object consisting of buffer with shader code and
-         * shader stage enum
+         * @return Shader code binary of the given stage
          */
-        const Shader &getShader(ShaderStage stage) const;
+        const std::vector<uint32_t> &getShaderBinary(ShaderStage stage) const;
 
 		/**
 		 * @brief Returns whether a shader exists in the program for a
@@ -98,11 +91,12 @@ namespace vkcv {
 	     */
         void reflectShader(ShaderStage shaderStage);
 
-        std::unordered_map<ShaderStage, Shader> m_Shaders;
+        std::unordered_map<ShaderStage, std::vector<uint32_t> > m_Shaders;
 
         // contains all vertex input attachments used in the vertex buffer
         std::vector<VertexAttachment> m_VertexAttachments;
         std::unordered_map<uint32_t, DescriptorBindings> m_DescriptorSets;
 		size_t m_pushConstantsSize = 0;
 	};
+
 }
diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
index 00533bc3668a54f245777c7bca4abb56afd3f056..47560b4d9fddb867dd5573c64fe57c24c69095ce 100644
--- a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
+++ b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
@@ -147,23 +147,23 @@ namespace vkcv::rtx {
 
     void RTXModule::createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader) {
         // -- process vkcv::ShaderProgram into vk::ShaderModule
-        std::vector<char> rayGenShaderCode = rtxShader.getShader(ShaderStage::RAY_GEN).shaderCode;
+        std::vector<uint32_t> rayGenShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_GEN);
 
         vk::ShaderModuleCreateInfo rayGenShaderModuleInfo(
             vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_,
-            rayGenShaderCode.size(), // size_t codeSize
-            (const uint32_t*)rayGenShaderCode.data() // const uint32_t* pCode
+            rayGenShaderCode.size() * sizeof(uint32_t), // size_t codeSize
+            rayGenShaderCode.data() // const uint32_t* pCode
         );
         vk::ShaderModule rayGenShaderModule = m_core->getContext().getDevice().createShaderModule(rayGenShaderModuleInfo);
         if (!rayGenShaderModule) {
             vkcv_log(LogLevel::ERROR, "The Ray Generation Shader Module could not be created!");
         }
 
-        std::vector<char> rayMissShaderCode = rtxShader.getShader(ShaderStage::RAY_MISS).shaderCode;
+        std::vector<uint32_t> rayMissShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_MISS);
         vk::ShaderModuleCreateInfo rayMissShaderModuleInfo(
             vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_,
-            rayMissShaderCode.size(), //size_t codeSize
-            (const uint32_t*)rayMissShaderCode.data() // const uint32_t* pCode
+            rayMissShaderCode.size() * sizeof(uint32_t), //size_t codeSize
+            rayMissShaderCode.data() // const uint32_t* pCode
         );
 
         vk::ShaderModule rayMissShaderModule = m_core->getContext().getDevice().createShaderModule(rayMissShaderModuleInfo);
@@ -171,11 +171,11 @@ namespace vkcv::rtx {
             vkcv_log(LogLevel::ERROR, "The Ray Miss Shader Module could not be created!");
         }
 
-        std::vector<char> rayClosestHitShaderCode = rtxShader.getShader(ShaderStage::RAY_CLOSEST_HIT).shaderCode;
+        std::vector<uint32_t> rayClosestHitShaderCode = rtxShader.getShaderBinary(ShaderStage::RAY_CLOSEST_HIT);
         vk::ShaderModuleCreateInfo rayClosestHitShaderModuleInfo(
             vk::ShaderModuleCreateFlags(), // vk::ShaderModuleCreateFlags flags_,
-            rayClosestHitShaderCode.size(), //size_t codeSize
-            (const uint32_t*)rayClosestHitShaderCode.data() // const uint32_t* pCode_
+            rayClosestHitShaderCode.size() * sizeof(uint32_t), //size_t codeSize
+            rayClosestHitShaderCode.data() // const uint32_t* pCode_
         );
         vk::ShaderModule rayClosestHitShaderModule = m_core->getContext().getDevice().createShaderModule(rayClosestHitShaderModuleInfo);
         if (!rayClosestHitShaderModule) {
diff --git a/src/vkcv/ComputePipelineManager.cpp b/src/vkcv/ComputePipelineManager.cpp
index be1caf18264994ebf2b12d5be941e1308ce50cc5..264389ca9b5ed118666911b07158ab589a4ca0ee 100644
--- a/src/vkcv/ComputePipelineManager.cpp
+++ b/src/vkcv/ComputePipelineManager.cpp
@@ -112,8 +112,8 @@ namespace vkcv
 
     vk::Result ComputePipelineManager::createShaderModule(vk::ShaderModule &module, const ShaderProgram &shaderProgram, const ShaderStage stage)
     {
-        std::vector<char> code = shaderProgram.getShader(stage).shaderCode;
-        vk::ShaderModuleCreateInfo moduleInfo({}, code.size(), reinterpret_cast<uint32_t*>(code.data()));
+        std::vector<uint32_t> code = shaderProgram.getShaderBinary(stage);
+        vk::ShaderModuleCreateInfo moduleInfo({}, code.size() * sizeof(uint32_t), code.data());
         return m_Device.createShaderModule(&moduleInfo, nullptr, &module);
     }
 }
\ No newline at end of file
diff --git a/src/vkcv/GraphicsPipelineManager.cpp b/src/vkcv/GraphicsPipelineManager.cpp
index 54206dceb417a75ed4c8b51a6c614fe5ba972618..93face1ee3cfa11483d1b1952c0650d967117381 100644
--- a/src/vkcv/GraphicsPipelineManager.cpp
+++ b/src/vkcv/GraphicsPipelineManager.cpp
@@ -110,8 +110,8 @@ namespace vkcv
             vk::PipelineShaderStageCreateInfo*  outCreateInfo) {
 
         assert(outCreateInfo);
-        std::vector<char>           code = shaderProgram.getShader(stage).shaderCode;
-        vk::ShaderModuleCreateInfo  vertexModuleInfo({}, code.size(), reinterpret_cast<uint32_t*>(code.data()));
+        std::vector<uint32_t>       code = shaderProgram.getShaderBinary(stage);
+        vk::ShaderModuleCreateInfo  vertexModuleInfo({}, code.size() * sizeof(uint32_t), code.data());
         vk::ShaderModule            shaderModule;
         if (device.createShaderModule(&vertexModuleInfo, nullptr, &shaderModule) != vk::Result::eSuccess)
             return false;
diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp
index 64cc3697fd259056262c43fbf6bfee2e2a0e0b13..4b2afbd43cd965a14b6e2748122f9866077e8f6f 100644
--- a/src/vkcv/ShaderProgram.cpp
+++ b/src/vkcv/ShaderProgram.cpp
@@ -14,19 +14,25 @@ namespace vkcv {
      * @param[in] relative path to the shader code
      * @return vector of chars as a buffer for the code
      */
-	std::vector<char> readShaderCode(const std::filesystem::path &shaderPath) {
+	std::vector<uint32_t> readShaderCode(const std::filesystem::path &shaderPath) {
 		std::ifstream file (shaderPath.string(), std::ios::ate | std::ios::binary);
 		
 		if (!file.is_open()) {
-			vkcv_log(LogLevel::ERROR, "The file could not be opened");
-			return std::vector<char>{};
+			vkcv_log(LogLevel::ERROR, "The file could not be opened: %s", shaderPath.c_str());
+			return std::vector<uint32_t>();
 		}
 		
 		size_t fileSize = (size_t)file.tellg();
-		std::vector<char> buffer(fileSize);
+
+        if (fileSize % sizeof(uint32_t) != 0) {
+            vkcv_log(LogLevel::ERROR, "The file is not a valid shader: %s", shaderPath.c_str());
+            return std::vector<uint32_t>();
+        }
+
+		std::vector<uint32_t> buffer(fileSize / sizeof(uint32_t));
 		
 		file.seekg(0);
-		file.read(buffer.data(), fileSize);
+		file.read(reinterpret_cast<char*>(buffer.data()), fileSize);
 		file.close();
 		
         return buffer;
@@ -82,19 +88,18 @@ namespace vkcv {
 			vkcv_log(LogLevel::WARNING, "Overwriting existing shader stage");
 		}
 
-	    const std::vector<char> shaderCode = readShaderCode(path);
+	    const std::vector<uint32_t> shaderCode = readShaderCode(path);
 	    
 	    if (shaderCode.empty()) {
 			return false;
 		} else {
-            Shader shader{shaderCode, stage};
-            m_Shaders.insert(std::make_pair(stage, shader));
+            m_Shaders.insert(std::make_pair(stage, shaderCode));
             reflectShader(stage);
             return true;
         }
 	}
 
-    const Shader &ShaderProgram::getShader(ShaderStage stage) const
+    const std::vector<uint32_t> &ShaderProgram::getShaderBinary(ShaderStage stage) const
     {
 	    return m_Shaders.at(stage);
 	}
@@ -109,13 +114,9 @@ namespace vkcv {
 
     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]);
+        auto shaderCode = m_Shaders.at(shaderStage);
 
-        spirv_cross::Compiler comp(move(shaderCode));
+        spirv_cross::Compiler comp(shaderCode);
         spirv_cross::ShaderResources resources = comp.get_shader_resources();
 
         //reflect vertex input