From 4c9d1888f89fc84baa2059640cb538b7413a5ce0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 20 Jun 2014 22:52:19 +0200 Subject: [PATCH 1/3] Factorize transparent mesh rendering. --- src/graphics/render.cpp | 23 ++++++++++++++++++++ src/graphics/stkanimatedmesh.cpp | 28 ++++++------------------ src/graphics/stkmesh.hpp | 19 ++++++++++++++++ src/graphics/stkmeshscenenode.cpp | 36 +++++++++++-------------------- 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index b7647a38c..89a1b46aa 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -648,7 +648,30 @@ void IrrDriver::renderTransparent() glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glDisable(GL_CULL_FACE); + TransparentMeshes::reset(); + TransparentMeshes::reset(); m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT); + + if (World::getWorld() && World::getWorld()->isFogEnabled()) + { + glUseProgram(MeshShader::TransparentFogShader::Program); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) + drawTransparentFogObject(*TransparentMeshes::MeshSet[i], TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix); + glBlendFunc(GL_ONE, GL_ONE); + for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) + drawTransparentFogObject(*TransparentMeshes::MeshSet[i], TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix); + } + else + { + glUseProgram(MeshShader::TransparentShader::Program); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) + drawTransparentObject(*TransparentMeshes::MeshSet[i], TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix); + glBlendFunc(GL_ONE, GL_ONE); + for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) + drawTransparentObject(*TransparentMeshes::MeshSet[i], TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix); + } } void IrrDriver::renderParticles() diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 91769e262..b4464a46c 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -227,30 +227,16 @@ void STKAnimatedMesh::render() glUseProgram(MeshShader::BubbleShader::Program); GLMesh* mesh; - for_in(mesh, TransparentMesh[TM_BUBBLE]) - drawBubble(*mesh, ModelViewProjectionMatrix); - - if (World::getWorld() != NULL && World::getWorld()->isFogEnabled()) + for_in(mesh, TransparentMesh[TM_DEFAULT]) { - if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) - glUseProgram(MeshShader::TransparentFogShader::Program); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for_in(mesh, TransparentMesh[TM_DEFAULT]) - drawTransparentFogObject(*mesh, ModelViewProjectionMatrix, mesh->TextureMatrix); - glBlendFunc(GL_ONE, GL_ONE); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) - drawTransparentFogObject(*mesh, ModelViewProjectionMatrix, mesh->TextureMatrix); + TransparentMeshes::MeshSet.push_back(mesh); + TransparentMeshes::MVPSet.push_back(ModelViewProjectionMatrix); } - else + + for_in(mesh, TransparentMesh[TM_ADDITIVE]) { - if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) - glUseProgram(MeshShader::TransparentShader::Program); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for_in(mesh, TransparentMesh[TM_DEFAULT]) - drawTransparentObject(*mesh, ModelViewProjectionMatrix, mesh->TextureMatrix); - glBlendFunc(GL_ONE, GL_ONE); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) - drawTransparentObject(*mesh, ModelViewProjectionMatrix, mesh->TextureMatrix); + TransparentMeshes::MeshSet.push_back(mesh); + TransparentMeshes::MVPSet.push_back(ModelViewProjectionMatrix); } return; } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index a7e0fb19d..c16e075b0 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -147,6 +147,25 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix); void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix); +template +class TransparentMeshes +{ +public: + static std::vector MeshSet; + static std::vector MVPSet; + + static void reset() + { + MeshSet.clear(); + MVPSet.clear(); + } +}; + +template +std::vector TransparentMeshes::MeshSet; +template +std::vector TransparentMeshes::MVPSet; + // Forward pass (for transparents meshes) void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 0ecf8586d..07d9b0bd0 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -440,33 +440,23 @@ void STKMeshSceneNode::render() ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation); GLMesh* mesh; + + for_in(mesh, TransparentMesh[TM_DEFAULT]) + { + TransparentMeshes::MeshSet.push_back(mesh); + TransparentMeshes::MVPSet.push_back(ModelViewProjectionMatrix); + } + + for_in(mesh, TransparentMesh[TM_ADDITIVE]) + { + TransparentMeshes::MeshSet.push_back(mesh); + TransparentMeshes::MVPSet.push_back(ModelViewProjectionMatrix); + } + if (!TransparentMesh[TM_BUBBLE].empty()) glUseProgram(MeshShader::BubbleShader::Program); for_in(mesh, TransparentMesh[TM_BUBBLE]) drawBubble(*mesh, ModelViewProjectionMatrix); - - if (World::getWorld() ->isFogEnabled()) - { - if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) - glUseProgram(MeshShader::TransparentFogShader::Program); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for_in(mesh, TransparentMesh[TM_DEFAULT]) - drawTransparentFogObject(*mesh, ModelViewProjectionMatrix, (*mesh).TextureMatrix); - glBlendFunc(GL_ONE, GL_ONE); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) - drawTransparentFogObject(*mesh, ModelViewProjectionMatrix, (*mesh).TextureMatrix); - } - else - { - if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) - glUseProgram(MeshShader::TransparentShader::Program); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for_in(mesh, TransparentMesh[TM_DEFAULT]) - drawTransparentObject(*mesh, ModelViewProjectionMatrix, (*mesh).TextureMatrix); - glBlendFunc(GL_ONE, GL_ONE); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) - drawTransparentObject(*mesh, ModelViewProjectionMatrix, (*mesh).TextureMatrix); - } return; } From cb161a2774fda07412a0c0ad8873034cdca7e8bb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 20 Jun 2014 22:56:56 +0200 Subject: [PATCH 2/3] Remove code never executed. --- src/graphics/stkmeshscenenode.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 07d9b0bd0..4f97ed8c7 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -209,33 +209,9 @@ void STKMeshSceneNode::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type) { switch (type) { - case SM_SPHEREMAP: - drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); - break; - case SM_SPLATTING: - drawSplatting(mesh, ModelViewProjectionMatrix); - break; - case SM_ALPHA_REF_TEXTURE: - drawObjectRefPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); - break; case SM_GRASS: drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir); break; - case SM_RIMLIT: - drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, core::matrix4::EM4CONST_IDENTITY); - break; - case SM_UNLIT: - drawObjectUnlit(mesh, ModelViewProjectionMatrix); - break; - case SM_DETAILS: - drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); - break; - case SM_UNTEXTURED: - drawUntexturedObject(mesh, ModelViewProjectionMatrix); - break; - case SM_DEFAULT: - drawObjectPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); - break; default: assert(0 && "Wrong shaded material"); break; From 71969acd228393dfbe6dc4798e0faeef9b045041 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 20 Jun 2014 23:10:31 +0200 Subject: [PATCH 3/3] Use a precomputed invmatrix in gi.frag (General) matrix inversion is costly, it's better if it's done a single time on cpu. Improve performance. --- data/shaders/gi.frag | 3 ++- src/graphics/post_processing.cpp | 4 +++- src/graphics/shaders.cpp | 5 ++++- src/graphics/shaders.hpp | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/data/shaders/gi.frag b/data/shaders/gi.frag index 92f9e0804..b6983b4f2 100644 --- a/data/shaders/gi.frag +++ b/data/shaders/gi.frag @@ -12,6 +12,7 @@ uniform sampler3D SHB; uniform float R_wcs = 10.; uniform vec3 extents; uniform mat4 RHMatrix; +uniform mat4 InvRHMatrix; layout (std140) uniform MatrixesData { @@ -55,7 +56,7 @@ void main() if (depth==1.0) discard; vec4 pos_screen_space = getPosFromUVDepth(vec3(uv, depth), InverseProjectionMatrix); - vec4 tmp = (inverse(RHMatrix) * InverseViewMatrix * pos_screen_space); + vec4 tmp = (InvRHMatrix * InverseViewMatrix * pos_screen_space); vec3 pos = tmp.xyz / tmp.w; vec3 normal_screen_space = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); vec3 normal = (transpose(ViewMatrix) * vec4(normal_screen_space, 0.)).xyz; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index fd4fc0eed..648e76301 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -244,6 +244,8 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, GLuint shr, GLuint shg, GLuint shb) { + core::matrix4 InvRHMatrix; + RHMatrix.getInverse(InvRHMatrix); glDisable(GL_DEPTH_TEST); glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program); glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao); @@ -267,7 +269,7 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3 } setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST); setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); - FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, rh_extend, 3, 4, 0, 1, 2); + FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, InvRHMatrix, rh_extend, 3, 4, 0, 1, 2); glDrawArrays(GL_TRIANGLES, 0, 3); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 14cd9035d..1744ce8ad 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -2400,6 +2400,7 @@ namespace FullScreenShader GLuint GlobalIlluminationReconstructionShader::uniform_SHB; GLuint GlobalIlluminationReconstructionShader::uniform_extents; GLuint GlobalIlluminationReconstructionShader::uniform_RHMatrix; + GLuint GlobalIlluminationReconstructionShader::uniform_InvRHMatrix; GLuint GlobalIlluminationReconstructionShader::vao; void GlobalIlluminationReconstructionShader::init() @@ -2415,15 +2416,17 @@ namespace FullScreenShader uniform_SHG = glGetUniformLocation(Program, "SHG"); uniform_SHB = glGetUniformLocation(Program, "SHB"); uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix"); + uniform_InvRHMatrix = glGetUniformLocation(Program, "InvRHMatrix"); uniform_extents = glGetUniformLocation(Program, "extents"); vao = createFullScreenVAO(Program); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } - void GlobalIlluminationReconstructionShader::setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB) + void GlobalIlluminationReconstructionShader::setUniforms(const core::matrix4 &RHMatrix, const core::matrix4 &InvRHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB) { glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer()); + glUniformMatrix4fv(uniform_InvRHMatrix, 1, GL_FALSE, InvRHMatrix.pointer()); glUniform1i(uniform_ntex, TU_ntex); glUniform1i(uniform_dtex, TU_dtex); glUniform1i(uniform_SHR, TU_SHR); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 551275678..53089372f 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -624,11 +624,11 @@ class GlobalIlluminationReconstructionShader { public: static GLuint Program; - static GLuint uniform_ntex, uniform_dtex, uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix; + static GLuint uniform_ntex, uniform_dtex, uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix, uniform_InvRHMatrix; static GLuint vao; static void init(); - static void setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB); + static void setUniforms(const core::matrix4 &RHMatrix, const core::matrix4 &InvRHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB); }; class Gaussian17TapHShader