diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index e9fd3eb95a90e6ece71c592407b91025804e798f..6f5053e97963a8ebcdaf2ee97c4dd27ba24bf4b0 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -342,8 +342,8 @@ namespace vkcv
         
 
         /**
-         * Prepares RTXPipeline for Raygeneration by recording the binding Table to the Commandstream.
-         * Currently only supports closestHit, rayGen and miss shaderstages.
+         * Prepares the @p rtxPipeline for ray generation by recording the @p shaderBindingTable to the @p cmdStreamHandle.
+         * Currently only supports @p closestHit, @p rayGen and @c miss shaderstages @c.
          * @param cmdStreamHandle The command stream handle which receives relevant commands for drawing.
          * @param rtxPipeline The raytracing pipeline from the RTXModule.
          * @param rtxPipelineLayout The raytracing pipeline layout from the RTXModule.
diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp
index 64f426a787d85f1e753da2bcc83d3c5ca886e6b1..457e8952d0fcb2dbe0ad281f6f8018575c4f4ede 100644
--- a/include/vkcv/DescriptorWrites.hpp
+++ b/include/vkcv/DescriptorWrites.hpp
@@ -37,6 +37,9 @@ namespace vkcv {
 		SamplerHandle	sampler;
 	};
 
+	/**
+	 * @brief Only used for RTX. Used to bind the Acceleration Structure.
+	 */
 	struct AccelerationDescriptorWrite {
 	    inline AccelerationDescriptorWrite(uint32_t binding) : binding(binding) {};
 	    uint32_t    binding;
diff --git a/include/vkcv/FeatureManager.hpp b/include/vkcv/FeatureManager.hpp
index cb4a1f181703fc92050dcd602428bc28dcabafc2..e9abd69009da1120284aefeb375dd380abd20201 100644
--- a/include/vkcv/FeatureManager.hpp
+++ b/include/vkcv/FeatureManager.hpp
@@ -79,15 +79,39 @@ namespace vkcv {
 		[[nodiscard]]
 		bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const;
 
+		/**
+         * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan12Features.
+         * @param features The features.
+         * @param required True, if the @p features are required, else false.
+         * @return @p True, if the @p features are supported, else @p false.
+         */
 		[[nodiscard]]
 		bool checkSupport(const vk::PhysicalDeviceVulkan12Features& features, bool required) const;
 
+		/**
+         * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan11Features.
+         * @param features The features.
+         * @param required True, if the @p features are required, else false.
+         * @return @p True, if the @p features are supported, else @p false.
+         */
 		[[nodiscard]]
 		bool checkSupport(const vk::PhysicalDeviceVulkan11Features& features, bool required) const;
 
+		/**
+		 * @brief Only used for RTX. Checks support of the @p vk::PhysicalDeviceAccelerationStructureFeaturesKHR.
+		 * @param features The features.
+		 * @param required True, if the @p features are required, else false.
+		 * @return @p True, if the @p features are supported, else @p false.
+		 */
 		[[nodiscard]]
 		bool checkSupport(const vk::PhysicalDeviceAccelerationStructureFeaturesKHR& features, bool required) const;
 
+		/**
+         * @brief Only used for RTX. Checks support of the @p vk::PhysicalDeviceRayTracingPipelineFeaturesKHR.
+         * @param features The features.
+         * @param required True, if the @p features are required, else false.
+         * @return @p True, if the @p features are supported, else @p false.
+         */
 		[[nodiscard]]
 		bool checkSupport(const vk::PhysicalDeviceRayTracingPipelineFeaturesKHR& features, bool required) const;
 		
diff --git a/include/vkcv/ShaderStage.hpp b/include/vkcv/ShaderStage.hpp
index 368cd9ae3fb1a184810f9322d2416e2f924e5426..0baaaf5b57fcc510159b8620e3119e4749467093 100644
--- a/include/vkcv/ShaderStage.hpp
+++ b/include/vkcv/ShaderStage.hpp
@@ -13,12 +13,12 @@ namespace vkcv {
 		COMPUTE         = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCompute),
 		TASK            = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eTaskNV),
 		MESH            = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMeshNV),
-		RAY_GEN          = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eRaygenKHR),
-		RAY_ANY_HIT         = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eAnyHitKHR),
-		RAY_CLOSEST_HIT     = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eClosestHitKHR),
-		RAY_MISS            = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMissKHR),
-		RAY_INTERSECTION    = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eIntersectionKHR),
-		RAY_CALLABLE        = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCallableKHR)
+		RAY_GEN          = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eRaygenKHR), // RTX
+		RAY_ANY_HIT         = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eAnyHitKHR), // RTX
+		RAY_CLOSEST_HIT     = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eClosestHitKHR), // RTX
+		RAY_MISS            = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMissKHR), // RTX
+		RAY_INTERSECTION    = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eIntersectionKHR), // RTX
+		RAY_CALLABLE        = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCallableKHR) // RTX
 	};
 	
 	using ShaderStages = vk::Flags<ShaderStage>;
diff --git a/modules/rtx/include/vkcv/rtx/ASManager.hpp b/modules/rtx/include/vkcv/rtx/ASManager.hpp
index ec49cc6ba12acc94d4b215ac5c8fd67aa34d8caf..0cdb14d110982845b8106707ad845baac493094d 100644
--- a/modules/rtx/include/vkcv/rtx/ASManager.hpp
+++ b/modules/rtx/include/vkcv/rtx/ASManager.hpp
@@ -60,23 +60,29 @@ namespace vkcv::rtx {
         vk::DispatchLoaderDynamic m_rtxDispatcher;
         
         /**
-            TODO
-        */
+         * Creates a command pool.
+         */
         vk::CommandPool createCommandPool();
 
         /**
-            TODO
-        */
+         * @brief Takes a @p cmdPool, allocates a command buffer and starts recording it.
+         * @param cmdPool The command pool.
+         * @return The allocated command buffer.
+         */
         vk::CommandBuffer allocateAndBeginCommandBuffer( vk::CommandPool cmdPool);
 
         /**
-           TODO
-        */
+         * @brief Ends recording, submits, waits, and then frees the @p commandBuffer.
+         * @param commandPool The command pool.
+         * @param commandBuffer The command buffer.
+         */
         void submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer);
 
         /**
-           TODO
-        */
+         * @brief Gets the device address of a @p buffer.
+         * @param buffer The buffer.
+         * @return The device address of the @p buffer.
+         */
         vk::DeviceAddress getBufferDeviceAddress(vk::Buffer buffer);
 
         /**
@@ -102,9 +108,9 @@ namespace vkcv::rtx {
         ~ASManager();
 
         /**
-         * @brief Returns a #RTXBuffer object holding data of type uint16_t from given @p data of type uint8_t.
-         * @param data The input data of type uint8_t.
-         * @return A @#RTXBuffer object holding @p data.
+         * @brief Returns a @#RTXBuffer object holding data of type @p T.
+         * @param data The input data of type @p T.
+         * @return A @#RTXBuffer object holding @p data of type @p T.
          */
         template<class T>
         RTXBuffer makeBufferFromData(std::vector<T>& data) {
@@ -112,11 +118,6 @@ namespace vkcv::rtx {
             // first: Staging Buffer creation
             RTXBuffer stagingBuffer;
             stagingBuffer.bufferType = RTXBufferType::STAGING;
-            auto test = sizeof(T);
-            auto test1 = sizeof(float);
-            auto test1a = sizeof(uint32_t);
-            auto test2 = sizeof(data[0]);
-            auto test3 = data.size();
             stagingBuffer.deviceSize = sizeof(T) * data.size();
             stagingBuffer.data = data.data();
             stagingBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eTransferSrc;
@@ -143,17 +144,19 @@ namespace vkcv::rtx {
         };
 
         /**
-        * @brief A helper function used by #ASManager::makeBufferFromData. Creates a fully initialized #RTXBuffer object
+        * @brief A helper function used by @#ASManager::makeBufferFromData. Creates a fully initialized @#RTXBuffer object
         * from partially specified @p buffer. All missing data of @p buffer will be completed by this function.
-        * @param buffer The partially specified #RTXBuffer holding that part of information which is required for
-        * successfully creating a vk::Buffer object.
+        * @param buffer The partially specified @#RTXBuffer holding that part of information which is required for
+        * successfully creating a @p vk::Buffer object.
         */
         void createBuffer(RTXBuffer& buffer);
 
         /**
-         * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertices and @p indices.
-         * @param[in] vertices The vertex data of type uint8_t.
-         * @param[in] indices The index data of type uint8_t.
+         * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertexBuffer and @p indexBuffer.
+         * @param[in] vertexBuffer The vertex data.
+         * @param[in] vertexCount The amount of vertices in @p vertexBuffer.
+         * @param[in] indexBuffer The index data.
+         * @param[in] indexCount The amount of indices in @p indexBuffer.
          */
         void buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount);
 
@@ -164,8 +167,8 @@ namespace vkcv::rtx {
         void buildTLAS();
 
         /**
-        * @brief Returns the top-level acceleration structure buffer.
-        * @return A @#TopLevelAccelerationStructure object holding the tlas.
+        * @brief Returns the top-level acceleration structure (TLAS) buffer.
+        * @return A @#TopLevelAccelerationStructure object holding the TLAS.
         */
         TopLevelAccelerationStructure getTLAS();
 
diff --git a/modules/rtx/include/vkcv/rtx/RTX.hpp b/modules/rtx/include/vkcv/rtx/RTX.hpp
index 78b1185374f668ab2a13044631ed34d852d56372..3712ddb98948ebb5205ee6b8851b8422ea754b12 100644
--- a/modules/rtx/include/vkcv/rtx/RTX.hpp
+++ b/modules/rtx/include/vkcv/rtx/RTX.hpp
@@ -14,18 +14,18 @@ namespace vkcv::rtx {
         ASManager* m_asManager;
         vk::Pipeline m_pipeline;
         vk::PipelineLayout m_pipelineLayout;
-        RTXBuffer m_shaderBindingtableBuffer;
+        RTXBuffer m_shaderBindingTableBuffer;
         vk::DeviceSize m_shaderGroupBaseAlignment;
 
     public:
 
         /**
-         * TODO
-         * @brief Initializes the RTXModule with scene data.
-         * @param core The reference to the #Core.
-         * @param vertices The scene vertex data of type uint8_t.
-         * @param indices The scene index data of type uint8_t.
-         * @param descriptorSetHandles The descriptorSetHandles for RTX
+         * @brief Initializes the @#RTXModule with scene data.
+         * @param core The reference to the @#Core.
+         * @param asManager The reference to the @#ASManager.
+         * @param vertices The vertex data of the scene.
+         * @param indices The index data of the scene.
+         * @param descriptorSetHandles The descriptor set handles for RTX.
          */
         RTXModule(Core* core, ASManager* asManager, std::vector<float>& vertices,
             std::vector<uint32_t>& indices, std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles);
@@ -36,47 +36,50 @@ namespace vkcv::rtx {
         ~RTXModule();
 
         /**
-         * @brief TODO
-         * @return
+         * @brief Returns the RTX pipeline.
+         * @return The RTX pipeline.
          */
         vk::Pipeline getPipeline();
 
-        /** TODO
-        */
-        vk::Buffer getShaderBindingBuffer();
+        /**
+         * @brief Returns the shader binding table buffer.
+         * @return The shader binding table buffer.
+         */
+        vk::Buffer getShaderBindingTableBuffer();
 
-        /** TODO
-        */
+        /**
+         * @brief Returns the shader group base alignment for partitioning the shader binding table buffer.
+         * @return The shader group base alignment.
+         */
         vk::DeviceSize getShaderGroupBaseAlignment();
 
         /**
-         * @brief TODO
-         * @return
+         * @brief Returns the RTX pipeline layout.
+         * @return The RTX pipeline layout.
          */
         vk::PipelineLayout getPipelineLayout();
 
-        /** TODO
-        */
+        /**
+         * @brief Sets the shader group base alignment and creates the shader binding table by allocating a shader
+         * binding table buffer. The allocation depends on @p shaderCount and the shader group base alignment.
+         * @param shaderCount The amount of shaders to be used for RTX.
+         */
         void createShaderBindingTable(uint32_t shaderCount);
 
         /**
          * @brief Creates Descriptor-Writes for RTX
-         * @param descriptorSetHandles The descriptorSetHandles for RTX
+         * @param descriptorSetHandles The descriptorSetHandles for RTX.
          */
         void RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles);
 
         /**
-         * TODO
-         * @brief Returns the Vulkan handle of the RTX pipeline.
-         * @param descriptorSetLayouts The descriptorSetLayouts used for creating a @p vk::PipelineLayoutCreateInfo.
-         * @param rayGenShader The ray generation shader.
-         * @param rayMissShader The ray miss shader.
-         * @param rayClostestHitShader The ray closest hit shader.
-         * @return The Vulkan handle of the RTX pipeline.
+         * @brief Creates the RTX pipeline and the RTX pipeline layout. Currently, only RayGen, RayClosestHit and
+         * RayMiss are supported.
+         * @param pushConstantSize The size of the push constant used in the RTX shaders.
+         * @param descriptorSetLayouts The descriptor set layout handles.
+         * @param rtxShader The RTX shader program.
          */
-        //void createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rayGenShader, ShaderProgram &rayMissShader, ShaderProgram &rayClosestHitShader);
-
-        void createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader);
+        void createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader);
     };
 
 }
diff --git a/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp b/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp
index b868b568c123ef4cbc717d10c3b9d9ce5afb224a..067428e07c349b6ad9f64452bef91686549b4efa 100644
--- a/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp
+++ b/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp
@@ -8,7 +8,7 @@ class RTXExtensions {
 private:
     std::vector<const char*> m_instanceExtensions;  // the instance extensions needed for using RTX
     std::vector<const char*> m_deviceExtensions;    // the device extensions needed for using RTX
-    vkcv::Features m_features; // the features needed to be enabled for using RTX
+    vkcv::Features m_features;                      // the features needed to be enabled for using RTX
 public:
 
     RTXExtensions();
diff --git a/modules/rtx/src/vkcv/rtx/ASManager.cpp b/modules/rtx/src/vkcv/rtx/ASManager.cpp
index 6501e78e425b1797d92aef33e6bc88b067d1199b..67bf2048920589b94e600b311952f64a0b8dc239 100644
--- a/modules/rtx/src/vkcv/rtx/ASManager.cpp
+++ b/modules/rtx/src/vkcv/rtx/ASManager.cpp
@@ -7,12 +7,13 @@ namespace vkcv::rtx {
     ASManager::ASManager(vkcv::Core *core) :
     m_core(core),
     m_device(&(core->getContext().getDevice())){
-        // INFO: It seems that we need a dynamic dispatch loader because Vulkan is an ASs ...
+        // INFO: Using RTX extensions implies that we cannot use the standard dispatcher from Vulkan because using RTX
+        // specific functions via vk::Device will result in validation errors. Instead we need to use a
+        // vk::DispatchLoaderDynamic which is used as dispatcher parameter of the device functions.
         m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") );
         m_rtxDispatcher.init(m_core->getContext().getInstance());
 
-        // SUGGESTION: recursive call of buildBLAS etc.
-
+        // TODO: Recursive call of buildBLAS for bigger scenes. Currently, the RTX module only supports one mesh.
     }
 
     ASManager::~ASManager() noexcept {
@@ -55,7 +56,6 @@ namespace vkcv::rtx {
         return commandPool;
     };
 
-    // Allocates and begins a one-time command buffer from the command pool.
     vk::CommandBuffer ASManager::allocateAndBeginCommandBuffer(vk::CommandPool commandPool)
     {
         vk::CommandBufferAllocateInfo commandBufferAllocateInfo{};
@@ -72,7 +72,6 @@ namespace vkcv::rtx {
         return commandBuffer;
     }
 
-    // Ends recording, submits, waits, and then frees the command buffer.
     void ASManager::submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer)
     {
         commandBuffer.end();
@@ -90,36 +89,12 @@ namespace vkcv::rtx {
         m_device->destroyCommandPool(commandPool);
     }
 
-    // Gets the device address of a buffer.
     vk::DeviceAddress ASManager::getBufferDeviceAddress(vk::Buffer buffer)
     {
         vk::BufferDeviceAddressInfo bufferDeviceAddressInfo(buffer);
         return m_device->getBufferAddress(bufferDeviceAddressInfo);
     }
 
-
-    // Find a memory in `memoryTypeBitsRequirement` that includes all of `requiredProperties`
-    // taken from Vulkan Spec
-    int32_t findProperties(vk::PhysicalDeviceMemoryProperties* pMemoryProperties,
-        uint32_t memoryTypeBitsRequirement,
-        vk::MemoryPropertyFlags requiredProperties) {
-        const uint32_t memoryCount = pMemoryProperties->memoryTypeCount;
-        for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) {
-            const uint32_t memoryTypeBits = (1 << memoryIndex);
-            const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits;
-
-            const vk::MemoryPropertyFlags properties =
-                pMemoryProperties->memoryTypes[memoryIndex].propertyFlags;
-            const bool hasRequiredProperties =
-                (properties & requiredProperties) == requiredProperties;
-
-            if (isRequiredMemoryType && hasRequiredProperties)
-                return static_cast<int32_t>(memoryIndex);
-        }
-        // failed to find memory type
-        return -1;
-    }
-
     void ASManager::createBuffer(RTXBuffer& buffer) {
 
         vk::BufferCreateInfo bufferCreateInfo;
@@ -140,14 +115,13 @@ namespace vkcv::rtx {
 
         uint32_t memoryTypeIndex = -1;
         for (int i = 0; i < physicalDeviceMemoryProperties.memoryTypeCount; i++) {
-            if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i)) && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) {
+            if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i))
+                    && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) {
                 memoryTypeIndex = i;
                 break;
             }
         }
 
-
-
         vk::MemoryAllocateInfo memoryAllocateInfo(
             memoryRequirements2.memoryRequirements.size,  // size of allocation in bytes
             memoryTypeIndex // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure.
@@ -186,6 +160,7 @@ namespace vkcv::rtx {
     }
 
     void ASManager::buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount) {
+        // TODO: organize hierarchical structure of multiple BLAS
 
         vk::DeviceAddress vertexBufferAddress = getBufferDeviceAddress(vertexBuffer.vulkanHandle);
         vk::DeviceAddress indexBufferAddress = getBufferDeviceAddress(indexBuffer.vulkanHandle);
@@ -239,7 +214,7 @@ namespace vkcv::rtx {
                 );
 
         // create buffer for acceleration structure
-        RTXBuffer blasBuffer; // NOT scratch Buffer
+        RTXBuffer blasBuffer;
         blasBuffer.bufferType = RTXBufferType::ACCELERATION;
         blasBuffer.deviceSize = asBuildSizesInfo.accelerationStructureSize;
         blasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR
@@ -308,7 +283,9 @@ namespace vkcv::rtx {
     }
 
     void ASManager::buildTLAS() {
-        // We need an the device address of each BLAS --> TODO: for loop
+        // TODO: organize hierarchical structure of multiple BLAS
+
+        // We need an the device address of each BLAS --> TODO: for loop for bigger scenes
         vk::AccelerationStructureDeviceAddressInfoKHR addressInfo(
             m_bottomLevelAccelerationStructures[0].vulkanHandle
         );
@@ -389,18 +366,18 @@ namespace vkcv::rtx {
             {}    // vk::GeometryFlagsKHR flags_ = {}
         );
 
-        // Finally, create the TLAS (--> ASs)
+        // Finally, create the TLAS
         vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo(
             vk::AccelerationStructureTypeKHR::eTopLevel, // type of the AS: bottom vs. top
             vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency
             vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update
             {}, // src AS (this seems to be for copying AS)
             {}, // dst AS (this seems to be for copying AS)
-            1, // the geometryCount. TODO: how many do we need?
+            1, // the geometryCount.
             &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry?
         );
 
-        // Query the worst -case AS size and scratch space size based on the number of instances (in this case, 1).
+        // Query the worst-case AS size and scratch space size based on the number of instances (in this case, 1).
         vk::AccelerationStructureBuildSizesInfoKHR asSizeInfo;
         m_core->getContext().getDevice().getAccelerationStructureBuildSizesKHR(
             vk::AccelerationStructureBuildTypeKHR::eDevice,
diff --git a/modules/rtx/src/vkcv/rtx/RTX.cpp b/modules/rtx/src/vkcv/rtx/RTX.cpp
index 7a8e48ff6715851f2a4f6c5fc836139ba87b0df6..6a64b442588794c02fc9312f4aa08db5a7160814 100644
--- a/modules/rtx/src/vkcv/rtx/RTX.cpp
+++ b/modules/rtx/src/vkcv/rtx/RTX.cpp
@@ -19,8 +19,8 @@ namespace vkcv::rtx {
     {
         m_core->getContext().getDevice().destroy(m_pipeline);
         m_core->getContext().getDevice().destroy(m_pipelineLayout);
-        m_core->getContext().getDevice().destroy(m_shaderBindingtableBuffer.vulkanHandle);
-        m_core->getContext().getDevice().freeMemory(m_shaderBindingtableBuffer.deviceMemory);
+        m_core->getContext().getDevice().destroy(m_shaderBindingTableBuffer.vulkanHandle);
+        m_core->getContext().getDevice().freeMemory(m_shaderBindingTableBuffer.deviceMemory);
     }
     
     void RTXModule::createShaderBindingTable(uint32_t shaderCount) {
@@ -32,14 +32,14 @@ namespace vkcv::rtx {
         m_core->getContext().getPhysicalDevice().getProperties2(&physicalProperties);
 
         vk::DeviceSize shaderBindingTableSize = rayTracingProperties.shaderGroupHandleSize * shaderCount;
-       
-       
-        m_shaderBindingtableBuffer.bufferType = RTXBufferType::SHADER_BINDING;
-        m_shaderBindingtableBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderBindingTableKHR | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR;
-        m_shaderBindingtableBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostVisible;
-        m_shaderBindingtableBuffer.deviceSize = shaderBindingTableSize;
 
-        m_asManager->createBuffer(m_shaderBindingtableBuffer);
+
+        m_shaderBindingTableBuffer.bufferType = RTXBufferType::SHADER_BINDING;
+        m_shaderBindingTableBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderBindingTableKHR | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR;
+        m_shaderBindingTableBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostVisible;
+        m_shaderBindingTableBuffer.deviceSize = shaderBindingTableSize;
+
+        m_asManager->createBuffer(m_shaderBindingTableBuffer);
 
         void* shaderHandleStorage = (void*)malloc(sizeof(uint8_t) * shaderBindingTableSize);
         
@@ -49,13 +49,13 @@ namespace vkcv::rtx {
         }
 
         m_shaderGroupBaseAlignment =  rayTracingProperties.shaderGroupBaseAlignment;
-        uint8_t* mapped = (uint8_t*) m_core->getContext().getDevice().mapMemory(m_shaderBindingtableBuffer.deviceMemory, 0, shaderBindingTableSize);
+        uint8_t* mapped = (uint8_t*) m_core->getContext().getDevice().mapMemory(m_shaderBindingTableBuffer.deviceMemory, 0, shaderBindingTableSize);
         for (int i = 0; i < shaderCount; i++) {
             memcpy(mapped, (uint8_t*)shaderHandleStorage + (i * rayTracingProperties.shaderGroupHandleSize), rayTracingProperties.shaderGroupHandleSize);
             mapped += m_shaderGroupBaseAlignment;
         }
 
-        m_core->getContext().getDevice().unmapMemory(m_shaderBindingtableBuffer.deviceMemory);
+        m_core->getContext().getDevice().unmapMemory(m_shaderBindingTableBuffer.deviceMemory);
         free(shaderHandleStorage);        
     }
 
@@ -113,9 +113,7 @@ namespace vkcv::rtx {
         m_core->getContext().getDevice().updateDescriptorSets(indexWrite, nullptr);
     }
 
-    void RTXModule::createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader) {
-        // TODO: maybe all of this must be moved to the vkcv::PipelineManager? If we use scene.recordDrawcalls(), this requires a vkcv::PipelineHandle and not a vk::Pipeline
-
+    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;
 
@@ -170,7 +168,7 @@ namespace vkcv::rtx {
             "main" // const char* pName_ = {},
         );
       
-        // ray clostest hit
+        // ray closest hit
         vk::PipelineShaderStageCreateInfo rayClosestHitShaderStageInfo(
             vk::PipelineShaderStageCreateFlags(), // vk::PipelineShaderStageCreateFlags flags_ = {}
             vk::ShaderStageFlagBits::eClosestHitKHR, // vk::ShaderStageFlagBits stage_ = vk::ShaderStageFlagBits::eVertex,
@@ -178,13 +176,13 @@ namespace vkcv::rtx {
             "main" // const char* pName_ = {},
         );
         
-        std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = {   // HARD CODED
+        std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = {   // HARD CODED. TODO: Support more shader stages.
             rayGenShaderStageInfo, rayMissShaderStageInfo, rayClosestHitShaderStageInfo
         };
 
         // -- PipelineLayouts
 
-        std::vector<vk::RayTracingShaderGroupCreateInfoKHR> shaderGroups(3);   // HARD CODED
+        std::vector<vk::RayTracingShaderGroupCreateInfoKHR> shaderGroups(shaderStages.size());
         // Ray Gen
         shaderGroups[0] = vk::RayTracingShaderGroupCreateInfoKHR(
             vk::RayTracingShaderGroupTypeKHR::eGeneral, // vk::RayTracingShaderGroupTypeKHR type_ = vk::RayTracingShaderGroupTypeKHR::eGeneral
@@ -283,9 +281,9 @@ namespace vkcv::rtx {
         return m_pipeline;
     }
 
-    vk::Buffer RTXModule::getShaderBindingBuffer()
+    vk::Buffer RTXModule::getShaderBindingTableBuffer()
     {
-        return m_shaderBindingtableBuffer.vulkanHandle;
+        return m_shaderBindingTableBuffer.vulkanHandle;
     }
 
     vk::DeviceSize RTXModule::getShaderGroupBaseAlignment()
diff --git a/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp b/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp
index 0afd3f4e1581599df83a179025c250dc00dda54a..59a248ac552c5aaa22a3725a69a6dd0f47a2778f 100644
--- a/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp
+++ b/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp
@@ -26,7 +26,7 @@ RTXExtensions::RTXExtensions()
         m_features.requireExtension(deviceExtension);
     }
 
-    /* FIXME : We must disable features that will be mentioned as "not supported" by the FeatureManager. If every unsupported feature is disabled, this should work.
+    /* FIXME: We must disable features that will be mentioned as "not supported" by the FeatureManager. If every unsupported feature is disabled, this should work.
      * Maybe we find a better workaround...
      */
     m_features.requireFeature<vk::PhysicalDeviceVulkan12Features>(
diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp
index 37261c301510781719b13de70f53861f04edf1cd..cd02004f56ea3dfddcd20618b7859a0699d92d71 100644
--- a/modules/scene/src/vkcv/scene/Scene.cpp
+++ b/modules/scene/src/vkcv/scene/Scene.cpp
@@ -132,7 +132,7 @@ namespace vkcv::scene {
 			node.recordDrawcalls(viewProjection, pushConstants, drawcalls, record);
 		}
 		
-		//vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count);
+		vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count);
 		
 		m_core->recordDrawcallsToCmdStream(
 				cmdStream,
diff --git a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
index 28e92aa1b9795be10d01772471cf7e6cd386f832..c639118f5a4482eb9db2cee46057e5662b472181 100644
--- a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
+++ b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
@@ -56,17 +56,17 @@ namespace vkcv::shader {
 				return EShLangTaskNV;
 			case ShaderStage::MESH:
 				return EShLangMeshNV;
-			case ShaderStage::RAY_GEN:
+			case ShaderStage::RAY_GEN: // for RTX
 			    return EShLangRayGen;
-			case ShaderStage::RAY_CLOSEST_HIT:
+			case ShaderStage::RAY_CLOSEST_HIT: // for RTX
 			    return EShLangClosestHit;
-			case ShaderStage::RAY_MISS:
+			case ShaderStage::RAY_MISS: // for RTX
 			    return EShLangMiss;
-			case ShaderStage::RAY_INTERSECTION:
+			case ShaderStage::RAY_INTERSECTION: // for RTX
 				return EShLangIntersect;
-			case ShaderStage::RAY_ANY_HIT:
+			case ShaderStage::RAY_ANY_HIT: // for RTX
 				return EShLangAnyHit;
-			case ShaderStage::RAY_CALLABLE:
+			case ShaderStage::RAY_CALLABLE: // for RTX
 				return EShLangCallable;
 			default:
 				return EShLangCount;
@@ -227,7 +227,7 @@ namespace vkcv::shader {
 		
 		glslang::TShader shader (language);
 
-		//configure environment for rt shaders
+		// configure environment for rtx shaders by adjusting versions of Vulkan and SPIR-V, else rtx shader cannot be compiled.
 		if((shaderStage == ShaderStage::RAY_GEN) || (shaderStage == ShaderStage::RAY_ANY_HIT)
 		|| (shaderStage == ShaderStage::RAY_CLOSEST_HIT) || (shaderStage == ShaderStage::RAY_MISS)
 		|| (shaderStage == ShaderStage::RAY_INTERSECTION) || (shaderStage == ShaderStage::RAY_CALLABLE)){
diff --git a/projects/rtx/resources/shaders/ambientOcclusion.rchit b/projects/rtx/resources/shaders/ambientOcclusion.rchit
index 55bd6531e9452065a3ff041361cc3c92d5160319..b073916e4eaf992d5e6ae4186013478634263fbd 100644
--- a/projects/rtx/resources/shaders/ambientOcclusion.rchit
+++ b/projects/rtx/resources/shaders/ambientOcclusion.rchit
@@ -10,7 +10,7 @@ layout(location = 0) rayPayloadInEXT Payload {
   vec3 worldNormal;
 } payload;
 
-layout(binding = 2, set = 0) uniform accelerationStructureEXT tlas;     // top level acceleration structure (for the noobs here (you!))
+layout(binding = 2, set = 0) uniform accelerationStructureEXT tlas;     // top level acceleration structure
 
 layout(binding = 3, set = 0, scalar) buffer rtxVertices
 {
diff --git a/projects/rtx/resources/shaders/ambientOcclusion.rgen b/projects/rtx/resources/shaders/ambientOcclusion.rgen
index 7790ef167394058f1ecf0f719a8b40cbf0b6388e..ca74919da8e4b8f49d34f1861c0923c8af03f47f 100644
--- a/projects/rtx/resources/shaders/ambientOcclusion.rgen
+++ b/projects/rtx/resources/shaders/ambientOcclusion.rgen
@@ -3,6 +3,8 @@
 
 #define M_PI 3.1415926535897932384626433832795
 
+// TODO: credits!!!
+
 // A location for a ray payload (we can have multiple of these)
 layout(location = 0) rayPayloadEXT Payload {
   float hitSky;
@@ -10,32 +12,36 @@ layout(location = 0) rayPayloadEXT Payload {
   vec3 worldNormal;
 } payload;
 
-layout(binding = 0, set = 0, rgba16) uniform image2D outImg;           // the output image -> maybe use 16 bit values?
-layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas;     // top level acceleration structure (for the noobs here (you!))
+layout(binding = 0, set = 0, rgba16) uniform image2D outImg;            // the output image -> maybe use 16 bit values?
+layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas;     // top level acceleration structure
 
 layout( push_constant ) uniform constants {
     vec4 camera_position;   // as origin for ray generation
     vec4 camera_right;      // for computing ray direction
     vec4 camera_up;         // for computing ray direction
     vec4 camera_forward;    // for computing ray direction
+} camera;
 
-    uint frameCount;        // resets when camera moves, otherwise frameCount++
-}camera;
+uint rngState = gl_LaunchIDEXT.x * 2000 + gl_LaunchIDEXT.y;     // each shader call has its own rngState
 
 float random(vec2 uv, float seed) {
   return fract(sin(mod(dot(uv, vec2(12.9898, 78.233)) + 1113.1 * seed, M_PI)) * 43758.5453);;
 }
 
+/**
+ * Retrieves pixel information.
+ * @param[in,out] hitSky Defines if the ray has hit the sky
+ * @param[in,out] pos The position of intersection
+ * @param[in,out] norm The normal at the position of intersection
+ */
 void GetPixelInfo(out bool hitSky, out vec3 pos, out vec3 norm){
   // Use a camera model to generate a ray for this pixel.
-  //const vec2 pixelCenter       = vec2(gl_LaunchIDEXT.xy) + 0.5;
-  //const uvec2 resolution       = gl_LaunchSizeEXT.xy;
   vec2 uv = gl_LaunchIDEXT.xy + vec2(random(gl_LaunchIDEXT.xy, 0), random(gl_LaunchIDEXT.xy, 1));
   uv /= vec2(gl_LaunchSizeEXT.xy);
-  uv = vec2(1.0, -1.0) * (uv * 2.0 - 1.0);
-  //const float fovVerticalSlope = 1.0 / 5.0;
+  uv = (uv * 2.0 - 1.0) // normalize uv coordinates into Vulkan viewport space
+    * vec2(1.0, -1.0);  // flips y-axis
   const vec3 orig              = camera.camera_position.xyz;
-  const vec3 dir               = normalize((-1) * uv.x * camera.camera_right + uv.y * camera.camera_up + camera.camera_forward).xyz;
+  const vec3 dir               = normalize(uv.x * camera.camera_right + uv.y * camera.camera_up + camera.camera_forward).xyz;
 
   // Trace a ray into the scene; get back data in the payload.
   traceRayEXT(tlas,  // Acceleration structure
@@ -56,6 +62,11 @@ void GetPixelInfo(out bool hitSky, out vec3 pos, out vec3 norm){
   norm = payload.worldNormal;
 }
 
+/**
+ * @brief Casts a shadow ray. Returns @p true, if the shadow ray hit the sky.
+ * @param[in] orig The point of origin of the shadow ray.
+ * @param[in] dir The direction of the shadow ray.
+ */
 float ShadowRay(vec3 orig, vec3 dir){
   payload.hitSky = 0.0f;  // Assume ray is occluded
   traceRayEXT(tlas,   // Acceleration structure
@@ -72,6 +83,11 @@ float ShadowRay(vec3 orig, vec3 dir){
   return payload.hitSky;
 }
 
+/**
+ * @brief Computes the offset position at @p worldPosition and its @p normal to avoid self-intersection.
+ * @param[in] worldPosition The point of intersection.
+ * @param[in] normal The normal at the point of intersection.
+ */
 vec3 OffsetPositionAlongNormal(vec3 worldPosition, vec3 normal){
   // Convert the normal to an integer offset.
   const float int_scale = 256.0f;
@@ -93,8 +109,9 @@ vec3 OffsetPositionAlongNormal(vec3 worldPosition, vec3 normal){
       abs(worldPosition.z) < origin ? worldPosition.z + floatScale * normal.z : p_i.z);
 }
 
-uint rngState = gl_LaunchIDEXT.x * 2000 + gl_LaunchIDEXT.y;
-
+/**
+ * @brief Used for creating random float numbers.
+ */
 float StepAndOutputRNGFloat(){
   // Condensed version of pcg_output_rxs_m_xs_32_32, with simple conversion to floating-point [0,1].
   rngState  = rngState * 747796405 + 1;
@@ -103,21 +120,25 @@ float StepAndOutputRNGFloat(){
   return float(word) / 4294967295.0f;
 }
 
-// Gets a randomly chosen cosine-weighted direction within the unit hemisphere
-// defined by the surface normal.
+
+/**
+ * @brief Gets a randomly chosen cosine-weighted direction within the unit hemisphere defined by @p norm.
+ * @param[in] norm The surface normal.
+ */
 vec3 GetRandCosDir(vec3 norm){
   // To generate a cosine-weighted normal, generate a random point on a sphere:
   float theta      = 6.2831853 * StepAndOutputRNGFloat();  // Random in [0, 2pi]
   float z          = 2 * StepAndOutputRNGFloat() - 1.0;    // Random in [-1, 1]
   float r          = sqrt(1.0 - z * z);
   vec3  ptOnSphere = vec3(r * cos(theta), r * sin(theta), z);
-  // Then add the normal to it and normalize to make it cosine-weighted on a
-  // hemisphere:
+  // Then add the normal to it and normalize to make it cosine-weighted on a hemisphere:
   return normalize(ptOnSphere + norm);
 }
 
 
 void main(){
+     uint rays = 64;    // the amount of rays to be casted
+
      uvec2 pixel = gl_LaunchIDEXT.xy;
      bool pixelIsSky; // Does the pixel show the sky (not an object)?
      vec3 pos, norm;  // AO rays from where?
@@ -131,20 +152,9 @@ void main(){
       // Compute ambient occlusion
      pos = OffsetPositionAlongNormal(pos, norm); // Avoid self-intersection
      float aoColor = 0.0;
-     for(uint i = 0; i < 64; i++){  // Use 64 rays.
-        aoColor += ShadowRay(pos, GetRandCosDir(norm)) / 64.0;
+     for(uint i = 0; i < rays; i++){
+        aoColor += ShadowRay(pos, GetRandCosDir(norm)) / rays;
      }
      vec4 aoColorVec = vec4(aoColor);
-     if (camera.frameCount > 0) {
-         vec4 previousColor = imageLoad(outImg, ivec2(gl_LaunchIDEXT.xy));
-         previousColor *= camera.frameCount;
-
-         aoColorVec += previousColor;
-         aoColorVec /= (camera.frameCount + 1);
-     }
      imageStore(outImg, ivec2(pixel), aoColorVec);
-
-    //color=vec4(0.0001*camera.frameCount,0,0,1);//DEBUG
-    //color=vec4(1,0,0,1);//DEBUG
-    //imageStore(outImg, ivec2(gl_LaunchIDEXT.xy), color);
 }
diff --git a/projects/rtx/src/main.cpp b/projects/rtx/src/main.cpp
index dccf6154064aaa86fdc44438dc5e82b6406f1894..99304c072995fd1b768b9f1a4d19cc740ba4432a 100644
--- a/projects/rtx/src/main.cpp
+++ b/projects/rtx/src/main.cpp
@@ -38,18 +38,13 @@ int main(int argc, const char** argv) {
 	vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, false);
 
 	vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle));
-	uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
-	uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
-	
-	cameraManager.getCamera(camIndex0).setPosition(glm::vec3(-8, 1, -0.5));
-	cameraManager.getCamera(camIndex0).setNearFar(0.1f, 30.0f);
-	
-	cameraManager.getCamera(camIndex1).setNearFar(0.1f, 30.0f);
+	uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+	cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f);
 	
     // get Teapot vertices and indices
-	std::vector<float> vertices;
-    std::vector<uint32_t> indices;
-    Teapot teapot(vertices,indices);
+    Teapot teapot;
+    std::vector<float> vertices = teapot.getVertices();
+    std::vector<uint32_t> indices = teapot.getIndices();
 
 	vkcv::shader::GLSLCompiler compiler;
 
@@ -85,12 +80,11 @@ int main(int argc, const char** argv) {
 	    glm::vec4 camera_right;      // for computing ray direction
 	    glm::vec4 camera_up;         // for computing ray direction
 	    glm::vec4 camera_forward;    // for computing ray direction
-	    glm::uint frameCount;        // resets when camera moves, otherwise frameCount++
 	};
 
 	uint32_t pushConstantSize = sizeof(RaytracingPushConstantData);
 
-	rtxModule.createRTXPipeline(pushConstantSize, descriptorSetLayoutHandles, rtxShaderProgram);
+    rtxModule.createRTXPipelineAndLayout(pushConstantSize, descriptorSetLayoutHandles, rtxShaderProgram);
 
 	vk::Pipeline rtxPipeline = rtxModule.getPipeline();
 	vk::PipelineLayout rtxPipelineLayout = rtxModule.getPipelineLayout();
@@ -102,11 +96,8 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorWrites rtxWrites;
 
 	auto start = std::chrono::system_clock::now();
-	uint32_t frameCount = 0;
 	while (vkcv::Window::hasOpenWindow()) {
         vkcv::Window::pollEvents();
-        glm::vec4 camMove1;
-        glm::vec4 camMove2;
 
 		if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0)
 			continue;
@@ -133,21 +124,10 @@ int main(int argc, const char** argv) {
 		
 		RaytracingPushConstantData raytracingPushData;
 		raytracingPushData.camera_position = glm::vec4(cameraManager.getActiveCamera().getPosition(),0);
-		raytracingPushData.camera_right = glm::vec4(glm::cross(cameraManager.getActiveCamera().getFront(), cameraManager.getActiveCamera().getUp()), 0);
+		raytracingPushData.camera_right = glm::vec4(glm::cross(cameraManager.getActiveCamera().getUp(), cameraManager.getActiveCamera().getFront()), 0);
 		raytracingPushData.camera_up = glm::vec4(cameraManager.getActiveCamera().getUp(),0);
 		raytracingPushData.camera_forward = glm::vec4(cameraManager.getActiveCamera().getFront(),0);
 
-        // reset frameCount if camera movement is detected
-        if (camMove1 != glm::vec4(cameraManager.getActiveCamera().getFront(),0)
-            || camMove2 != glm::vec4(cameraManager.getActiveCamera().getPosition(),0)){
-            raytracingPushData.frameCount = 0;
-            frameCount = 0;
-        } else {
-            raytracingPushData.frameCount = frameCount++;
-        }
-        camMove1 = glm::vec4(cameraManager.getActiveCamera().getFront(),0);
-        camMove2 = glm::vec4(cameraManager.getActiveCamera().getPosition(),0);
-
 		vkcv::PushConstants pushConstantsRTX(sizeof(RaytracingPushConstantData));
 		pushConstantsRTX.appendDrawcall(raytracingPushData);
 
@@ -162,7 +142,7 @@ int main(int argc, const char** argv) {
 			cmdStream,
 			rtxPipeline,
 			rtxPipelineLayout,
-			rtxModule.getShaderBindingBuffer(),
+            rtxModule.getShaderBindingTableBuffer(),
 			rtxModule.getShaderGroupBaseAlignment(),
 			{	vkcv::DescriptorSetUsage(0, core.getDescriptorSet(rtxShaderDescriptorSet).vulkanHandle)},
 			pushConstantsRTX,
diff --git a/projects/rtx/src/teapot.hpp b/projects/rtx/src/teapot.hpp
index 6225c25df7d2b9c3af4aaa81949169a5101b61b0..1f35400a313b230f92098fa2ef59cc3c8f3a30df 100644
--- a/projects/rtx/src/teapot.hpp
+++ b/projects/rtx/src/teapot.hpp
@@ -4,27 +4,34 @@
 class Teapot {
 public:
     /**
-     * constructor fills given vectors @p vertices and @p indices with vertex data and index data respectively
-     * @param vertices
-     * @param indices
+     * @brief The default constructor.
      */
-    Teapot(std::vector<float> &vertices, std::vector<uint32_t> &indices) {
-        for (size_t i = 0; i < std::size(m_teapotVertices); i++) {
-            vertices.push_back(m_teapotVertices[i]);
-        }
-        for (size_t i = 0; i < std::size(m_teapotIndices); i++) {
-            indices.push_back(m_teapotIndices[i]);
-        }
-    };
+    Teapot() = default;
 
     /**
      * default destructor
      */
-    ~Teapot()=default;
+    ~Teapot() = default;
+
+    /**
+     * @brief Returns the vertex data of the teapot.
+     * @return The vertex data of the teapot.
+     */
+    std::vector<float> getVertices() {
+        return m_teapotVertices;
+    }
+
+    /**
+     * @brief Returns the index data of the teapot.
+     * @return The index data of the teapot.
+     */
+    std::vector<uint32_t> getIndices() {
+        return m_teapotIndices;
+    }
 
 private:
 
-    float m_teapotVertices[3872 * 3] =
+    std::vector<float> m_teapotVertices =
             {
                     0.69999999f, 0.45000005f, 0.00000001f,
                     0.69098389f, 0.44999996f, 0.11485600f,
@@ -3900,7 +3907,7 @@ private:
                     1.39999998f, 0.45000005f, 0.00000001f,
             };
 
-    uint32_t m_teapotIndices[19200] =
+    std::vector<uint32_t> m_teapotIndices =
             {
                     0, 1, 11, 11, 1, 12,
                     1, 2, 12, 12, 2, 13,
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index de960373fc7d1e2f0e05ff7bc91c07949d89980a..60ee35629dd54c16f40762861667de5054defc12 100644
--- a/src/vkcv/Context.cpp
+++ b/src/vkcv/Context.cpp
@@ -326,7 +326,6 @@ namespace vkcv
 				queuePairsTransfer
 		);
 
-        // TODO ?vma::AllocatorCreateFlagBits::eKhrDedicatedAllocation?
 		vma::AllocatorCreateFlags vmaFlags;
 		const vma::AllocatorCreateInfo allocatorCreateInfo (
 				vma::AllocatorCreateFlags(),
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index d2082bd46d5009a8294a110c89ca5f5758e37a4b..7b097c018862f3d8669b3104149208b7721b15e2 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -436,14 +436,17 @@ namespace vkcv
 					pushConstants.getSizePerDrawcall(),
 					pushConstants.getData());
 			}
+			// Define offsets for the RTX shaders. RayGen is the first allocated shader. Each following shader is
+			// shifted by shaderGroupBaseAlignment.
 			vk::DeviceSize rayGenOffset = 0;
 			vk::DeviceSize missOffset = shaderGroupBaseAlignment;
 			vk::DeviceSize closestHitOffset = 2 * shaderGroupBaseAlignment;
-			vk::DeviceSize shaderBindingTableSize = shaderGroupBaseAlignment * 3; //4 hardcoded to rtx-shader count
+			vk::DeviceSize shaderBindingTableSize = shaderGroupBaseAlignment * 3; // 3 hardcoded to rtx-shader count
 
 			auto m_rtxDispatcher = vk::DispatchLoaderDynamic((PFN_vkGetInstanceProcAddr)m_Context.getInstance().getProcAddr("vkGetInstanceProcAddr"));
 			m_rtxDispatcher.init(m_Context.getInstance());
 
+			// Create regions for the shader binding table buffer which are used for vk::CommandBuffer::traceRaysKHR
 			vk::StridedDeviceAddressRegionKHR rgenRegion;
 			vk::BufferDeviceAddressInfoKHR shaderBindingTableAddressInfo(shaderBindingTable);
 			rgenRegion.deviceAddress = m_Context.getDevice().getBufferAddressKHR(shaderBindingTableAddressInfo, m_rtxDispatcher) + rayGenOffset;
diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp
index 1b471d61b1cb57aefeb9d3edfd0874ffb2ad5663..69a35685098509afcbfd49210b2b09b454e9bbb9 100644
--- a/src/vkcv/DescriptorManager.cpp
+++ b/src/vkcv/DescriptorManager.cpp
@@ -15,8 +15,8 @@ namespace vkcv
 				vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1000),
 				vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 1000),
 				vk::DescriptorPoolSize(vk::DescriptorType::eUniformBufferDynamic, 1000),
-				vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000),
-				vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000)
+				vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000),    // for RTX
+				vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000) // for RTX
 		};
 
 		m_PoolInfo = vk::DescriptorPoolCreateInfo(
diff --git a/src/vkcv/FeatureManager.cpp b/src/vkcv/FeatureManager.cpp
index 2800058ed3fe11ce8a6fcf807241ac5e6220880a..2dd5585d0f3b01c9741e8e52da6a7b45b24d37e5 100644
--- a/src/vkcv/FeatureManager.cpp
+++ b/src/vkcv/FeatureManager.cpp
@@ -362,8 +362,6 @@ m_physicalDevice.getFeatures2(&query)
 	    vkcv_check_feature(variablePointers);
 	    vkcv_check_feature(variablePointersStorageBuffer);
 
-	    // TODO: (Validation Error) if using VulkanFeatures11, disable VkPhysicalDevice16BitStorageFeatures
-
 	    return true;
 	}
 
diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp
index 65e4cab5c75db17ecc91b36313880c3c0126da06..4d2165aa22eb5f53dcc3067273721543edd309e4 100644
--- a/src/vkcv/ShaderProgram.cpp
+++ b/src/vkcv/ShaderProgram.cpp
@@ -254,6 +254,7 @@ namespace vkcv {
             }
         }
 
+        // Used to reflect acceleration structure bindings for RTX.
         for (uint32_t i = 0; i < resources.acceleration_structures.size(); i++) {
             auto& u = resources.acceleration_structures[i];
             const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id);