Allow GL3 to have hardware skinning

This commit is contained in:
Benau 2016-12-09 18:41:13 +08:00
parent b7e047b4c1
commit 76e070b709
7 changed files with 128 additions and 73 deletions

View File

@ -1,81 +1,86 @@
// SuperTuxKart - a fun racing game with go-kart #ifdef GL_ES
// Copyright (C) 2013 the SuperTuxKart team uniform mat4 ModelMatrix;
// uniform mat4 InverseModelMatrix;
// This program is free software; you can redistribute it and/or uniform vec2 texture_trans;
// modify it under the terms of the GNU General Public License #else
// as published by the Free Software Foundation; either version 3 uniform mat4 ModelMatrix =
// of the License, or (at your option) any later version. mat4(1., 0., 0., 0.,
// 0., 1., 0., 0.,
// This program is distributed in the hope that it will be useful, 0., 0., 1., 0.,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 0., 0., 0., 1.);
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the uniform mat4 InverseModelMatrix =
// GNU General Public License for more details. mat4(1., 0., 0., 0.,
// 0., 1., 0., 0.,
// You should have received a copy of the GNU General Public License 0., 0., 1., 0.,
// along with this program; if not, write to the Free Software 0., 0., 0., 1.);
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// skinning.vert uniform vec2 texture_trans = vec2(0., 0.);
#version 330 compatibility #endif
#define MAX_JOINT_NUM 36 uniform int skinning_offset;
#define MAX_LIGHT_NUM 8
uniform mat4 JointTransform[MAX_JOINT_NUM]; layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec4 Data1;
layout(location = 4) in vec4 Data2;
layout(location = 5) in ivec4 Joint;
layout(location = 6) in vec4 Weight;
void main() out vec3 nor;
out vec3 tangent;
out vec3 bitangent;
out vec2 uv;
out vec4 color;
#stk_include "utils/getworldmatrix.vert"
void main(void)
{ {
int index; mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
vec4 ecPos; vec4 idle_position = vec4(Position, 1.);
vec3 normal; vec4 idle_normal = vec4(Normal, 0.);
vec3 light_dir; vec4 skinned_position = vec4(0.);
float n_dot_l; vec4 skinned_normal = vec4(0.);
float dist;
mat4 ModelTransform = gl_ModelViewProjectionMatrix; // 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;
index = int(gl_Color.r * 255.99); // First bone:
mat4 vertTran = JointTransform[index - 1]; 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;
index = int(gl_Color.g * 255.99); // Second bone:
if(index > 0) single_bone_influenced_position = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_position;
vertTran += JointTransform[index - 1]; 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;
index = int(gl_Color.b * 255.99); // Third bone:
if(index > 0) single_bone_influenced_position = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_position;
vertTran += JointTransform[index - 1]; 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;
index = int(gl_Color.a * 255.99); // Fourth bone:
if(index > 0) single_bone_influenced_position = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_position;
vertTran += JointTransform[index - 1]; 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;
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex; gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * skinned_position;
// Keep orthogonality
nor = (TransposeInverseModelView * skinned_normal).xyz;
// Keep direction
tangent = (ViewMatrix * ModelMatrix * vec4(Data1.z, Data1.w, Data2.x, 0.)).xyz;
bitangent = (ViewMatrix * ModelMatrix * vec4(Data2.y, Data2.z, Data2.w, 0.)).xyz;
normal = (vertTran * vec4(gl_Normal, 0.0)).xyz; uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
normal = normalize(gl_NormalMatrix * normal); color = Color.zyxw;
gl_FrontColor = vec4(0,0,0,0);
for(int i = 0;i < MAX_LIGHT_NUM;i++)
{
light_dir = vec3(gl_LightSource[i].position-ecPos);
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
dist = length(light_dir);
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
}
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
ModelTransform *= vertTran;
gl_Position = ModelTransform * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
/*
// Reflections.
vec3 r = reflect( ecPos.xyz , normal );
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
gl_TexCoord[1].s = r.x/m + 0.5;
gl_TexCoord[1].t = r.y/m + 0.5;
*/
} }

View File

@ -46,6 +46,7 @@ void DrawCalls::clearLists()
ListDisplacement::getInstance()->clear(); ListDisplacement::getInstance()->clear();
ListMatDefault::getInstance()->clear(); ListMatDefault::getInstance()->clear();
ListSkinnedSolid::getInstance()->clear();
ListMatAlphaRef::getInstance()->clear(); ListMatAlphaRef::getInstance()->clear();
ListMatSphereMap::getInstance()->clear(); ListMatSphereMap::getInstance()->clear();
ListMatDetails::getInstance()->clear(); ListMatDetails::getInstance()->clear();
@ -305,6 +306,12 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f))); core::vector2df(0.0f, 0.0f)));
break; break;
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
ListSkinnedSolid::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)), skinning_offset);
break;
case Material::SHADERTYPE_ALPHA_TEST: case Material::SHADERTYPE_ALPHA_TEST:
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ? (mesh->m_render_info && mesh->m_material ?

View File

@ -176,6 +176,7 @@ void drawRSM(const core::matrix4 & rsm_matrix)
void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
{ {
renderMeshes1stPass<DefaultMaterial, 2, 1>(); renderMeshes1stPass<DefaultMaterial, 2, 1>();
renderMeshes1stPass<SkinnedSolid, 5, 2, 1>();
renderMeshes1stPass<SplattingMat, 2, 1>(); renderMeshes1stPass<SplattingMat, 2, 1>();
renderMeshes1stPass<UnlitMat, 3, 2, 1>(); renderMeshes1stPass<UnlitMat, 3, 2, 1>();
renderMeshes1stPass<AlphaRef, 3, 2, 1>(); renderMeshes1stPass<AlphaRef, 3, 2, 1>();
@ -191,6 +192,7 @@ void GL3DrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
const std::vector<GLuint>& prefilled_tex) const const std::vector<GLuint>& prefilled_tex) const
{ {
renderMeshes2ndPass<DefaultMaterial, 4, 3, 1> (handles, prefilled_tex); renderMeshes2ndPass<DefaultMaterial, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<SkinnedSolid, 5, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<AlphaRef, 4, 3, 1> (handles, prefilled_tex); renderMeshes2ndPass<AlphaRef, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<UnlitMat, 3, 1 > (handles, prefilled_tex); renderMeshes2ndPass<UnlitMat, 3, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex); renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);

View File

@ -655,8 +655,8 @@ struct SkinnedSolid
typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader; typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader;
//typedef InstancedShadowShader InstancedShadowPassShader; //typedef InstancedShadowShader InstancedShadowPassShader;
//typedef CInstancedRSMShader InstancedRSMShader; //typedef CInstancedRSMShader InstancedRSMShader;
//typedef Shaders::ObjectPass1Shader FirstPassShader; typedef Shaders::SkinnedMeshPass1Shader FirstPassShader;
//typedef Shaders::ObjectPass2Shader SecondPassShader; typedef Shaders::SkinnedMeshPass2Shader SecondPassShader;
//typedef ShadowShader ShadowPassShader; //typedef ShadowShader ShadowPassShader;
//typedef CRSMShader RSMShader; //typedef CRSMShader RSMShader;
typedef ListSkinnedSolid List; typedef ListSkinnedSolid List;
@ -668,7 +668,7 @@ struct SkinnedSolid
static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures; static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures;
static const STK::Tuple<> ShadowTextures; static const STK::Tuple<> ShadowTextures;
static const STK::Tuple<size_t> RSMTextures; static const STK::Tuple<size_t> RSMTextures;
}; // struct DefaultMaterial }; // struct SkinnedSolid
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
struct DefaultMaterial struct DefaultMaterial

View File

@ -359,6 +359,29 @@ Shaders::ObjectPass2Shader::ObjectPass2Shader()
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED); 5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // ObjectPass2Shader } // ObjectPass2Shader
// ============================================================================
Shaders::SkinnedMeshPass1Shader::SkinnedMeshPass1Shader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert",
GL_FRAGMENT_SHADER, "object_pass1.frag");
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // SkinnedMeshPass1Shader
// ============================================================================
Shaders::SkinnedMeshPass2Shader::SkinnedMeshPass2Shader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert",
GL_FRAGMENT_SHADER, "object_pass2.frag");
assignUniforms("ModelMatrix", "texture_trans", "color_change", "skinning_offset");
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
1, "SpecularMap", ST_NEAREST_FILTERED,
2, "SSAO", ST_BILINEAR_FILTERED,
3, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED,
4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // SkinnedMeshPass2Shader
// ============================================================================ // ============================================================================
Shaders::TransparentShader::TransparentShader() Shaders::TransparentShader::TransparentShader()
{ {

View File

@ -153,6 +153,24 @@ public:
}; // ObjectPass2Shader }; // ObjectPass2Shader
// ======================================================================== // ========================================================================
class SkinnedMeshPass1Shader : public TextureShader<SkinnedMeshPass1Shader, 1,
core::matrix4, core::matrix4,
int>
{
public:
SkinnedMeshPass1Shader();
}; // SkinnedMeshPass1Shader
// ========================================================================
class SkinnedMeshPass2Shader : public TextureShader < SkinnedMeshPass2Shader, 6,
core::matrix4, core::vector2df,
core::vector2df, int >
{
public:
SkinnedMeshPass2Shader();
}; // SkinnedMeshPass2Shader
// ========================================================================
}; // class Shaders }; // class Shaders

View File

@ -119,7 +119,7 @@ class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class ListSkinnedSolid : public MeshList<ListSkinnedSolid, GLMesh *, core::matrix4, class ListSkinnedSolid : public MeshList<ListSkinnedSolid, GLMesh *, core::matrix4,
core::matrix4, core::vector2df, core::matrix4, core::vector2df,
core::vector2df> core::vector2df, int>
{}; {};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------