From f04fcfcd45ac49dbb62a333d068938ab7c479ad6 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Thu, 24 Jun 2021 19:47:45 +0200
Subject: [PATCH] [#82] Add alpha to coverage to anti-alias alpha tested
 geometry

---
 include/vkcv/PipelineConfig.hpp                    |  3 ++-
 .../resources/shaders/depthPrepass.frag            | 14 ++++++++++----
 projects/voxelization/src/main.cpp                 |  7 ++++---
 src/vkcv/PipelineManager.cpp                       |  2 +-
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp
index 0d29625a..b1dd56d5 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 b2401639..5e2f7a09 100644
--- a/projects/voxelization/resources/shaders/depthPrepass.frag
+++ b/projects/voxelization/resources/shaders/depthPrepass.frag
@@ -6,9 +6,15 @@
 
 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;
-    if(alpha < 0.5){
-        discard;
-    }
+    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/src/main.cpp b/projects/voxelization/src/main.cpp
index c3ca1c7f..d2b1ca56 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -263,9 +263,10 @@ int main(int argc, const char** argv) {
 			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_culling         = vkcv::CullMode::Back;
+	prepassPipelineConfig.m_multisampling   = msaa;
+	prepassPipelineConfig.m_depthTest       = vkcv::DepthTest::LessEqual;
+	prepassPipelineConfig.m_alphaToCoverage = true;
 
 	vkcv::PipelineHandle prepassPipeline = core.createGraphicsPipeline(prepassPipelineConfig);
 
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index ca0f9225..212e5b56 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
         );
 
-- 
GitLab