From 54b1ce39e4706c1b615e1e73119be2cdeb060721 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 13 Jul 2014 21:33:44 +0200 Subject: [PATCH] Add Grass shadows. For non instancing object. --- data/shaders/shadow.vert | 6 +++-- data/shaders/shadow_grass.vert | 33 ++++++++++++++++++++++++++ src/graphics/render.cpp | 23 ++++++++++++++++++ src/graphics/shaders.cpp | 43 ++++++++++++++++++---------------- src/graphics/shaders.hpp | 11 ++++----- 5 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 data/shaders/shadow_grass.vert diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index d1212e7ea..0e26cdb4f 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -8,8 +8,10 @@ layout (std140) uniform MatrixesData }; uniform mat4 ModelMatrix; +uniform vec3 windDir; layout(location = 0) in vec3 Position; +layout(location = 2) in vec4 Color; layout(location = 3) in vec2 Texcoord; #ifdef VSLayer @@ -24,10 +26,10 @@ void main(void) #ifdef VSLayer gl_Layer = gl_InstanceID & 3; uv = Texcoord; - gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); #else layerId = gl_InstanceID & 3; tc = Texcoord; - gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); #endif } diff --git a/data/shaders/shadow_grass.vert b/data/shaders/shadow_grass.vert new file mode 100644 index 000000000..d1212e7ea --- /dev/null +++ b/data/shaders/shadow_grass.vert @@ -0,0 +1,33 @@ +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; + +uniform mat4 ModelMatrix; + +layout(location = 0) in vec3 Position; +layout(location = 3) in vec2 Texcoord; + +#ifdef VSLayer +out vec2 uv; +#else +out vec2 tc; +out int layerId; +#endif + +void main(void) +{ +#ifdef VSLayer + gl_Layer = gl_InstanceID & 3; + uv = Texcoord; + gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); +#else + layerId = gl_InstanceID & 3; + tc = Texcoord; + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); +#endif +} diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index fe0d0b2f3..fb8b64b6f 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -933,6 +933,28 @@ void drawShadow(const T *Shader, const std::vector TextureUnits, const s } } +static void drawShadowGrass(const std::vector TextureUnits, const std::vector > &t) +{ + glUseProgram(MeshShader::GrassShadowShaderInstance->Program); + glBindVertexArray(getVAO(EVT_STANDARD)); + for (unsigned i = 0; i < t.size(); i++) + { + const GLMesh *mesh = std::get<0>(t[i]); + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh->PrimitiveType; + GLenum itype = mesh->IndexType; + size_t count = mesh->IndexCount; + for (unsigned j = 0; j < TextureUnits.size(); j++) + { + compressTexture(mesh->textures[j], true); + setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + } + + MeshShader::GrassShadowShaderInstance->setUniforms(std::get<1>(t[i]), std::get<3>(t[i])); + glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, 4, mesh->vaoBaseVertex); + } +} + template void drawRSM(const core::matrix4 & rsm_matrix, const std::vector TextureUnits, const std::vector >&t) { @@ -968,6 +990,7 @@ void IrrDriver::renderShadows() drawShadow(MeshShader::ShadowShaderInstance, {}, ListDefault2TCoordG::Arguments); drawShadow(MeshShader::ShadowShaderInstance, {}, ListNormalG::Arguments); drawShadow(MeshShader::RefShadowShaderInstance, { MeshShader::RefShadowShaderInstance->TU_tex }, ListAlphaRefG::Arguments); + drawShadowGrass({ MeshShader::GrassShadowShaderInstance->TU_tex }, ListGrassG::Arguments); glDisable(GL_POLYGON_OFFSET_FILL); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 0fb525c7f..6c0a95495 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -354,7 +354,7 @@ void Shaders::loadShaders() MeshShader::InstancedShadowShader::init(); MeshShader::RefShadowShaderInstance = new MeshShader::RefShadowShader(); MeshShader::InstancedRefShadowShader::init(); - MeshShader::GrassShadowShader::init(); + MeshShader::GrassShadowShaderInstance = new MeshShader::GrassShadowShader(); MeshShader::SkyboxShader::init(); MeshShader::ViewFrustrumShader::init(); ParticleShader::FlipParticleRender::init(); @@ -1130,30 +1130,33 @@ namespace MeshShader glUniform1i(uniform_tex, TU_tex); } - GLuint GrassShadowShader::Program; - GLuint GrassShadowShader::uniform_MVP; - GLuint GrassShadowShader::uniform_tex; - GLuint GrassShadowShader::uniform_windDir; - - void GrassShadowShader::init() + GrassShadowShader::GrassShadowShader() { - return; - Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/grass_pass.vert").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_windDir = glGetUniformLocation(Program, "windDir"); + // Geometry shader needed + if (irr_driver->getGLSLVersion() < 150) + return; + if (irr_driver->hasVSLayerExtension()) + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow_grass.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } + else + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow_grass.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } + AssignUniforms(Program, uniforms, { "ModelMatrix", "windDir" }); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); + TU_tex = 0; + + AssignTextureUnit(Program, { { TU_tex, "tex" } }); } - void GrassShadowShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_tex) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_tex, TU_tex); - glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); - } + GrassShadowShader *GrassShadowShaderInstance; GLuint DisplaceMaskShader::Program; GLuint DisplaceMaskShader::uniform_MVP; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 3b47fede5..5f9bf22d8 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -383,16 +383,15 @@ public: static void setUniforms(unsigned TU_tex); }; -class GrassShadowShader +class GrassShadowShader : public ShaderHelper { public: - static GLuint Program; - static GLuint uniform_MVP, uniform_tex, uniform_windDir; - - static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_tex); + GLuint TU_tex; + GrassShadowShader(); }; +extern GrassShadowShader *GrassShadowShaderInstance; + class DisplaceMaskShader { public: