diff --git a/data/shaders/instanced_object_pass.vert b/data/shaders/instanced_object_pass.vert index 79bbd6d2d..c8f54b6e7 100644 --- a/data/shaders/instanced_object_pass.vert +++ b/data/shaders/instanced_object_pass.vert @@ -30,6 +30,7 @@ in vec3 Bitangent; in vec3 Origin; in vec3 Orientation; in vec3 Scale; +in vec4 misc_data; #endif out vec3 nor; @@ -38,10 +39,12 @@ out vec3 bitangent; out vec2 uv; out vec2 uv_bis; out vec4 color; +out vec2 color_change; #ifdef Use_Bindless_Texture flat out sampler2D handle; flat out sampler2D secondhandle; flat out sampler2D thirdhandle; +flat out sampler2D fourthhandle; #endif #stk_include "utils/getworldmatrix.vert" @@ -56,12 +59,18 @@ void main(void) // Keep direction tangent = (ViewMatrix * ModelMatrix * vec4(Tangent, 0.)).xyz; bitangent = (ViewMatrix * ModelMatrix * vec4(Bitangent, 0.)).xyz; - uv = Texcoord; + uv = (mat4(1., 0., 0., 0., + 0., 1., 0., 0., + misc_data.x, misc_data.y, 1., 0., + 0., 0., 0., 1.) + * vec4(Texcoord, 1., 1.)).xy; uv_bis = SecondTexcoord; color = Color.zyxw; + color_change = misc_data.zw; #ifdef Use_Bindless_Texture handle = Handle; secondhandle = SecondHandle; thirdhandle = ThirdHandle; + fourthhandle = FourthHandle; #endif } diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 6d8bb14f8..04b86c44f 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -7,12 +7,12 @@ uniform sampler2D colorization_mask; #ifdef Use_Bindless_Texture flat in sampler2D handle; flat in sampler2D secondhandle; +flat in sampler2D fourthhandle; #endif -uniform vec2 color_change; - in vec2 uv; in vec4 color; +in vec2 color_change; out vec4 FragColor; #stk_include "utils/getLightFactor.frag" @@ -24,6 +24,7 @@ void main(void) vec4 col = texture(handle, uv); float specmap = texture(secondhandle, uv).g; float emitmap = texture(secondhandle, uv).b; + float mask = texture(fourthhandle, uv).a; #ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); #endif diff --git a/src/graphics/command_buffer.cpp b/src/graphics/command_buffer.cpp index 22ef6453d..af3b88407 100644 --- a/src/graphics/command_buffer.cpp +++ b/src/graphics/command_buffer.cpp @@ -21,30 +21,30 @@ // ---------------------------------------------------------------------------- template<> -void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataSingleTex &instance) +void InstanceFiller::add(GLMesh *mesh, InstanceSettings is, InstanceDataSingleTex &instance) { - fillOriginOrientationScale(node, instance); + fillOriginOrientationScale(STK::tuple_get<0>(is), instance); instance.Texture = mesh->TextureHandles[0]; } // ---------------------------------------------------------------------------- template<> -void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataDualTex &instance) +void InstanceFiller::add(GLMesh *mesh, InstanceSettings is, InstanceDataDualTex &instance) { - fillOriginOrientationScale(node, instance); + fillOriginOrientationScale(STK::tuple_get<0>(is), instance); instance.Texture = mesh->TextureHandles[0]; instance.SecondTexture = mesh->TextureHandles[1]; } // ---------------------------------------------------------------------------- template<> -void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataThreeTex &instance) +void InstanceFiller::add(GLMesh *mesh, InstanceSettings is, InstanceDataThreeTex &instance) { - fillOriginOrientationScale(node, instance); - instance.MiscData.X = 0; - instance.MiscData.Y = 0; - instance.MiscData.Z = 0; - instance.MiscData.W = 0; + fillOriginOrientationScale(STK::tuple_get<0>(is), instance); + instance.MiscData.X = STK::tuple_get<1>(is).X; + instance.MiscData.Y = STK::tuple_get<1>(is).Y; + instance.MiscData.Z = STK::tuple_get<2>(is).X; + instance.MiscData.W = STK::tuple_get<2>(is).Y; instance.Texture = mesh->TextureHandles[0]; instance.SecondTexture = mesh->TextureHandles[1]; instance.ThirdTexture = mesh->TextureHandles[7]; @@ -52,13 +52,13 @@ void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode * // ---------------------------------------------------------------------------- template<> -void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataFourTex &instance) +void InstanceFiller::add(GLMesh *mesh, InstanceSettings is, InstanceDataFourTex &instance) { - fillOriginOrientationScale(node, instance); - instance.MiscData.X = 0; - instance.MiscData.Y = 0; - instance.MiscData.Z = 0; - instance.MiscData.W = 0; + fillOriginOrientationScale(STK::tuple_get<0>(is), instance); + instance.MiscData.X = STK::tuple_get<1>(is).X; + instance.MiscData.Y = STK::tuple_get<1>(is).Y; + instance.MiscData.Z = STK::tuple_get<2>(is).X; + instance.MiscData.W = STK::tuple_get<2>(is).Y; instance.Texture = mesh->TextureHandles[0]; instance.SecondTexture = mesh->TextureHandles[1]; instance.ThirdTexture = mesh->TextureHandles[2]; @@ -67,8 +67,9 @@ void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *n // ---------------------------------------------------------------------------- template<> -void InstanceFiller::add(GLMesh *mesh, scene::ISceneNode *node, GlowInstanceData &instance) +void InstanceFiller::add(GLMesh *mesh, InstanceSettings is, GlowInstanceData &instance) { + scene::ISceneNode* node = STK::tuple_get<0>(is); fillOriginOrientationScale(node, instance); STKMeshSceneNode *nd = dynamic_cast(node); instance.Color = nd->getGlowColor().color; diff --git a/src/graphics/command_buffer.hpp b/src/graphics/command_buffer.hpp index f7d5b3d15..063829b28 100644 --- a/src/graphics/command_buffer.hpp +++ b/src/graphics/command_buffer.hpp @@ -29,15 +29,17 @@ #include #include +typedef STK::Tuple InstanceSettings; + struct InstanceList { GLMesh *m_mesh; - std::vector m_scene_nodes; + std::vector m_instance_settings; }; typedef std::unordered_map , InstanceList, MeshRenderInfoHash, MeshRenderInfoEquals> SolidPassMeshMap; - + typedef std::unordered_map OtherMeshMap; // ---------------------------------------------------------------------------- @@ -67,7 +69,7 @@ void fillOriginOrientationScale(scene::ISceneNode *node, InstanceData &instance) template struct InstanceFiller { - static void add(GLMesh *, scene::ISceneNode *, InstanceData &); + static void add(GLMesh *, InstanceSettings, InstanceData &); }; // ---------------------------------------------------------------------------- @@ -93,10 +95,10 @@ void FillInstances_impl(InstanceList instance_list, GLMesh *mesh = instance_list.m_mesh; size_t initial_offset = instance_buffer_offset; - for (unsigned i = 0; i < instance_list.m_scene_nodes.size(); i++) + for (unsigned i = 0; i < instance_list.m_instance_settings.size(); i++) { - scene::ISceneNode *node = instance_list.m_scene_nodes[i]; - InstanceFiller::add(mesh, node, instance_buffer[instance_buffer_offset++]); + InstanceFiller::add(mesh, instance_list.m_instance_settings[i], + instance_buffer[instance_buffer_offset++]); assert(instance_buffer_offset * sizeof(T) < 10000 * sizeof(InstanceDataThreeTex)); } @@ -305,8 +307,7 @@ public: (const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); if (!mesh->mb->getMaterial().BackfaceCulling) glEnable(GL_CULL_FACE); - } - + } } //drawIndirectFirstPass // ---------------------------------------------------------------------------- @@ -356,19 +357,6 @@ public: { GLMesh *mesh = m_meshes[T::MaterialType][i]; expandTexSecondPass(*mesh, prefilled_tex); - - //TODO: next 10 lines are duplicated in draw_tools.hpp (see CustomUnrollArgs::drawMesh) - //TODO: find a way to remove duplicated code - const bool support_change_hue = (mesh->m_render_info != NULL && - mesh->m_material != NULL); - const bool need_change_hue = - (support_change_hue && mesh->m_render_info->getHue() > 0.0f); - if (need_change_hue) - { - T::InstancedSecondPassShader::getInstance()->changeableColor - (mesh->m_render_info->getHue(), - mesh->m_material->getColorizationFactor()); - } if (!mesh->mb->getMaterial().BackfaceCulling) glDisable(GL_CULL_FACE); glDrawElementsIndirect(GL_TRIANGLES, @@ -376,11 +364,6 @@ public: (const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); if (!mesh->mb->getMaterial().BackfaceCulling) glEnable(GL_CULL_FACE); - if (need_change_hue) - { - // Reset after changing - T::InstancedSecondPassShader::getInstance()->changeableColor(); - } } } //drawIndirectSecondPass diff --git a/src/graphics/draw_calls.cpp b/src/graphics/draw_calls.cpp index 0a4c561b3..724ad0732 100644 --- a/src/graphics/draw_calls.cpp +++ b/src/graphics/draw_calls.cpp @@ -254,53 +254,27 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node, if (node->glow()) { m_glow_pass_mesh[mesh->mb].m_mesh = mesh; - m_glow_pass_mesh[mesh->mb].m_scene_nodes.emplace_back(Node); + m_glow_pass_mesh[mesh->mb].m_instance_settings + .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } - - if (Mat != Material::SHADERTYPE_SPLATTING && mesh->texture_trans.getLength() == 0.0f) + if (Mat == Material::SHADERTYPE_SPLATTING) { - std::pair meshRenderInfo(mesh->mb, mesh->m_render_info); - m_solid_pass_mesh[Mat][meshRenderInfo].m_mesh = mesh; - m_solid_pass_mesh[Mat][meshRenderInfo].m_scene_nodes.emplace_back(Node); + //TODO: write instanced splatting solid shader and remove this if + core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; + ModelMatrix.getInverse(InvModelMatrix); + ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix); } else { - core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; - ModelMatrix.getInverse(InvModelMatrix); - switch (Mat) - { - case Material::SHADERTYPE_SOLID: - ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, - (mesh->m_render_info && mesh->m_material ? - core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : - core::vector2df(0.0f, 0.0f))); - break; - case Material::SHADERTYPE_ALPHA_TEST: - ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); - break; - case Material::SHADERTYPE_SOLID_UNLIT: - ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); - break; - case Material::SHADERTYPE_SPLATTING: - ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix); - break; - case Material::SHADERTYPE_ALPHA_BLEND: - break; - case Material::SHADERTYPE_ADDITIVE: - break; - case Material::SHADERTYPE_VEGETATION: - break; - case Material::SHADERTYPE_WATER: - break; - case Material::SHADERTYPE_SPHERE_MAP: - break; - case Material::SHADERTYPE_NORMAL_MAP: - break; - case Material::SHADERTYPE_DETAIL_MAP: - break; - default: - Log::warn("DrawCalls", "Unknown material type: %d", Mat); - } + // Only take render info into account if the node is not static (animated) + // So they can have different animation + std::pair mesh_render_info(mesh->mb, + dynamic_cast(Node) == NULL ? mesh->m_render_info : NULL); + m_solid_pass_mesh[Mat][mesh_render_info].m_mesh = mesh; + m_solid_pass_mesh[Mat][mesh_render_info].m_instance_settings.emplace_back(Node, mesh->texture_trans, + (mesh->m_render_info && mesh->m_material ? + core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : + core::vector2df(0.0f, 0.0f))); } } } @@ -369,7 +343,8 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node, for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_mesh = mesh; - m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_scene_nodes.emplace_back(Node); + m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings + .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } } else @@ -425,21 +400,20 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node, { if (CVS->supportsIndirectInstancingRendering()) { - if (Mat == Material::SHADERTYPE_SPLATTING) + for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { - for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) + if (Mat == Material::SHADERTYPE_SPLATTING) { + //TODO: write instanced splatting rsm shader and remove this if core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix); } - } - else - { - for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) + else { m_reflective_shadow_map_mesh[Mat][mesh->mb].m_mesh = mesh; - m_reflective_shadow_map_mesh[Mat][mesh->mb].m_scene_nodes.emplace_back(Node); + m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings + .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } } } diff --git a/src/graphics/draw_policies.cpp b/src/graphics/draw_policies.cpp index cddd3ebdf..5971dd9fd 100644 --- a/src/graphics/draw_policies.cpp +++ b/src/graphics/draw_policies.cpp @@ -198,13 +198,8 @@ void GL3DrawPolicy::drawReflectiveShadowMap(const DrawCalls& draw_calls, void IndirectDrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const { #if !defined(USE_GLES2) - //TODO: find a way to add TextureMarix in instanced shaders, - //and remove these four lines - renderMeshes1stPass(); + //TODO: add instanced splatting solid shader renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - draw_calls.drawIndirectSolidFirstPass(); #endif //!defined(USE_GLES2) } @@ -215,13 +210,8 @@ void IndirectDrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls, const std::vector& prefilled_tex) const { #if !defined(USE_GLES2) - //TODO: find a way to add TextureMatrix in instanced shaders, - //and remove these four lines - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - + //TODO: add instanced splatting solid shader + renderMeshes2ndPass (handles, prefilled_tex); draw_calls.drawIndirectSolidSecondPass(prefilled_tex); #endif //!defined(USE_GLES2) } @@ -271,13 +261,8 @@ void IndirectDrawPolicy::drawReflectiveShadowMap(const DrawCalls& draw_calls, void MultidrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const { #if !defined(USE_GLES2) - //TODO: find a way to add TextureMarix in instanced shaders, - //and remove these four lines - renderMeshes1stPass(); + //TODO: add instanced splatting solid shader renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - draw_calls.multidrawSolidFirstPass(); #endif //!defined(USE_GLES2) } @@ -288,13 +273,8 @@ void MultidrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls, const std::vector& prefilled_tex) const { #if !defined(USE_GLES2) - //TODO: find a way to add TextureMarix in instanced shaders, - //and remove these four lines - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - renderMeshes2ndPass (handles, prefilled_tex); - + //TODO: add instanced splatting solid shader + renderMeshes2ndPass (handles, prefilled_tex); draw_calls.multidrawSolidSecondPass(handles); #endif //!defined(USE_GLES2) } diff --git a/src/graphics/materials.hpp b/src/graphics/materials.hpp index 27a371f0f..99e5d7cea 100644 --- a/src/graphics/materials.hpp +++ b/src/graphics/materials.hpp @@ -75,15 +75,11 @@ public: // ============================================================================ class InstancedObjectPass2Shader : public TextureShader { -private: - GLint m_color_change_location; - public: InstancedObjectPass2Shader() { loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_object_pass.vert", GL_FRAGMENT_SHADER, "instanced_object_pass2.frag"); - m_color_change_location = glGetUniformLocation(m_program, "color_change"); assignUniforms(); assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, 1, "SpecularMap", ST_NEAREST_FILTERED, @@ -92,12 +88,6 @@ public: 4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, 5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED); } // InstancedObjectPass2Shader - - virtual bool changeableColor(float hue = 0.0f, float min_sat = 0.0f) const OVERRIDE - { - glUniform2f(m_color_change_location, hue, min_sat); - return true; - } // changeableColor }; // InstancedObjectPass2Shader // ============================================================================ diff --git a/src/graphics/stk_mesh.cpp b/src/graphics/stk_mesh.cpp index 2f0a1ecbe..79cb9671d 100644 --- a/src/graphics/stk_mesh.cpp +++ b/src/graphics/stk_mesh.cpp @@ -399,19 +399,24 @@ void initTextures(GLMesh &mesh, Material::ShaderType mat) switch (mat) { default: + case Material::SHADERTYPE_VEGETATION: + setTexture(mesh, 0, true, getShaderTypeName(mat)); + setTexture(mesh, 1, false, getShaderTypeName(mat)); + break; case Material::SHADERTYPE_SOLID: case Material::SHADERTYPE_ALPHA_TEST: - case Material::SHADERTYPE_VEGETATION: case Material::SHADERTYPE_SPHERE_MAP: case Material::SHADERTYPE_SOLID_UNLIT: setTexture(mesh, 0, true, getShaderTypeName(mat)); setTexture(mesh, 1, false, getShaderTypeName(mat)); + setTexture(mesh, 7, false, getShaderTypeName(mat)); break; case Material::SHADERTYPE_DETAIL_MAP: case Material::SHADERTYPE_NORMAL_MAP: setTexture(mesh, 0, true, getShaderTypeName(mat)); setTexture(mesh, 1, false, getShaderTypeName(mat)); setTexture(mesh, 2, false, getShaderTypeName(mat)); + setTexture(mesh, 7, false, getShaderTypeName(mat)); break; case Material::SHADERTYPE_SPLATTING: setTexture(mesh, 0, true, getShaderTypeName(mat)); diff --git a/src/graphics/texture_shader.hpp b/src/graphics/texture_shader.hpp index b704ea603..f93125bd2 100644 --- a/src/graphics/texture_shader.hpp +++ b/src/graphics/texture_shader.hpp @@ -244,13 +244,6 @@ public: glDeleteSamplers(1, &m_sampler_ids[i]); } // ~TextureShader - /** Override this class and return true if a shader has changeable color. - */ - virtual bool changeableColor(float hue = 0.0f, float min_sat = 0.0f) const - { - return false; - } // changeableColor - }; // class TextureShader #endif