Use instancing to expand shadows instead of GS

This commit is contained in:
vlj 2014-05-07 23:57:07 +02:00
parent d4b263761e
commit fd7399d983
5 changed files with 44 additions and 46 deletions

View File

@ -1,3 +1,12 @@
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
in vec3 Origin; in vec3 Origin;
in vec3 Orientation; in vec3 Orientation;
in vec3 Scale; in vec3 Scale;
@ -6,13 +15,15 @@ in vec3 Position;
in vec2 Texcoord; in vec2 Texcoord;
out vec2 tc; out vec2 tc;
out int layerId;
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void) void main(void)
{ {
layerId = gl_InstanceID & 3;
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
gl_Position = ModelMatrix * vec4(Position, 1.); gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
tc = Texcoord; tc = Texcoord;
} }

View File

@ -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; layout(triangles) in;
#endif layout(triangle_strip, max_vertices=4) out;
layout(triangle_strip, max_vertices=12) out;
in vec2 tc[3]; in vec2 tc[3];
in int layerId[3];
out vec2 uv; out vec2 uv;
void emitToLayer(int layerId) void main(void)
{ {
gl_Layer = layerId; gl_Layer = layerId[0];
for(int i=0; i<3; i++) for(int i=0; i<3; i++)
{ {
uv = tc[i]; uv = tc[i];
gl_Position = ShadowViewProjMatrixes[layerId] * gl_in[i].gl_Position; gl_Position = gl_in[i].gl_Position;
EmitVertex(); EmitVertex();
} }
EndPrimitive(); EndPrimitive();
} }
void main(void)
{
#if __VERSION__ >= 400
emitToLayer(gl_InvocationID);
#else
for (int j = 0; j<4; j++)
{
emitToLayer(j);
}
#endif
}

View File

@ -1,12 +1,23 @@
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
uniform mat4 ModelMatrix; uniform mat4 ModelMatrix;
in vec3 Position; in vec3 Position;
in vec2 Texcoord; in vec2 Texcoord;
out vec2 tc; out vec2 tc;
out int layerId;
void main(void) void main(void)
{ {
layerId = gl_InstanceID & 3;
tc = Texcoord; tc = Texcoord;
gl_Position = ModelMatrix * vec4(Position, 1.); gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
} }

View File

@ -56,18 +56,18 @@ void STKInstancedSceneNode::createGLMeshes()
isMaterialInitialized = false; isMaterialInitialized = false;
} }
template<typename T> template<typename T, unsigned divisor>
void setInstanceAttribPointer() void setInstanceAttribPointer()
{ {
glEnableVertexAttribArray(T::attrib_origin); glEnableVertexAttribArray(T::attrib_origin);
glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); 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); glEnableVertexAttribArray(T::attrib_orientation);
glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); 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); glEnableVertexAttribArray(T::attrib_scale);
glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); 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) void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
@ -80,12 +80,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader, 1>();
if (irr_driver->getGLSLVersion() >= 150) 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); 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); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedShadowShader>(); setInstanceAttribPointer<MeshShader::InstancedShadowShader, 4>();
} }
break; break;
case FPSM_ALPHA_REF_TEXTURE: case FPSM_ALPHA_REF_TEXTURE:
@ -94,12 +94,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader, 1>();
if (irr_driver->getGLSLVersion() >= 150) 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); 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); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedRefShadowShader>(); setInstanceAttribPointer<MeshShader::InstancedRefShadowShader, 4>();
} }
break; break;
case FPSM_GRASS: case FPSM_GRASS:
@ -108,7 +108,7 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedGrassPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedGrassPass1Shader, 1>();
break; break;
default: default:
return; return;
@ -122,19 +122,19 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, 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); MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedObjectPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectPass2Shader, 1>();
break; break;
case SM_ALPHA_REF_TEXTURE: case SM_ALPHA_REF_TEXTURE:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, 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); MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectRefPass2Shader, 1>();
break; break;
case SM_GRASS: case SM_GRASS:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, 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); 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); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedGrassPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedGrassPass2Shader, 1>();
break; break;
default: default:
return; return;
@ -220,7 +220,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
assert(mesh.vao_shadow_pass); assert(mesh.vao_shadow_pass);
glBindVertexArray(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) static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count)

View File

@ -710,7 +710,7 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
assert(mesh.vao_shadow_pass); assert(mesh.vao_shadow_pass);
glBindVertexArray(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) 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); assert(mesh.vao_shadow_pass);
glBindVertexArray(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) bool isObject(video::E_MATERIAL_TYPE type)