From fd7399d98334d293315460e082947f7461f9703b Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 7 May 2014 23:57:07 +0200 Subject: [PATCH] Use instancing to expand shadows instead of GS --- data/shaders/instanciedshadow.vert | 13 +++++++++- data/shaders/shadow.geom | 34 ++++---------------------- data/shaders/shadow.vert | 13 +++++++++- src/graphics/stkinstancedscenenode.cpp | 26 ++++++++++---------- src/graphics/stkmesh.cpp | 4 +-- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/data/shaders/instanciedshadow.vert b/data/shaders/instanciedshadow.vert index 0c2377b93..fbc28db16 100644 --- a/data/shaders/instanciedshadow.vert +++ b/data/shaders/instanciedshadow.vert @@ -1,3 +1,12 @@ +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; + in vec3 Origin; in vec3 Orientation; in vec3 Scale; @@ -6,13 +15,15 @@ in vec3 Position; in vec2 Texcoord; out vec2 tc; +out int layerId; mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); void main(void) { + layerId = gl_InstanceID & 3; mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); - gl_Position = ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); tc = Texcoord; } \ No newline at end of file diff --git a/data/shaders/shadow.geom b/data/shaders/shadow.geom index e57567f84..4824679d7 100644 --- a/data/shaders/shadow.geom +++ b/data/shaders/shadow.geom @@ -1,43 +1,19 @@ -layout (std140) uniform MatrixesData -{ - mat4 ViewMatrix; - mat4 ProjectionMatrix; - mat4 InverseViewMatrix; - mat4 InverseProjectionMatrix; - mat4 ShadowViewProjMatrixes[4]; -}; - -#if __VERSION__ >= 400 -layout(triangles, invocations=4) in; -#else layout(triangles) in; -#endif -layout(triangle_strip, max_vertices=12) out; +layout(triangle_strip, max_vertices=4) out; in vec2 tc[3]; +in int layerId[3]; out vec2 uv; -void emitToLayer(int layerId) +void main(void) { - gl_Layer = layerId; + gl_Layer = layerId[0]; for(int i=0; i<3; i++) { uv = tc[i]; - gl_Position = ShadowViewProjMatrixes[layerId] * gl_in[i].gl_Position; + gl_Position = gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); } - -void main(void) -{ -#if __VERSION__ >= 400 - emitToLayer(gl_InvocationID); -#else - for (int j = 0; j<4; j++) - { - emitToLayer(j); - } -#endif -} diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index 1c45d5fdc..aafe186ce 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -1,12 +1,23 @@ +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; + uniform mat4 ModelMatrix; in vec3 Position; in vec2 Texcoord; out vec2 tc; +out int layerId; void main(void) { + layerId = gl_InstanceID & 3; tc = Texcoord; - gl_Position = ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); } diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index 146a28e70..b57ff462d 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -56,18 +56,18 @@ void STKInstancedSceneNode::createGLMeshes() isMaterialInitialized = false; } -template +template void setInstanceAttribPointer() { glEnableVertexAttribArray(T::attrib_origin); glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); - glVertexAttribDivisor(T::attrib_origin, 1); + glVertexAttribDivisor(T::attrib_origin, divisor); glEnableVertexAttribArray(T::attrib_orientation); glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(T::attrib_orientation, 1); + glVertexAttribDivisor(T::attrib_orientation, divisor); glEnableVertexAttribArray(T::attrib_scale); glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(T::attrib_scale, 1); + glVertexAttribDivisor(T::attrib_scale, divisor); } void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) @@ -80,12 +80,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); if (irr_driver->getGLSLVersion() >= 150) { mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); } break; case FPSM_ALPHA_REF_TEXTURE: @@ -94,12 +94,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); if (irr_driver->getGLSLVersion() >= 150) { mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); } break; case FPSM_GRASS: @@ -108,7 +108,7 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; default: return; @@ -122,19 +122,19 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; case SM_ALPHA_REF_TEXTURE: mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; case SM_GRASS: mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, MeshShader::InstancedGrassPass2Shader::attrib_normal, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; default: return; @@ -220,7 +220,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElementsInstanced(ptype, count, itype, 0, instance_count); + glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); } static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 981da15b9..e6a8db142 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -710,7 +710,7 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); + glDrawElementsInstanced(ptype, count, itype, 0, 4); } void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) @@ -724,7 +724,7 @@ void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); + glDrawElementsInstanced(ptype, count, itype, 0, 4); } bool isObject(video::E_MATERIAL_TYPE type)