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()
return IncomingLight(rel_pos/d, light_sources[index].color*attenuation);
}
+float apply_alpha_cutoff(float alpha, AlphaCutoffParams params)
+{
+ if(use_alpha_cutoff)
+ {
+ if(alpha<params.cutoff)
+ discard;
+ float limit = min(params.cutoff+params.feather*fwidth(alpha), 1.0);
+ return smoothstep(params.cutoff, limit, alpha);
+ }
+ else
+ return alpha;
+}
+
vec3 apply_fog(vec3 color)
{
float fog_value = exp(fog_coord*fog_density);
layout(set=1) uniform PbrMaterial
{
PbrMaterialParameters pbr_material;
- float alpha_cutoff;
+ AlphaCutoffParams alpha_cutoff;
};
layout(set=1) uniform sampler2D base_color_map;
layout(constant_id=auto) const bool use_emission = false;
layout(constant_id=auto) const bool use_emission_map = false;
layout(constant_id=auto) const bool use_image_based_lighting = false;
-layout(constant_id=auto) const bool use_alpha_cutoff = false;
#pragma MSP stage(fragment)
virtual vec4 get_base_color()
void main()
{
vec4 base_color = get_base_color();
- if(use_alpha_cutoff && base_color.a<alpha_cutoff)
- discard;
+ float alpha = apply_alpha_cutoff(base_color.a, alpha_cutoff);
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
vec3 lit_color = cooktorrance_lighting(normal, look, base_color.rgb, metalness, roughness);
- frag_color = vec4(lit_color, base_color.a);
+ frag_color = vec4(lit_color, alpha);
}
layout(set=1) uniform BasicMaterial
{
BasicMaterialParameters basic_material;
- float alpha_cutoff;
+ AlphaCutoffParameters alpha_cutoff;
};
layout(set=1) uniform sampler2D diffuse_map;
layout(constant_id=auto) const bool use_emission_map = false;
layout(constant_id=auto) const bool use_reflectivity = false;
layout(constant_id=auto) const bool use_reflectivity_map = false;
-layout(constant_id=auto) const bool use_alpha_cutoff = false;
#pragma MSP stage(fragment)
virtual vec4 get_diffuse_color()
void main()
{
vec4 surface_diffuse = get_diffuse_color();
- if(use_alpha_cutoff && surface_diffuse.a<alpha_cutoff)
- discard;
+ float alpha = apply_alpha_cutoff(surface_diffuse.a, alpha_cutoff);
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
vec3 lit_color = phong_lighting(normal, look, surface_diffuse.rgb, surface_specular, shininess);
- frag_color = vec4(lit_color, surface_diffuse.a);
+ frag_color = vec4(lit_color, alpha);
}
layout(set=1) uniform UnlitMaterial
{
UnlitMaterialParameters unlit_material;
- float alpha_cutoff;
+ AlphaCutoffParams alpha_cutoff;
};
layout(set=1) uniform sampler2D color_tex;
layout(constant_id=auto) const bool use_texture = false;
layout(constant_id=auto) const bool use_vertex_color = false;
layout(constant_id=auto) const bool use_fog = false;
-layout(constant_id=auto) const bool use_alpha_cutoff = false;
#pragma MSP stage(fragment)
virtual vec4 get_color()
void main()
{
vec4 color = get_color();
- if(use_alpha_cutoff && color.a<alpha_cutoff)
- discard;
+ color.a = apply_alpha_cutoff(color.a, alpha_cutoff);
if(use_fog)
color.rgb = apply_fog(color.rgb);
glDisable(GL_BLEND);
glColorMask(true, true, true, true);
}
+
+ if(blend.alpha_to_coverage && self.framebuffer && self.framebuffer->get_format().get_samples()>1)
+ glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+ else
+ glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
applied_to = &device;
}
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)
{
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;
Blend::Loader::Loader(Blend &b):
ObjectLoader<Blend>(b)
{
+ add("alpha_to_coverage", &Blend::alpha_to_coverage);
add("equation", &Loader::equation);
add("factors", &Loader::factors);
add("constant", &Loader::constant);
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);
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;
}
Material::Material()
{
set_alpha_cutoff(0.0f);
+ set_alpha_feather(1.0f);
}
const Program *Material::create_compatible_shader(const map<string, int> &extra_spec) const
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)
void Material::Loader::init_actions()
{
add("alpha_cutoff", &Loader::alpha_cutoff);
+ add("alpha_cutoff", &Loader::alpha_cutoff_feather);
add("sampler", &Loader::sampler);
}
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<Sampler>(name);
private:
void alpha_cutoff(float);
+ void alpha_cutoff_feather(float, float);
void sampler(const std::string &);
};
protected:
const Sampler *sampler = 0;
float alpha_cutoff = 0.0f;
+ float alpha_feather = 1.0f;
ProgramData shdata;
Material();
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 &);