From 70b0fce50c1c2e7d5eb2bbeba18dc7228a4da7ea Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 13 Aug 2014 19:20:40 +0200 Subject: [PATCH] Add support for instanced normal map mesh. --- data/shaders/instanced_object_pass.vert | 6 +++++ data/shaders/normalmap.vert | 29 ------------------------- data/shaders/object_pass.vert | 6 +++++ src/graphics/render_geometry.cpp | 9 ++++++++ src/graphics/shaders.cpp | 21 +++++++++++++++++- src/graphics/shaders.hpp | 8 +++++++ src/graphics/stkinstancedscenenode.cpp | 3 +++ src/graphics/stkinstancedscenenode.hpp | 3 +++ 8 files changed, 55 insertions(+), 30 deletions(-) delete mode 100644 data/shaders/normalmap.vert diff --git a/data/shaders/instanced_object_pass.vert b/data/shaders/instanced_object_pass.vert index 409487993..7d94bd78a 100644 --- a/data/shaders/instanced_object_pass.vert +++ b/data/shaders/instanced_object_pass.vert @@ -3,6 +3,8 @@ layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec4 Color; layout(location = 3) in vec2 Texcoord; +layout(location = 5) in vec3 Tangent; +layout(location = 6) in vec3 Bitangent; layout(location = 7) in vec3 Origin; layout(location = 8) in vec3 Orientation; @@ -19,6 +21,8 @@ in vec3 Scale; #endif out vec3 nor; +out vec3 tangent; +out vec3 bitangent; out vec2 uv; out vec4 color; @@ -31,6 +35,8 @@ void main(void) mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix); gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.); nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; + tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz; + bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz; uv = Texcoord; color = Color.zyxw; } diff --git a/data/shaders/normalmap.vert b/data/shaders/normalmap.vert deleted file mode 100644 index 91bd707b7..000000000 --- a/data/shaders/normalmap.vert +++ /dev/null @@ -1,29 +0,0 @@ -uniform mat4 ModelMatrix; -uniform mat4 InverseModelMatrix; - -#if __VERSION__ >= 330 -layout(location = 0) in vec3 Position; -layout(location = 3) in vec2 Texcoord; -layout(location = 5) in vec3 Tangent; -layout(location = 6) in vec3 Bitangent; -#else -in vec3 Position; -in vec2 Texcoord; -in vec3 Tangent; -in vec3 Bitangent; -#endif - -out vec3 tangent; -out vec3 bitangent; -out vec2 uv; - -void main() -{ - mat4 ModelViewProjectionMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix; - mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix); - uv = Texcoord; - tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz; - bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz; - gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); - -} diff --git a/data/shaders/object_pass.vert b/data/shaders/object_pass.vert index dfd7d315f..fc4394118 100644 --- a/data/shaders/object_pass.vert +++ b/data/shaders/object_pass.vert @@ -13,6 +13,8 @@ layout(location = 1) in vec3 Normal; layout(location = 2) in vec4 Color; layout(location = 3) in vec2 Texcoord; layout(location = 4) in vec2 SecondTexcoord; +layout(location = 5) in vec3 Tangent; +layout(location = 6) in vec3 Bitangent; #else in vec3 Position; in vec3 Normal; @@ -22,6 +24,8 @@ in vec2 SecondTexcoord; #endif out vec3 nor; +out vec3 tangent; +out vec3 bitangent; out vec2 uv; out vec2 uv_bis; out vec4 color; @@ -34,6 +38,8 @@ void main(void) mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix); gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; + tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz; + bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz; uv = (TextureMatrix * vec4(Texcoord, 1., 1.)).xy; uv_bis = SecondTexcoord; } diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index baa6d6317..d104ee4b3 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -215,6 +215,7 @@ void IrrDriver::renderSolidFirstPass() ListInstancedMatDefault::getInstance()->clear(); ListInstancedMatAlphaRef::getInstance()->clear(); ListInstancedMatGrass::getInstance()->clear(); + ListInstancedMatNormalMap::getInstance()->clear(); m_scene_manager->drawAll(scene::ESNRP_SOLID); if (!UserConfigParams::m_dynamic_lights) @@ -245,6 +246,9 @@ void IrrDriver::renderSolidFirstPass() renderInstancedMeshes1stPass( TexUnits(TexUnit(MeshShader::InstancedGrassPass1Shader::getInstance()->TU_tex, true)), ListInstancedMatGrass::getInstance()); + renderInstancedMeshes1stPass( + TexUnits(TexUnit(MeshShader::InstancedNormalMapShader::getInstance()->TU_glossy, true), TexUnit(MeshShader::InstancedNormalMapShader::getInstance()->TU_normalmap, true)), + ListInstancedMatNormalMap::getInstance()); } } @@ -388,6 +392,9 @@ void IrrDriver::renderSolidSecondPass() renderInstancedMeshes2ndPass( TexUnits(TexUnit(MeshShader::InstancedObjectPass2Shader::getInstance()->TU_Albedo, true)), ListInstancedMatDefault::getInstance()); + renderInstancedMeshes2ndPass( + TexUnits(TexUnit(MeshShader::InstancedObjectPass2Shader::getInstance()->TU_Albedo, true)), + ListInstancedMatNormalMap::getInstance()); renderInstancedMeshes2ndPass( TexUnits(TexUnit(MeshShader::InstancedObjectRefPass2Shader::getInstance()->TU_Albedo, true)), ListInstancedMatAlphaRef::getInstance()); @@ -683,6 +690,7 @@ void IrrDriver::renderShadows() ListInstancedMatDefault::getInstance()->clear(); ListInstancedMatAlphaRef::getInstance()->clear(); ListInstancedMatGrass::getInstance()->clear(); + ListInstancedMatNormalMap::getInstance()->clear(); m_scene_manager->drawAll(scene::ESNRP_SOLID); std::vector noTexUnits; @@ -698,6 +706,7 @@ void IrrDriver::renderShadows() renderInstancedShadow(noTexUnits, ListInstancedMatDefault::getInstance()); renderInstancedShadow(std::vector{ MeshShader::InstancedRefShadowShader::getInstance()->TU_tex }, ListInstancedMatAlphaRef::getInstance()); renderInstancedShadow(std::vector{ MeshShader::InstancedGrassShadowShader::getInstance()->TU_tex }, ListInstancedMatGrass::getInstance()); + renderInstancedShadow(noTexUnits, ListInstancedMatNormalMap::getInstance()); glDisable(GL_POLYGON_OFFSET_FILL); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index b0e67d0d5..d6c378ae9 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -628,7 +628,7 @@ namespace MeshShader NormalMapShader::NormalMapShader() { Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/normalmap.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/normalmap.frag").c_str()); AssignUniforms("ModelMatrix", "InverseModelMatrix"); @@ -649,6 +649,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str()); TU_tex = 0; + AssignUniforms(); AssignTextureUnit(Program, TexUnit(TU_tex, "tex")); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); @@ -663,6 +664,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); TU_tex = 0; + AssignUniforms(); AssignTextureUnit(Program, TexUnit(TU_tex, "tex")); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); @@ -684,6 +686,23 @@ namespace MeshShader glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } + InstancedNormalMapShader::InstancedNormalMapShader() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/normalmap.frag").c_str()); + AssignUniforms(); + + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); + + TU_normalmap = 1; + TU_glossy = 0; + AssignTextureUnit(Program, TexUnit(TU_normalmap, "normalMap"), TexUnit(TU_glossy, "DiffuseForAlpha")); + } + // Solid Lit pass shaders ObjectPass2Shader::ObjectPass2Shader() { diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 43b1d31e8..e39208b1b 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -220,6 +220,14 @@ public: InstancedGrassPass1Shader(); }; +class InstancedNormalMapShader : public ShaderHelperSingleton +{ +public: + GLuint TU_glossy, TU_normalmap; + + InstancedNormalMapShader(); +}; + class ObjectPass2Shader : public ShaderHelperSingleton { public: diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index 81a1438de..9c3d5c2f9 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -160,4 +160,7 @@ void STKInstancedSceneNode::render() SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); for (auto mesh : MeshSolidMaterial[MAT_GRASS]) ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, windDir, cb->getPosition())); + + for (auto mesh : MeshSolidMaterial[MAT_NORMAL_MAP]) + ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9)); } diff --git a/src/graphics/stkinstancedscenenode.hpp b/src/graphics/stkinstancedscenenode.hpp index 0f07db057..d1063ca6d 100644 --- a/src/graphics/stkinstancedscenenode.hpp +++ b/src/graphics/stkinstancedscenenode.hpp @@ -13,6 +13,9 @@ class ListInstancedMatAlphaRef : public MeshList {}; +class ListInstancedMatNormalMap : public MeshList +{}; + class STKInstancedSceneNode : public irr::scene::CMeshSceneNode { protected: