Having to implement it separately in each material's shader is not
optimal, but since they each define their own uniform block, no better
solution is readily apparent.
The occluder shader also supports alpha cutoff so that objects with
such materials can cast proper shadows.
uniform PbrMaterial
{
PbrMaterialParameters pbr_material;
uniform PbrMaterial
{
PbrMaterialParameters pbr_material;
};
uniform sampler2D base_color_map;
};
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_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()
#pragma MSP stage(fragment)
virtual vec4 get_base_color()
+ vec4 base_color = get_base_color();
+ if(use_alpha_cutoff && base_color.a<alpha_cutoff)
+ discard;
+
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
- vec4 base_color = get_base_color();
float metalness = get_metalness_value();
float roughness = get_roughness_value();
float metalness = get_metalness_value();
float roughness = get_roughness_value();
+uniform AlphaCutoff
+{
+ float alpha_cutoff;
+};
+
+uniform sampler2D alpha_map;
+
+layout(constant_id=auto) const bool use_alpha_cutoff = false;
+
#pragma MSP stage(vertex)
virtual vec4 get_vertex_position()
{
#pragma MSP stage(vertex)
virtual vec4 get_vertex_position()
{
vec4 eye_vertex = eye_world_matrix*get_vertex_transform()*get_vertex_position();
clipping(eye_vertex.xyz);
gl_Position = clip_eye_matrix*eye_vertex;
vec4 eye_vertex = eye_world_matrix*get_vertex_transform()*get_vertex_position();
clipping(eye_vertex.xyz);
gl_Position = clip_eye_matrix*eye_vertex;
+ passthrough;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+
+void main()
+{
+ if(use_alpha_cutoff)
+ {
+ float alpha = texture(alpha_map, texcoord.xy).a;
+ if(alpha<alpha_cutoff)
+ discard;
+ frag_color = vec4(1.0);
+ }
uniform BasicMaterial
{
BasicMaterialParameters basic_material;
uniform BasicMaterial
{
BasicMaterialParameters basic_material;
};
uniform sampler2D diffuse_map;
};
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_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()
#pragma MSP stage(fragment)
virtual vec4 get_diffuse_color()
+ vec4 surface_diffuse = get_diffuse_color();
+ if(use_alpha_cutoff && surface_diffuse.a<alpha_cutoff)
+ discard;
+
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
vec3 normal = get_fragment_normal();
vec3 look = normalize(world_look_dir);
- vec4 surface_diffuse = get_diffuse_color();
vec3 surface_specular = get_specular_color();
float shininess = get_shininess_value();
vec3 surface_specular = get_specular_color();
float shininess = get_shininess_value();
uniform UnlitMaterial
{
UnlitMaterialParameters unlit_material;
uniform UnlitMaterial
{
UnlitMaterialParameters unlit_material;
};
uniform sampler2D color_tex;
};
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_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()
#pragma MSP stage(fragment)
virtual vec4 get_color()
void main()
{
vec4 color = get_color();
void main()
{
vec4 color = get_color();
+ if(use_alpha_cutoff && color.a<alpha_cutoff)
+ discard;
+
if(use_fog)
color.rgb = apply_fog(color.rgb);
frag_color = color;
if(use_fog)
color.rgb = apply_fog(color.rgb);
frag_color = color;
namespace Msp {
namespace GL {
namespace Msp {
namespace GL {
+Material::Material()
+{
+ set_alpha_cutoff(0.0f);
+}
+
const Program *Material::create_compatible_shader(const map<string, int> &extra_spec) const
{
string module_name;
map<string, int> spec_values;
const Program *Material::create_compatible_shader(const map<string, int> &extra_spec) const
{
string module_name;
map<string, int> spec_values;
+ if(alpha_cutoff>0.0f)
+ spec_values["use_alpha_cutoff"] = true;
+
fill_program_info(module_name, spec_values);
for(const auto &kvp: extra_spec)
fill_program_info(module_name, spec_values);
for(const auto &kvp: extra_spec)
+void Material::set_alpha_cutoff(float a)
+{
+ alpha_cutoff = a;
+ shdata.uniform("alpha_cutoff", a);
+}
+
void Material::set_debug_name(const string &name)
{
#ifdef DEBUG
void Material::set_debug_name(const string &name)
{
#ifdef DEBUG
void Material::Loader::init_actions()
{
void Material::Loader::init_actions()
{
+ add("alpha_cutoff", &Loader::alpha_cutoff);
add("sampler", &Loader::sampler);
}
add("sampler", &Loader::sampler);
}
+void Material::Loader::alpha_cutoff(float a)
+{
+ obj.set_alpha_cutoff(a);
+}
+
void Material::Loader::sampler(const string &name)
{
obj.sampler = &get_collection().get<Sampler>(name);
void Material::Loader::sampler(const string &name)
{
obj.sampler = &get_collection().get<Sampler>(name);
virtual void init_actions();
private:
virtual void init_actions();
private:
+ void alpha_cutoff(float);
void sampler(const std::string &);
};
void sampler(const std::string &);
};
protected:
const Sampler *sampler = 0;
protected:
const Sampler *sampler = 0;
+ float alpha_cutoff = 0.0f;
public:
virtual ~Material() = default;
public:
virtual ~Material() = default;
virtual const Texture *get_texture(Tag) const = 0;
virtual const Sampler *get_sampler(Tag) const { return sampler; }
virtual const Texture *get_texture(Tag) const = 0;
virtual const Sampler *get_sampler(Tag) const { return sampler; }
+ void set_alpha_cutoff(float a);
+ float get_alpha_cutoff() const { return alpha_cutoff; }
+
void set_debug_name(const std::string &);
template<typename T>
void set_debug_name(const std::string &);
template<typename T>