Avoid using else if in skinning vertex shader

This commit is contained in:
Benau
2016-12-09 14:16:30 +08:00
parent 21d9117b2d
commit b7e047b4c1
9 changed files with 37 additions and 56 deletions

View File

@@ -1,5 +1,6 @@
#ifndef HEADER_TXT
#define HEADER_TXT
#define MAX_BONES 1000
#ifdef UBO_DISABLED
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
@@ -66,7 +67,7 @@ layout (std140) uniform LightingData
layout (std140) uniform SkinningData
{
mat4 joint_matrices[1000];
mat4 joint_matrices[MAX_BONES];
};
#endif

View File

@@ -16,7 +16,7 @@ layout(location = 12) in sampler2D SecondHandle;
layout(location = 13) in sampler2D ThirdHandle;
layout(location = 14) in sampler2D FourthHandle;
#endif
layout(location = 15) in uint skinning_offset;
layout(location = 15) in int skinning_offset;
out vec3 nor;
out vec3 tangent;
@@ -42,62 +42,36 @@ void main(void)
vec4 idle_normal = vec4(Normal, 0.);
vec4 skinned_position = vec4(0.);
vec4 skinned_normal = vec4(0.);
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
vec4 single_bone_influenced_position;
vec4 single_bone_influenced_normal;
if (Joint[0] >= 0)
{
single_bone_influenced_position = joint_matrices[Joint[0] + skinning_offset] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[Joint[0] + skinning_offset] * idle_normal;
}
else
{
single_bone_influenced_position = idle_position;
single_bone_influenced_normal = idle_normal;
}
// First bone:
single_bone_influenced_position = joint_matrices[clamp(Joint[0] + skinning_offset, 0, MAX_BONES)] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[clamp(Joint[0] + skinning_offset, 0, MAX_BONES)] * idle_normal;
skinned_position += Weight[0] * single_bone_influenced_position;
skinned_normal += Weight[0] * single_bone_influenced_normal;
if (Joint[1] >= 0)
{
single_bone_influenced_position= joint_matrices[Joint[1] + skinning_offset] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[Joint[1] + skinning_offset] * idle_normal;
}
else
{
single_bone_influenced_position = idle_position;
single_bone_influenced_normal = idle_normal;
}
// Second bone:
single_bone_influenced_position = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_normal;
skinned_position += Weight[1] * single_bone_influenced_position;
skinned_normal += Weight[1] * single_bone_influenced_normal;
if (Joint[2] >= 0)
{
single_bone_influenced_position = joint_matrices[Joint[2] + skinning_offset] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[Joint[2] + skinning_offset] * idle_normal;
}
else
{
single_bone_influenced_position = idle_position;
single_bone_influenced_normal = idle_normal;
}
// Third bone:
single_bone_influenced_position = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_normal;
skinned_position += Weight[2] * single_bone_influenced_position;
skinned_normal += Weight[2] * single_bone_influenced_normal;
if (Joint[3] >= 0)
{
single_bone_influenced_position = joint_matrices[Joint[3] + skinning_offset] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[Joint[3] + skinning_offset] * idle_normal;
}
else
{
single_bone_influenced_position = idle_position;
single_bone_influenced_normal = idle_normal;
}
// Fourth bone:
single_bone_influenced_position = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
single_bone_influenced_normal = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_normal;
skinned_position += Weight[3] * single_bone_influenced_position;
skinned_normal += Weight[3] * single_bone_influenced_normal;

View File

@@ -1439,7 +1439,7 @@ void CSkinnedMesh::convertForSkinning()
influence = reported_weight[j];
else
{
influence.joint_idx = -1;
influence.joint_idx = -1000;
influence.weight = remaining_weight;
}
remaining_weight -= influence.weight;

View File

@@ -29,7 +29,7 @@
#include <array>
#include <unordered_map>
typedef STK::Tuple<scene::ISceneNode*, core::vector2df, core::vector2df, uint32_t> InstanceSettings;
typedef STK::Tuple<scene::ISceneNode*, core::vector2df, core::vector2df, int32_t> InstanceSettings;
struct InstanceList
{

View File

@@ -246,13 +246,13 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
uint32_t skinning_offset = 0;
int32_t skinning_offset = 0;
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(Node);
if (am && am->useHardwareSkinning() &&
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
{
skinning_offset = getSkinningOffset();
skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
m_mesh_for_skinning.insert(am);
am->setSkinningOffset(skinning_offset * 16 * sizeof(float));
}
@@ -883,7 +883,7 @@ void DrawCalls::multidrawGlow() const
#endif // !defined(USE_GLES2)
// ----------------------------------------------------------------------------
uint32_t DrawCalls::getSkinningOffset() const
int32_t DrawCalls::getSkinningOffset() const
{
return std::accumulate(m_mesh_for_skinning.begin(),
m_mesh_for_skinning.end(), 0, []

View File

@@ -107,7 +107,7 @@ public:
void drawIndirectGlow() const;
void multidrawGlow() const;
void renderBoundingBoxes();
uint32_t getSkinningOffset() const;
int32_t getSkinningOffset() const;
};
#endif //HEADER_DRAW_CALLS_HPP

View File

@@ -18,6 +18,8 @@
#include "graphics/shared_gpu_objects.hpp"
#include "graphics/central_settings.hpp"
#include "matrix4.h"
GLuint SharedGPUObjects::m_billboard_vbo;
GLuint SharedGPUObjects::m_sky_tri_vbo;
GLuint SharedGPUObjects::m_frustrum_vbo;
@@ -171,10 +173,14 @@ void SharedGPUObjects::initLightingDataUBO()
void SharedGPUObjects::initSkinningUBO()
{
assert(CVS->isARBUniformBufferObjectUsable());
irr::core::matrix4 m;
glGenBuffers(1, &m_skinning_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, m_skinning_ubo);
glBufferData(GL_UNIFORM_BUFFER, 1000 * 16 * sizeof(float), 0,
GL_STREAM_DRAW);
// Reserve a identity matrix for non moving mesh in animated model used by
// vertex shader calculation
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * sizeof(float), m.pointer());
glBindBuffer(GL_UNIFORM_BUFFER, 0);
} // initSkinningUBO

View File

@@ -162,7 +162,7 @@ void VAOInstanceUtil<InstanceDataSingleTex>::SetVertexAttrib()
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceDataSingleTex), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisorARB(11, 1);
glEnableVertexAttribArray(15);
glVertexAttribIPointer(15, 1, GL_UNSIGNED_INT, sizeof(InstanceDataSingleTex), (GLvoid*)(11 * sizeof(float)));
glVertexAttribIPointer(15, 1, GL_INT, sizeof(InstanceDataSingleTex), (GLvoid*)(11 * sizeof(float)));
glVertexAttribDivisorARB(15, 1);
}
@@ -204,7 +204,7 @@ void VAOInstanceUtil<InstanceDataFourTex>::SetVertexAttrib()
glVertexAttribIPointer(14, 2, GL_UNSIGNED_INT, sizeof(InstanceDataFourTex), (GLvoid*)(13 * sizeof(float) + 6 * sizeof(unsigned)));
glVertexAttribDivisorARB(14, 1);
glEnableVertexAttribArray(15);
glVertexAttribIPointer(15, 1, GL_UNSIGNED_INT, sizeof(InstanceDataFourTex), (GLvoid*)(13 * sizeof(float) + 8 * sizeof(unsigned)));
glVertexAttribIPointer(15, 1, GL_INT, sizeof(InstanceDataFourTex), (GLvoid*)(13 * sizeof(float) + 8 * sizeof(unsigned)));
glVertexAttribDivisorARB(15, 1);
}

View File

@@ -62,7 +62,7 @@ struct InstanceDataSingleTex
float Z;
} Scale;
uint64_t Texture;
uint32_t skinning_offset;
int32_t skinning_offset;
#ifdef WIN32
};
#else
@@ -136,7 +136,7 @@ struct InstanceDataFourTex
uint64_t SecondTexture;
uint64_t ThirdTexture;
uint64_t FourthTexture;
uint32_t skinning_offset;
int32_t skinning_offset;
#ifdef WIN32
};
#else