From 4595453156db0c47926946b0ea1732b1e37e70ce Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 23 Apr 2022 19:33:58 +0300 Subject: [PATCH] Add support for alpha to coverage --- shaderlib/common.glsl | 20 +++++++++++++++++++ shaderlib/cooktorrance.glsl | 8 +++----- shaderlib/phong.glsl | 8 +++----- shaderlib/unlit.glsl | 6 ++---- .../backends/opengl/pipelinestate_backend.cpp | 5 +++++ .../backends/vulkan/pipelinestate_backend.cpp | 4 +++- source/core/blend.cpp | 1 + source/core/blend.h | 4 +++- source/materials/material.cpp | 16 ++++++++++++++- source/materials/material.h | 6 +++++- 10 files changed, 60 insertions(+), 18 deletions(-) diff --git a/shaderlib/common.glsl b/shaderlib/common.glsl index 300726dc..695bce3b 100644 --- a/shaderlib/common.glsl +++ b/shaderlib/common.glsl @@ -1,10 +1,17 @@ import msp_interface; import shadow; +struct AlphaCutoffParams +{ + float cutoff; + float feather; +}; + layout(set=1) uniform sampler2D normal_map; layout(constant_id=auto) const bool use_instancing = false; layout(constant_id=auto) const bool use_normal_map = false; +layout(constant_id=auto) const bool use_alpha_cutoff = false; #pragma MSP stage(vertex) virtual vec4 get_vertex_position() @@ -95,6 +102,19 @@ virtual IncomingLight get_incoming_light(int index, vec3 world_pos) return IncomingLight(rel_pos/d, light_sources[index].color*attenuation); } +float apply_alpha_cutoff(float alpha, AlphaCutoffParams params) +{ + if(use_alpha_cutoff) + { + if(alphaget_format().get_samples()>1) + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); } applied_to = &device; diff --git a/source/backends/vulkan/pipelinestate_backend.cpp b/source/backends/vulkan/pipelinestate_backend.cpp index 1578f997..9c695b3d 100644 --- a/source/backends/vulkan/pipelinestate_backend.cpp +++ b/source/backends/vulkan/pipelinestate_backend.cpp @@ -118,6 +118,8 @@ uint64_t VulkanPipelineState::compute_hash() const } result = hash_round<64>(result, format.get_samples()); + if(format.get_samples()>1) + result = hash_round<64>(result, self.blend.alpha_to_coverage); if(self.depth_test.enabled) { @@ -216,7 +218,7 @@ void VulkanPipelineState::fill_graphics_creation_info(vector &buffer) cons multisample_info->sampleShadingEnable = VK_FALSE; multisample_info->minSampleShading = 1.0f; multisample_info->pSampleMask = 0; - multisample_info->alphaToCoverageEnable = VK_FALSE; + multisample_info->alphaToCoverageEnable = (format.get_samples()>1 && self.blend.alpha_to_coverage ? VK_TRUE : VK_FALSE); multisample_info->alphaToOneEnable = VK_FALSE; depth_stencil_info->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; diff --git a/source/core/blend.cpp b/source/core/blend.cpp index 99ffcd07..2923cb45 100644 --- a/source/core/blend.cpp +++ b/source/core/blend.cpp @@ -24,6 +24,7 @@ Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df): Blend::Loader::Loader(Blend &b): ObjectLoader(b) { + add("alpha_to_coverage", &Blend::alpha_to_coverage); add("equation", &Loader::equation); add("factors", &Loader::factors); add("constant", &Loader::constant); diff --git a/source/core/blend.h b/source/core/blend.h index 3edebc8c..874230c6 100644 --- a/source/core/blend.h +++ b/source/core/blend.h @@ -67,6 +67,7 @@ struct Blend BlendFactor dst_factor = ZERO; Color constant = { 0.0f, 0.0f, 0.0f, 0.0f }; ColorWriteMask write_mask = WRITE_ALL; + bool alpha_to_coverage = false; Blend() = default; Blend(BlendFactor, BlendFactor); @@ -79,7 +80,8 @@ struct Blend inline bool Blend::operator==(const Blend &other) const { return enabled==other.enabled && equation==other.equation && src_factor==other.src_factor && - dst_factor==other.dst_factor && constant==other.constant && write_mask==other.write_mask; + dst_factor==other.dst_factor && constant==other.constant && write_mask==other.write_mask && + alpha_to_coverage==other.alpha_to_coverage; } diff --git a/source/materials/material.cpp b/source/materials/material.cpp index 6af833e6..542c8474 100644 --- a/source/materials/material.cpp +++ b/source/materials/material.cpp @@ -14,6 +14,7 @@ namespace GL { Material::Material() { set_alpha_cutoff(0.0f); + set_alpha_feather(1.0f); } const Program *Material::create_compatible_shader(const map &extra_spec) const @@ -59,7 +60,13 @@ const Program *Material::create_compatible_shader(const map &extra_ void Material::set_alpha_cutoff(float a) { alpha_cutoff = a; - shdata.uniform("alpha_cutoff", a); + shdata.uniform("alpha_cutoff.cutoff", a); +} + +void Material::set_alpha_feather(float f) +{ + alpha_feather = f; + shdata.uniform("alpha_cutoff.feather", f); } void Material::set_debug_name(const string &name) @@ -93,6 +100,7 @@ Material::Loader::Loader(Material &m, Collection &c): void Material::Loader::init_actions() { add("alpha_cutoff", &Loader::alpha_cutoff); + add("alpha_cutoff", &Loader::alpha_cutoff_feather); add("sampler", &Loader::sampler); } @@ -101,6 +109,12 @@ void Material::Loader::alpha_cutoff(float a) obj.set_alpha_cutoff(a); } +void Material::Loader::alpha_cutoff_feather(float a, float f) +{ + obj.set_alpha_cutoff(a); + obj.set_alpha_feather(f); +} + void Material::Loader::sampler(const string &name) { obj.sampler = &get_collection().get(name); diff --git a/source/materials/material.h b/source/materials/material.h index 75ff972c..3210c966 100644 --- a/source/materials/material.h +++ b/source/materials/material.h @@ -28,6 +28,7 @@ private: private: void alpha_cutoff(float); + void alpha_cutoff_feather(float, float); void sampler(const std::string &); }; @@ -74,6 +75,7 @@ public: protected: const Sampler *sampler = 0; float alpha_cutoff = 0.0f; + float alpha_feather = 1.0f; ProgramData shdata; Material(); @@ -98,8 +100,10 @@ public: virtual const Texture *get_texture(Tag) const = 0; virtual const Sampler *get_sampler(Tag) const { return sampler; } - void set_alpha_cutoff(float a); + void set_alpha_cutoff(float); + void set_alpha_feather(float); float get_alpha_cutoff() const { return alpha_cutoff; } + float get_alpha_feather() const { return alpha_feather; } void set_debug_name(const std::string &); -- 2.43.0