From f1e296bb2442dfbea12e7b38a97cc152aa34569c Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 17 Mar 2022 22:04:52 +0200 Subject: [PATCH] Add instancing support to standard shaders and RenderMethod --- shaderlib/common.glsl | 11 +++++++++-- shaderlib/occluder.glsl | 6 +++++- source/materials/rendermethod.cpp | 3 +++ source/materials/rendermethod.h | 7 +++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/shaderlib/common.glsl b/shaderlib/common.glsl index 44ef150a..6bac9c37 100644 --- a/shaderlib/common.glsl +++ b/shaderlib/common.glsl @@ -10,6 +10,7 @@ layout(set=1) uniform sampler2D normal_map; layout(set=0) uniform samplerCube environment_map; layout(set=0) uniform samplerCube irradiance_map; +layout(constant_id=auto) const bool use_instancing = false; layout(constant_id=auto) const bool use_normal_map = false; #pragma MSP stage(vertex) @@ -25,12 +26,18 @@ virtual vec3 get_vertex_normal() virtual mat4 get_vertex_transform() { - return world_obj_matrix; + if(use_instancing) + return transpose(mat4(instance_transform[0], instance_transform[1], instance_transform[2], vec4(0.0, 0.0, 0.0, 1.0))); + else + return world_obj_matrix; } virtual mat3 get_normal_transform() { - return world_obj_normal_matrix; + if(use_instancing) + return transpose(mat3(instance_transform[0].xyz, instance_transform[1].xyz, instance_transform[2].xyz)); + else + return world_obj_normal_matrix; } void standard_transform() diff --git a/shaderlib/occluder.glsl b/shaderlib/occluder.glsl index 6d6cd560..a4d876ec 100644 --- a/shaderlib/occluder.glsl +++ b/shaderlib/occluder.glsl @@ -8,6 +8,7 @@ layout(set=1) uniform AlphaCutoff layout(set=1) uniform sampler2D alpha_map; layout(constant_id=auto) const bool use_alpha_cutoff = false; +layout(constant_id=auto) const bool use_instancing = false; #pragma MSP stage(vertex) virtual vec4 get_vertex_position() @@ -17,7 +18,10 @@ virtual vec4 get_vertex_position() virtual mat4 get_vertex_transform() { - return world_obj_matrix; + if(use_instancing) + return transpose(mat4(instance_transform[0], instance_transform[1], instance_transform[2], vec4(0.0, 0.0, 0.0, 1.0))); + else + return world_obj_matrix; } virtual void clipping(vec3 eye_vertex) diff --git a/source/materials/rendermethod.cpp b/source/materials/rendermethod.cpp index ddbe4f1e..66424856 100644 --- a/source/materials/rendermethod.cpp +++ b/source/materials/rendermethod.cpp @@ -34,6 +34,8 @@ void RenderMethod::maybe_create_material_shader() extra_spec["use_shadow_map"] = true; if(image_based_lighting) extra_spec["use_image_based_lighting"] = true; + if(instancing) + extra_spec["use_instancing"] = true; shprog = material->create_compatible_shader(extra_spec); @@ -154,6 +156,7 @@ void RenderMethod::Loader::init_actions() add("face_cull", &RenderMethod::face_cull); add("shader", &Loader::shader); add("image_based_lighting", &RenderMethod::image_based_lighting); + add("instancing", &RenderMethod::instancing); add("material", &Loader::material_inline); add("material", &Loader::material); add("material_slot", &RenderMethod::material_slot); diff --git a/source/materials/rendermethod.h b/source/materials/rendermethod.h index 9ac9337f..8fd289fe 100644 --- a/source/materials/rendermethod.h +++ b/source/materials/rendermethod.h @@ -89,6 +89,7 @@ private: Blend blend; bool receive_shadows = false; bool image_based_lighting = false; + bool instancing = false; void maybe_create_material_shader(); void set_material_textures(); @@ -126,6 +127,12 @@ public: bool get_image_based_lighting() const { return image_based_lighting; } + /** Toggles instanced rendering. Only affects shaders created from + materials. Should be used with InstanceArray. */ + void set_instancing(bool); + + bool get_instancing() const { return instancing; } + void apply(Renderer &) const; void set_debug_name(const std::string &); -- 2.43.0