diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp
index 0d29625aec6b7f607372e5f0c147ff32f229ad03..b1dd56d5ddb29d6f986bfa490d3cb7bdfb37c4ca 100644
--- a/include/vkcv/PipelineConfig.hpp
+++ b/include/vkcv/PipelineConfig.hpp
@@ -32,7 +32,8 @@ namespace vkcv {
         Multisampling                           m_multisampling                 = Multisampling::None;
         CullMode                                m_culling                       = CullMode::None;
         DepthTest                               m_depthTest                     = DepthTest::LessEqual;
-        bool                                    m_depthWrite              = true;
+        bool                                    m_depthWrite                    = true;
+        bool                                    m_alphaToCoverage               = false;
     };
 
 }
\ No newline at end of file
diff --git a/projects/voxelization/resources/shaders/depthPrepass.frag b/projects/voxelization/resources/shaders/depthPrepass.frag
index 65592d2cfe161b8522de1a0c3e68fa1d6afa80be..5e2f7a092ca300af40cc039608a44d080c28730f 100644
--- a/projects/voxelization/resources/shaders/depthPrepass.frag
+++ b/projects/voxelization/resources/shaders/depthPrepass.frag
@@ -2,6 +2,19 @@
 #extension GL_ARB_separate_shader_objects : enable
 #extension GL_GOOGLE_include_directive : enable
 
-void main()	{
+#include "perMeshResources.inc"
+
+layout(location = 0) in vec2 passUV;
 
+layout(location = 0) out vec4 outColor; // only used for alpha to coverage, not actually written to
+
+// coverage to alpha techniques explained in: https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f
+void main()	{
+    float alpha         = texture(sampler2D(albedoTexture, textureSampler), passUV).a;
+    float alphaCutoff   = 0.5;
+    
+    // scale alpha to one pixel width
+    alpha               = (alpha - alphaCutoff) / max(fwidth(alpha), 0.0001) + 0.5;
+    
+    outColor.a          = alpha;
 }
\ No newline at end of file
diff --git a/projects/voxelization/resources/shaders/depthPrepass.vert b/projects/voxelization/resources/shaders/depthPrepass.vert
index d800c547368c4f2126c880534276a3be3cf336f5..4bb3500eb59214e30fce84862e181fd7e24b7340 100644
--- a/projects/voxelization/resources/shaders/depthPrepass.vert
+++ b/projects/voxelization/resources/shaders/depthPrepass.vert
@@ -4,6 +4,9 @@
 #extension GL_GOOGLE_include_directive : enable
 
 layout(location = 0) in vec3 inPosition;
+layout(location = 2) in vec2 inUV;
+
+layout(location = 0) out vec2 passUV;
 
 layout( push_constant ) uniform constants{
     mat4 mvp;
@@ -11,4 +14,5 @@ layout( push_constant ) uniform constants{
 
 void main()	{
 	gl_Position = mvp * vec4(inPosition, 1.0);
+    passUV = inUV;
 }
\ No newline at end of file
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index b19fad0f1673deaea64be0ae5000cf013c97438e..e67098693249c5070dde7f003f1810988269cf1c 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -177,20 +177,6 @@ int main(int argc, const char** argv) {
 	vkcv::PassConfig prepassPassDefinition({ prepassAttachment }, msaa);
 	vkcv::PassHandle prepassPass = core.createPass(prepassPassDefinition);
 
-	vkcv::PipelineConfig prepassPipelineConfig{
-		depthPrepassShader,
-		windowWidth,
-		windowHeight,
-		prepassPass,
-		vertexLayout,
-		{},
-		true};
-	prepassPipelineConfig.m_culling         = vkcv::CullMode::Back;
-	prepassPipelineConfig.m_multisampling   = msaa;
-	prepassPipelineConfig.m_depthTest       = vkcv::DepthTest::LessEqual;
-
-	vkcv::PipelineHandle prepassPipeline = core.createGraphicsPipeline(prepassPipelineConfig);
-
 	// create descriptor sets
 	vkcv::SamplerHandle colorSampler = core.createSampler(
 		vkcv::SamplerFilterType::LINEAR,
@@ -264,13 +250,35 @@ int main(int argc, const char** argv) {
 		perMeshDescriptorSets.push_back(materialDescriptorSets[vertexGroup.materialIndex]);
 	}
 
+	// prepass pipeline
+	vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(std::vector<vkcv::DescriptorBinding>());
+
+	vkcv::PipelineConfig prepassPipelineConfig{
+		depthPrepassShader,
+		windowWidth,
+		windowHeight,
+		prepassPass,
+		vertexLayout,
+		{ 
+			core.getDescriptorSet(prepassDescriptorSet).layout,
+			core.getDescriptorSet(perMeshDescriptorSets[0]).layout },
+		true };
+	prepassPipelineConfig.m_culling         = vkcv::CullMode::Back;
+	prepassPipelineConfig.m_multisampling   = msaa;
+	prepassPipelineConfig.m_depthTest       = vkcv::DepthTest::LessEqual;
+	prepassPipelineConfig.m_alphaToCoverage = true;
+
+	vkcv::PipelineHandle prepassPipeline = core.createGraphicsPipeline(prepassPipelineConfig);
+
+	// forward pipeline
 	vkcv::PipelineConfig forwardPipelineConfig {
 		forwardProgram,
 		windowWidth,
 		windowHeight,
 		forwardPass,
 		vertexLayout,
-		{	core.getDescriptorSet(forwardShadingDescriptorSet).layout, 
+		{	
+			core.getDescriptorSet(forwardShadingDescriptorSet).layout, 
 			core.getDescriptorSet(perMeshDescriptorSets[0]).layout },
 		true
 	};
@@ -408,7 +416,9 @@ int main(int argc, const char** argv) {
 		drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { 
 			vkcv::DescriptorSetUsage(0, core.getDescriptorSet(forwardShadingDescriptorSet).vulkanHandle),
 			vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) }));
-		prepassDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {}));
+		prepassDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {
+			vkcv::DescriptorSetUsage(0, core.getDescriptorSet(prepassDescriptorSet).vulkanHandle),
+			vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) }));
 	}
 
 	vkcv::SamplerHandle voxelSampler = core.createSampler(
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index ca0f9225759cc7f4e16b1ba9596f2b9fd6275464..212e5b56e8ed7469a6e6368d9c61317ea08d5ad1 100644
--- a/src/vkcv/PipelineManager.cpp
+++ b/src/vkcv/PipelineManager.cpp
@@ -193,7 +193,7 @@ namespace vkcv
                 false,
                 0.f,
                 nullptr,
-                false,
+                config.m_alphaToCoverage,
                 false
         );