diff --git a/config/Sources.cmake b/config/Sources.cmake
index 0b111a15f1bbbc0a7d3bd8b3899b4c72abc386db..d714857cf87db179e504054c52ae5583797b017a 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -124,7 +124,10 @@ set(vkcv_sources
 		${vkcv_include}/vkcv/BlitDownsampler.hpp
 		${vkcv_source}/vkcv/BlitDownsampler.cpp
 		
+		${vkcv_include}/vkcv/SamplerTypes.hpp
+		
 		${vkcv_include}/vkcv/Sampler.hpp
+		${vkcv_source}/vkcv/Sampler.cpp
 		
 		${vkcv_include}/vkcv/Result.hpp
 )
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 73939037466796c79e41e66ef62c14944855871c..835248659a9eb71fec20b4079ca506f04257b4ce 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -18,7 +18,7 @@
 #include "GraphicsPipelineConfig.hpp"
 #include "ComputePipelineConfig.hpp"
 #include "Result.hpp"
-#include "Sampler.hpp"
+#include "SamplerTypes.hpp"
 #include "DescriptorWrites.hpp"
 #include "Event.hpp"
 #include "DrawcallRecording.hpp"
diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp
index 8b738b07c6302629d42978dc1f585383366ea52a..542658ae6aeb56b5221ca5f97504e955eaf0e478 100644
--- a/include/vkcv/Image.hpp
+++ b/include/vkcv/Image.hpp
@@ -15,7 +15,6 @@
 namespace vkcv {
 	
 	class Downsampler;
-	class ImageManager;
 
 	/**
 	 * @brief Returns whether an image format is usable as depth buffer.
diff --git a/include/vkcv/Sampler.hpp b/include/vkcv/Sampler.hpp
index c65ef8218ff209e6eeaf0e45f9309e21d85e782e..601370c71bfaa3a8eaad023cae532b083d78fa90 100644
--- a/include/vkcv/Sampler.hpp
+++ b/include/vkcv/Sampler.hpp
@@ -2,50 +2,21 @@
 /**
  * @authors Tobias Frisch
  * @file vkcv/Sampler.hpp
- * @brief Enums for different sampler attributes.
+ * @brief Support functions for basic sampler creation.
  */
 
-namespace vkcv {
-
-    /**
-     * @brief Enum class to specify a samplers type to filter during access.
-     */
-	enum class SamplerFilterType {
-		NEAREST = 1,
-		LINEAR = 2
-	};
-
-    /**
-     * @brief Enum class to specify a samplers mode to access mipmaps.
-     */
-	enum class SamplerMipmapMode {
-		NEAREST = 1,
-		LINEAR = 2
-	};
+#include "Core.hpp"
+#include "SamplerTypes.hpp"
+#include "Handles.hpp"
 
-    /**
-     * @brief Enum class to specify a samplers mode to access via address space.
-     */
-	enum class SamplerAddressMode {
-		REPEAT = 1,
-		MIRRORED_REPEAT = 2,
-		CLAMP_TO_EDGE = 3,
-		MIRROR_CLAMP_TO_EDGE = 4,
-		CLAMP_TO_BORDER = 5
-	};
-
-    /**
-     * @brief Enum class to specify a samplers color beyond a textures border.
-     */
-	enum class SamplerBorderColor {
-		INT_ZERO_OPAQUE = 1,
-		INT_ZERO_TRANSPARENT = 2,
-		
-		FLOAT_ZERO_OPAQUE = 3,
-		FLOAT_ZERO_TRANSPARENT = 4,
-		
-		INT_ONE_OPAQUE = 5,
-		FLOAT_ONE_OPAQUE = 6
-	};
+namespace vkcv {
+	
+	[[nodiscard]]
+	SamplerHandle samplerLinear(Core &core,
+								bool clampToEdge = false);
+	
+	[[nodiscard]]
+	SamplerHandle samplerNearest(Core &core,
+								 bool clampToEdge = false);
 
 }
diff --git a/include/vkcv/SamplerTypes.hpp b/include/vkcv/SamplerTypes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4dc68930050ff955a251f701657462a8b5ebbb1f
--- /dev/null
+++ b/include/vkcv/SamplerTypes.hpp
@@ -0,0 +1,51 @@
+#pragma once
+/**
+ * @authors Tobias Frisch
+ * @file vkcv/SamplerTypes.hpp
+ * @brief Enums for different sampler attributes.
+ */
+
+namespace vkcv {
+	
+	/**
+     * @brief Enum class to specify a samplers type to filter during access.
+     */
+	enum class SamplerFilterType {
+		NEAREST = 1,
+		LINEAR = 2
+	};
+	
+	/**
+	 * @brief Enum class to specify a samplers mode to access mipmaps.
+	 */
+	enum class SamplerMipmapMode {
+		NEAREST = 1,
+		LINEAR = 2
+	};
+	
+	/**
+	 * @brief Enum class to specify a samplers mode to access via address space.
+	 */
+	enum class SamplerAddressMode {
+		REPEAT = 1,
+		MIRRORED_REPEAT = 2,
+		CLAMP_TO_EDGE = 3,
+		MIRROR_CLAMP_TO_EDGE = 4,
+		CLAMP_TO_BORDER = 5
+	};
+	
+	/**
+	 * @brief Enum class to specify a samplers color beyond a textures border.
+	 */
+	enum class SamplerBorderColor {
+		INT_ZERO_OPAQUE = 1,
+		INT_ZERO_TRANSPARENT = 2,
+		
+		FLOAT_ZERO_OPAQUE = 3,
+		FLOAT_ZERO_TRANSPARENT = 4,
+		
+		INT_ONE_OPAQUE = 5,
+		FLOAT_ONE_OPAQUE = 6
+	};
+	
+}
diff --git a/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp b/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp
index fbfa20fb743fee689586b1e24034dbc4334c51a7..07987c13654ac0e96d5b47c3f45a82be84b5fbd7 100644
--- a/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp
+++ b/modules/effects/src/vkcv/effects/BloomAndFlaresEffect.cpp
@@ -4,6 +4,7 @@
 #include <vkcv/DrawcallRecording.hpp>
 #include <vkcv/PushConstants.hpp>
 #include <vkcv/Image.hpp>
+#include <vkcv/Sampler.hpp>
 
 #include <vkcv/shader/GLSLCompiler.hpp>
 #include <vkcv/asset/asset_loader.hpp>
@@ -190,12 +191,7 @@ namespace vkcv::effects {
 	m_blurImage(),
 	m_flaresImage(),
 	
-	m_linearSampler(m_core.createSampler(
-			vkcv::SamplerFilterType::LINEAR,
-			vkcv::SamplerFilterType::LINEAR,
-			vkcv::SamplerMipmapMode::LINEAR,
-			vkcv::SamplerAddressMode::CLAMP_TO_EDGE
-	)),
+	m_linearSampler(samplerLinear(m_core, true)),
 	
 	m_radialLutSampler(),
 	
@@ -238,13 +234,7 @@ namespace vkcv::effects {
 		);
 		
 		if (m_advanced) {
-			m_radialLutSampler = m_core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
-			
+			m_radialLutSampler = samplerLinear(m_core);
 			m_radialLut = loadTexture(m_core, "assets/RadialLUT.png");
 			m_lensDirt = loadTexture(m_core, "assets/lensDirt.jpg");
 		}
diff --git a/modules/material/src/vkcv/material/Material.cpp b/modules/material/src/vkcv/material/Material.cpp
index 6ee280a0796de1c9a83c19a84272fccc54181f63..8187b5de9205ba18ca32cd23dba9d5b457696712 100644
--- a/modules/material/src/vkcv/material/Material.cpp
+++ b/modules/material/src/vkcv/material/Material.cpp
@@ -1,7 +1,8 @@
 
 #include "vkcv/material/Material.hpp"
 
-#include "vkcv/Image.hpp"
+#include <vkcv/Image.hpp>
+#include <vkcv/Sampler.hpp>
 
 namespace vkcv::material {
 	
@@ -149,48 +150,23 @@ namespace vkcv::material {
 		}
 		
 		if (!colorSmp) {
-			samplers[0] = core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
+			samplers[0] = samplerLinear(core);
 		}
 		
 		if (!normalSmp) {
-			samplers[1] = core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
+			samplers[1] = samplerLinear(core);
 		}
 		
 		if (!metRoughSmp) {
-			samplers[2] = core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
+			samplers[2] = samplerLinear(core);
 		}
 		
 		if (!occlusionSmp) {
-			samplers[3] = core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
+			samplers[3] = samplerLinear(core);
 		}
 		
 		if (!emissiveSmp) {
-			samplers[4] = core.createSampler(
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerFilterType::LINEAR,
-					vkcv::SamplerMipmapMode::LINEAR,
-					vkcv::SamplerAddressMode::REPEAT
-			);
+			samplers[4] = samplerLinear(core);
 		}
 		
 		Material material;
diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp
index f702aa34d46dd942ac864c812328a79c72d3df65..6ecfe34aace42f1233f77b9b70a05885445cda30 100644
--- a/modules/scene/src/vkcv/scene/Scene.cpp
+++ b/modules/scene/src/vkcv/scene/Scene.cpp
@@ -3,6 +3,7 @@
 
 #include <vkcv/Image.hpp>
 #include <vkcv/Logger.hpp>
+#include <vkcv/Sampler.hpp>
 #include <vkcv/asset/asset_loader.hpp>
 
 #include <vkcv/algorithm/SinglePassDownsampler.hpp>
@@ -236,7 +237,6 @@ namespace vkcv::scene {
 				minFilter,
 				mipmapMode,
 				addressMode,
-				
 				mipLodBias
 		);
 	}
@@ -338,12 +338,7 @@ namespace vkcv::scene {
 			scene.getNode(root).loadMesh(asset_scene, mesh);
 		}
 		
-		vkcv::SamplerHandle sampler = core.createSampler(
-				vkcv::SamplerFilterType::LINEAR,
-				vkcv::SamplerFilterType::LINEAR,
-				vkcv::SamplerMipmapMode::LINEAR,
-				vkcv::SamplerAddressMode::REPEAT
-		);
+		vkcv::SamplerHandle sampler = samplerLinear(core);
 		
 		const vkcv::FeatureManager& featureManager = core.getContext().getFeatureManager();
 		
diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp
index 43247f69e4fd379143bd97bf954fa51e12ef55d6..c4e18699b4f93f5f35742d9d3aaff180a511152e 100644
--- a/projects/bindless_textures/src/main.cpp
+++ b/projects/bindless_textures/src/main.cpp
@@ -3,6 +3,7 @@
 #include <vkcv/Core.hpp>
 #include <vkcv/Image.hpp>
 #include <vkcv/Pass.hpp>
+#include <vkcv/Sampler.hpp>
 #include <GLFW/glfw3.h>
 #include <vkcv/camera/CameraManager.hpp>
 #include <chrono>
@@ -180,17 +181,13 @@ int main(int argc, const char** argv) {
 	
 	core.submitCommandStream(downsampleStream, false);
 
-	vkcv::SamplerHandle sampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::REPEAT
-	);
+	vkcv::SamplerHandle sampler = vkcv::samplerLinear(core);
 
 	const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
 		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()),
 		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()),
-		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) };
+		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle())
+	};
 
 	vkcv::DescriptorWrites setWrites;
 	
diff --git a/projects/fire_works/src/main.cpp b/projects/fire_works/src/main.cpp
index 91c044e6984f1de5cbd56d47c3cca26dcc7f811c..ffef4cd4cfe11c0d0d84d2c9a8a960985fb58b22 100644
--- a/projects/fire_works/src/main.cpp
+++ b/projects/fire_works/src/main.cpp
@@ -5,6 +5,7 @@
 #include <vkcv/Core.hpp>
 #include <vkcv/Image.hpp>
 #include <vkcv/Pass.hpp>
+#include <vkcv/Sampler.hpp>
 #include <vkcv/DrawcallRecording.hpp>
 
 #include <vkcv/camera/CameraManager.hpp>
@@ -786,12 +787,7 @@ int main(int argc, const char **argv) {
 			1, false, true
    	);
 	
-	vkcv::SamplerHandle voxelSampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::CLAMP_TO_EDGE
-	);
+	vkcv::SamplerHandle voxelSampler = vkcv::samplerLinear(core, true);
 	
 	vkcv::ShaderProgram voxelClearShader;
 	compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/clear.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index db985425b3f12b6225ce85c7905be73f9493765f..489fe0ade1f46d85ba4c77110b1d9644c2f46014 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -3,6 +3,7 @@
 #include <vkcv/Core.hpp>
 #include <vkcv/Image.hpp>
 #include <vkcv/Pass.hpp>
+#include <vkcv/Sampler.hpp>
 #include <vkcv/camera/CameraManager.hpp>
 #include <vkcv/asset/asset_loader.hpp>
 #include <vkcv/shader/GLSLCompiler.hpp>
@@ -123,17 +124,13 @@ int main(int argc, const char** argv) {
 		core.submitCommandStream(cmdStream, false);
 	}
 
-	vkcv::SamplerHandle sampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::REPEAT
-	);
+	vkcv::SamplerHandle sampler = vkcv::samplerLinear(core);
 
 	const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
 		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()),
 		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()),
-		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) };
+		vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle())
+	};
 
 	vkcv::DescriptorWrites setWrites;
 	setWrites.writeSampledImage(0, texture.getHandle());
diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp
index 44eb74f8ca22e6358c2d9e673d3e415a42316058..ef5afaf117a7e9212114f9ef7b431fac308fb630 100644
--- a/projects/indirect_dispatch/src/App.cpp
+++ b/projects/indirect_dispatch/src/App.cpp
@@ -1,7 +1,10 @@
 #include "App.hpp"
 #include "AppConfig.hpp"
-#include <chrono>
+
+#include <vkcv/Sampler.hpp>
 #include <vkcv/gui/GUI.hpp>
+
+#include <chrono>
 #include <functional>
 
 const char* MotionVectorVisualisationModeLabels[6] = {
@@ -60,12 +63,7 @@ bool App::initialize() {
 	if (!m_motionBlur.initialize(&m_core, m_windowWidth, m_windowHeight))
 		return false;
 
-	m_linearSampler = m_core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::CLAMP_TO_EDGE);
-
+	m_linearSampler = vkcv::samplerLinear(m_core, true);
 	m_renderTargets = createRenderTargets(m_core, m_windowWidth, m_windowHeight);
 
 	const int cameraIndex = m_cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp
index adffd1ea987834142b4eeea1de9c04d6bb1137dd..d90171deac32d03b0da31b169f9592c4464adca6 100644
--- a/projects/indirect_dispatch/src/MotionBlur.cpp
+++ b/projects/indirect_dispatch/src/MotionBlur.cpp
@@ -1,8 +1,11 @@
 #include "MotionBlur.hpp"
 #include "MotionBlurConfig.hpp"
 #include "MotionBlurSetup.hpp"
-#include <array>
+
 #include <vkcv/Buffer.hpp>
+#include <vkcv/Sampler.hpp>
+
+#include <array>
 
 bool MotionBlur::initialize(vkcv::Core* corePtr, const uint32_t targetWidth, const uint32_t targetHeight) {
 
@@ -76,11 +79,7 @@ bool MotionBlur::initialize(vkcv::Core* corePtr, const uint32_t targetWidth, con
 
 	m_renderTargets = MotionBlurSetup::createRenderTargets(targetWidth, targetHeight, *m_core);
 
-	m_nearestSampler = m_core->createSampler(
-		vkcv::SamplerFilterType::NEAREST,
-		vkcv::SamplerFilterType::NEAREST,
-		vkcv::SamplerMipmapMode::NEAREST,
-		vkcv::SamplerAddressMode::CLAMP_TO_EDGE);
+	m_nearestSampler = vkcv::samplerNearest(*m_core, true);
 	
 	return true;
 }
diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp
index d975d0c1042b5d8fd4714dbc18ded049703f3d59..2f1f08455190986fcd7abdf2bc15b27a116f8a29 100644
--- a/projects/indirect_draw/src/main.cpp
+++ b/projects/indirect_draw/src/main.cpp
@@ -2,9 +2,9 @@
 #include <vkcv/Buffer.hpp>
 #include <vkcv/Core.hpp>
 #include <vkcv/Pass.hpp>
+#include <vkcv/Sampler.hpp>
 #include <vkcv/Image.hpp>
 #include <vkcv/camera/CameraManager.hpp>
-#include <chrono>
 #include <vkcv/gui/GUI.hpp>
 #include <vkcv/asset/asset_loader.hpp>
 #include <vkcv/shader/GLSLCompiler.hpp>
@@ -444,12 +444,7 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings);
 	vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout);
 
-    vkcv::SamplerHandle standardSampler = core.createSampler(
-            vkcv::SamplerFilterType::LINEAR,
-            vkcv::SamplerFilterType::LINEAR,
-            vkcv::SamplerMipmapMode::LINEAR,
-            vkcv::SamplerAddressMode::REPEAT
-    );
+    vkcv::SamplerHandle standardSampler = vkcv::samplerLinear(core);
 	
 	vkcv::DescriptorWrites setWrites;
 	
diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp
index 16149c1b5730351bc3a2d0051dac751d3777c7cf..2ddbd0cfb37f17835b2939f28f9b75693ebb4128 100644
--- a/projects/saf_r/src/main.cpp
+++ b/projects/saf_r/src/main.cpp
@@ -2,14 +2,17 @@
 #include <vkcv/Core.hpp>
 #include <vkcv/Buffer.hpp>
 #include <vkcv/Pass.hpp>
-#include <GLFW/glfw3.h>
+#include <vkcv/Sampler.hpp>
+
 #include <vkcv/camera/CameraManager.hpp>
 #include <vkcv/asset/asset_loader.hpp>
 #include <vkcv/shader/GLSLCompiler.hpp>
-#include <chrono>
+
 #include <cmath>
 #include <vector>
 #include <cstring>
+#include <GLFW/glfw3.h>
+
 #include "safrScene.hpp"
 
 void createQuadraticLightCluster(std::vector<safrScene::Light>& lights, int countPerDimension, float dimension, float height, float intensity) {
@@ -114,12 +117,7 @@ int main(int argc, const char** argv) {
     */
     createQuadraticLightCluster(lights, 10, 2.5f, 20, 1.5f);
 	
-	vkcv::SamplerHandle sampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::REPEAT
-	);
+	vkcv::SamplerHandle sampler = vkcv::samplerLinear(core);
 	
 	//create Buffer for compute shader
 	vkcv::Buffer<safrScene::Light> lightsBuffer = vkcv::buffer<safrScene::Light>(
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index 139f22fe1a77018a7e09fce54ac90ae2a18bb36b..862ac3c2dd37ddbabb282c5299976635eb652d18 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -1,6 +1,7 @@
 #include <iostream>
 #include <vkcv/Core.hpp>
 #include <vkcv/Pass.hpp>
+#include <vkcv/Sampler.hpp>
 #include <GLFW/glfw3.h>
 #include <vkcv/camera/CameraManager.hpp>
 #include <chrono>
@@ -244,12 +245,7 @@ int main(int argc, const char** argv) {
 	vkcv::PassHandle prepassPass = vkcv::passFormat(core, depthBufferFormat, true, msaa);
 
 	// create descriptor sets
-	vkcv::SamplerHandle colorSampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::REPEAT
-	);
+	vkcv::SamplerHandle colorSampler = vkcv::samplerLinear(core);
 
 	std::vector<vkcv::DescriptorSetLayoutHandle> materialDescriptorSetLayouts;
 	std::vector<vkcv::DescriptorSetHandle> materialDescriptorSets;
@@ -503,12 +499,7 @@ int main(int argc, const char** argv) {
 		{ resolveDescriptorSetLayout }
 	});
 
-	vkcv::SamplerHandle resolveSampler = core.createSampler(
-		vkcv::SamplerFilterType::NEAREST,
-		vkcv::SamplerFilterType::NEAREST,
-		vkcv::SamplerMipmapMode::NEAREST,
-		vkcv::SamplerAddressMode::CLAMP_TO_EDGE
-	);
+	vkcv::SamplerHandle resolveSampler = vkcv::samplerNearest(core, true);
 
 	// model matrices per mesh
 	std::vector<glm::mat4> modelMatrices;
@@ -539,12 +530,7 @@ int main(int argc, const char** argv) {
 			vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) }));
 	}
 
-	vkcv::SamplerHandle voxelSampler = core.createSampler(
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerFilterType::LINEAR,
-		vkcv::SamplerMipmapMode::LINEAR,
-		vkcv::SamplerAddressMode::CLAMP_TO_EDGE
-	);
+	vkcv::SamplerHandle voxelSampler = vkcv::samplerLinear(core, true);
 
 	ShadowMapping shadowMapping(&core, vertexLayout);
 
diff --git a/src/vkcv/Sampler.cpp b/src/vkcv/Sampler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f122608afa6445bd59735be5c3d2cedc2a5e3d08
--- /dev/null
+++ b/src/vkcv/Sampler.cpp
@@ -0,0 +1,28 @@
+
+#include "vkcv/Sampler.hpp"
+
+namespace vkcv {
+	
+	SamplerHandle samplerLinear(Core &core, bool clampToEdge) {
+		return core.createSampler(
+				vkcv::SamplerFilterType::LINEAR,
+				vkcv::SamplerFilterType::LINEAR,
+				vkcv::SamplerMipmapMode::LINEAR,
+				clampToEdge?
+					vkcv::SamplerAddressMode::CLAMP_TO_EDGE :
+					vkcv::SamplerAddressMode::REPEAT
+		);
+	}
+	
+	SamplerHandle samplerNearest(Core &core, bool clampToEdge) {
+		return core.createSampler(
+				vkcv::SamplerFilterType::NEAREST,
+				vkcv::SamplerFilterType::NEAREST,
+				vkcv::SamplerMipmapMode::NEAREST,
+				clampToEdge?
+				vkcv::SamplerAddressMode::CLAMP_TO_EDGE :
+				vkcv::SamplerAddressMode::REPEAT
+		);
+	}
+	
+}