]> git.tdb.fi Git - libs/gl.git/commitdiff
Use specialization constants in the builtin material shaders
authorMikko Rasa <tdb@tdb.fi>
Fri, 26 Feb 2021 23:27:16 +0000 (01:27 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 26 Feb 2021 23:27:54 +0000 (01:27 +0200)
This has the side effect that RenderPass now requires a collection
to use the builtin shaders.

13 files changed:
shaderlib/common.glsl
shaderlib/cooktorrance.glsl
shaderlib/phong.glsl
shaderlib/shadow.glsl
source/materials/basicmaterial.cpp
source/materials/basicmaterial.h
source/materials/material.cpp
source/materials/material.h
source/materials/pbrmaterial.cpp
source/materials/pbrmaterial.h
source/materials/renderpass.cpp
source/materials/unlitmaterial.cpp
source/materials/unlitmaterial.h

index 4a81636037be1224d0d2856cdfd90b67d8eef3fc..5c10d06fbcac31a5fd9c06f5e37293ea406c2203 100644 (file)
@@ -1,7 +1,7 @@
 import msp_interface;
 import shadow;
 
-const bool use_normal_map = false;
+layout(constant_id=auto) const bool use_normal_map = false;
 
 #pragma MSP stage(vertex)
 vec4 get_vertex_position()
index 6a7ebb387fdf3e39aa772940b22b9a5b02007da9..89b4c99c3156db1f98aa88b37436b915df9cf008 100644 (file)
@@ -2,12 +2,12 @@ import msp_interface;
 import common;
 import shadow;
 
-const bool use_base_color_map = false;
-const bool use_metalness_map = false;
-const bool use_roughness_map = false;
-const bool use_occlusion_map = false;
-const bool use_emission = false;
-const bool use_emission_map = false;
+layout(constant_id=auto) const bool use_base_color_map = false;
+layout(constant_id=auto) const bool use_metalness_map = false;
+layout(constant_id=auto) const bool use_roughness_map = false;
+layout(constant_id=auto) const bool use_occlusion_map = false;
+layout(constant_id=auto) const bool use_emission = false;
+layout(constant_id=auto) const bool use_emission_map = false;
 
 const float PI = 3.1415926535;
 
index 90f0ac8ac51ef65f8ed05bc5b44dccdbf9cf28a6..56fa68c7767e1264d2a170baa4931e69ae8c0482 100644 (file)
@@ -2,16 +2,16 @@ import msp_interface;
 import common;
 import shadow;
 
-const bool use_diffuse_map = false;
-const bool use_specular = false;
-const bool use_specular_map = false;
-const bool use_shininess_map = false;
-const bool use_emission = false;
-const bool use_emission_map = false;
-const bool use_reflectivity = false;
-const bool use_reflectivity_map = false;
-const bool use_sky = false;
-const bool use_fog = false;
+layout(constant_id=auto) const bool use_diffuse_map = false;
+layout(constant_id=auto) const bool use_specular = false;
+layout(constant_id=auto) const bool use_specular_map = false;
+layout(constant_id=auto) const bool use_shininess_map = 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_reflectivity = false;
+layout(constant_id=auto) const bool use_reflectivity_map = false;
+layout(constant_id=auto) const bool use_sky = false;
+layout(constant_id=auto) const bool use_fog = false;
 
 #pragma MSP stage(fragment)
 vec4 get_diffuse_color()
index 0a20b3a513998272fc13d14f386f621f32864e8d..d751b460778af84155e127b828d21c6f4f614d33 100644 (file)
@@ -1,6 +1,6 @@
 import msp_interface;
 
-const bool use_shadow_map = false;
+layout(constant_id=auto) const bool use_shadow_map = false;
 
 #pragma MSP stage(vertex)
 void shadow_transform(vec4 eye_vertex)
index 362fc9db14e6a8636960bec3a746cd8e62715ed8..33dced53d7fb65c68fce1251893f14b202c144c3 100644 (file)
@@ -15,36 +15,21 @@ BasicMaterial::BasicMaterial():
        set_reflectivity(0.0f);
 }
 
-string BasicMaterial::create_program_source() const
-{
-       string source = "import phong;\n";
-       if(diffuse.texture)
-               source += "const bool use_diffuse_map = true;\n";
-       if(specular.texture || specular.value.r || specular.value.g || specular.value.b)
-       {
-               source += "const bool use_specular = true;\n";
-               if(specular.texture)
-                       source += "const bool use_specular_map = true;\n";
-               if(shininess.texture)
-                       source += "const bool use_shininess_map = true;\n";
-       }
-       if(normal.texture)
-               source += "const bool use_normal_map = true;\n";
-       if(emission.texture || emission.value.r || emission.value.g || emission.value.b)
-       {
-               source += "const bool use_emission = true;\n";
-               if(emission.texture)
-                       source += "const bool use_emission_map = true;\n";
-       }
-       if(reflectivity.value || reflectivity.texture)
-       {
-               source += "const bool use_reflectivity = true;\n";
-               if (reflectivity.texture)
-                       source += "const bool use_reflectivity_map = true;\n";
-       }
-       if(receive_shadows)
-               source += "const bool use_shadow_map = true;\n";
-       return source;
+void BasicMaterial::fill_program_info(string &module_name, map<string, int> &spec_values) const
+{
+       module_name = "phong.glsl";
+       spec_values["use_diffuse_map"] = (diffuse.texture!=0);
+       bool use_specular = (specular.texture || specular.value.r || specular.value.g || specular.value.b);
+       spec_values["use_specular"] = use_specular;
+       spec_values["use_specular_map"] = (specular.texture!=0);
+       spec_values["use_shininess_map"] = (use_specular && shininess.texture!=0);
+       spec_values["use_normal_map"] = (normal.texture!=0);
+       bool use_emission = (emission.texture || emission.value.r || emission.value.g || emission.value.b);
+       spec_values["use_emission"] = use_emission;
+       spec_values["use_emission_map"] = (emission.texture!=0);
+       spec_values["use_reflectivity"] = (reflectivity.value!=0 || reflectivity.texture!=0);
+       spec_values["use_reflectivity_map"] = (reflectivity.texture!=0);
+       spec_values["use_shadow_map"] = receive_shadows;
 }
 
 void BasicMaterial::attach_textures_to(Texturing &texturing, ProgramData &tex_shdata) const
index 95259f476b233198856c49a42391049f54f6b0b5..ef7d1526726c48d101e8ca8c232d63b903794521 100644 (file)
@@ -35,7 +35,7 @@ public:
        BasicMaterial();
 
 protected:
-       virtual std::string create_program_source() const;
+       virtual void fill_program_info(std::string &, std::map<std::string, int> &) const;
 
 public:
        virtual void attach_textures_to(Texturing &, ProgramData &) const;
index 17fa546bbf0ba9f94fb7e08688afd3a46a2d7cee..25ed72189b1bac8c43ef1e028d5f940a1b086214 100644 (file)
@@ -13,20 +13,23 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-Program *Material::create_compatible_shader() const
-{
-       return new Program(create_program_source());
-}
-
 const Program *Material::create_compatible_shader(DataFile::Collection &coll) const
 {
-       string source = create_program_source();
-       string name = format("_material_%016x.glsl", hash64(source));
+       string module_name;
+       map<string, int> spec_values;
+       fill_program_info(module_name, spec_values);
+
+       string info = module_name;
+       for(map<string, int>::const_iterator i=spec_values.begin(); i!=spec_values.end(); ++i)
+               info += format(",%s:%d", i->first, i->second);
+
+       string name = format("_material_%016x.shader", hash64(info));
        Program *shprog = coll.find<Program>(name);
        if(shprog)
                return shprog;
 
-       shprog = new Program(create_program_source());
+       const Module &module = coll.get<Module>(module_name);
+       shprog = new Program(module, spec_values);
        try
        {
                coll.add(name, shprog);
index 350372dd144d4aadb194696e27bd86939cd85f2b..727c61b7303c7faa230241d875c21605b6de598c 100644 (file)
@@ -96,10 +96,9 @@ protected:
 public:
        virtual ~Material() { }
 
-       virtual Program *create_compatible_shader() const;
        virtual const Program *create_compatible_shader(DataFile::Collection &) const;
 protected:
-       virtual std::string create_program_source() const = 0;
+       virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
 
 public:
        /** Returns the uniforms for the material. */
index bc7104cc652d485350614b5737b32e6a42771f80..16c287b4e40f6ad97987ac517ba57315646dc711 100644 (file)
@@ -14,28 +14,18 @@ PbrMaterial::PbrMaterial():
        set_emission(0.0f);
 }
 
-string PbrMaterial::create_program_source() const
-{
-       string source = "import cooktorrance;\n";
-       if(base_color.texture)
-               source += "const bool use_base_color_map = true;\n";
-       if(normal.texture)
-               source += "const bool use_normal_map = true;\n";
-       if(metalness.texture)
-               source += "const bool use_metalness_map = true;\n";
-       if(roughness.texture)
-               source += "const bool use_roughness_map = true;\n";
-       if(occlusion.texture)
-               source += "const bool use_occlusion_map = true;\n";
-       if(emission.texture || emission.value.r || emission.value.g || emission.value.b)
-       {
-               source += "const bool use_emission = true;\n";
-               if(emission.texture)
-                       source += "const bool use_emission_map = true;\n";
-       }
-       if(receive_shadows)
-               source += "const bool use_shadow_map = true;\n";
-       return source;
+void PbrMaterial::fill_program_info(string &module_name, map<string, int> &spec_values) const
+{
+       module_name = "cooktorrance.glsl";
+       spec_values["use_base_color_map"] = (base_color.texture!=0);
+       spec_values["use_normal_map"] = (normal.texture!=0);
+       spec_values["use_metalness_map"] = (metalness.texture!=0);
+       spec_values["use_roughness_map"] = (roughness.texture!=0);
+       spec_values["use_occlusion_map"] = (occlusion.texture!=0);
+       bool use_emission = (emission.texture || emission.value.r || emission.value.g || emission.value.b);
+       spec_values["use_emission"] = use_emission;
+       spec_values["use_emission_map"] = (emission.texture!=0);
+       spec_values["use_shadow_map"] = receive_shadows;
 }
 
 void PbrMaterial::attach_textures_to(Texturing &texturing, ProgramData &tex_shdata) const
index 2a0eef3531951efbc2669644d27ff4671a552d33..a1f736f4bf3af657f938be004de70e621e4c9570 100644 (file)
@@ -35,7 +35,7 @@ public:
        PbrMaterial();
 
 protected:
-       virtual std::string create_program_source() const;
+       virtual void fill_program_info(std::string &, std::map<std::string, int> &) const;
 
 public:
        virtual void attach_textures_to(Texturing &, ProgramData &) const;
index fb092624b756c06ff463cdb34097b458cdd15158..5ee50f8a1726b39cf986740db7326c699281f2d6 100644 (file)
@@ -77,7 +77,7 @@ void RenderPass::maybe_create_material_shader(DataFile::Collection *coll)
                shprog.keep();
        }
        else
-               shprog = material->create_compatible_shader();
+               throw invalid_operation("no collection");
 
        if(shdata)
                shdata = new ProgramData(*shdata, shprog.get());
index 5eddd66997416438643003dd5efdc872a25ebbec..9aded2522972250cc76b1efcc3b0a745916b4461 100644 (file)
@@ -12,14 +12,11 @@ UnlitMaterial::UnlitMaterial():
        set_tint(Color(1.0f));
 }
 
-string UnlitMaterial::create_program_source() const
+void UnlitMaterial::fill_program_info(string &module_name, map<string, int> &spec_values) const
 {
-       string source = "import unlit;\n";
-       if(texture)
-               source += "const bool use_texture = true;\n";
-       if(vertex_color)
-               source += "const bool use_vertex_color = true;\n";
-       return source;
+       module_name = "unlit.glsl";
+       spec_values["use_texture"] = (texture!=0);
+       spec_values["use_vertex_color"] = vertex_color;
 }
 
 void UnlitMaterial::attach_textures_to(Texturing &texturing, ProgramData &tex_shdata) const
index b8b28835b7ce18f031c79a4cb0a877670555b2ac..22e226917da00298d7c8934f3adedae0eed86c0e 100644 (file)
@@ -33,7 +33,7 @@ public:
        UnlitMaterial();
 
 protected:
-       virtual std::string create_program_source() const;
+       virtual void fill_program_info(std::string &, std::map<std::string, int> &) const;
 
 public:
        virtual void attach_textures_to(Texturing &, ProgramData &) const;