Allow GL3 to have hardware skinning
This commit is contained in:
parent
b7e047b4c1
commit
76e070b709
@ -1,81 +1,86 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#ifdef GL_ES
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 InverseModelMatrix;
|
||||
uniform vec2 texture_trans;
|
||||
#else
|
||||
uniform mat4 ModelMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
uniform mat4 InverseModelMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
|
||||
// skinning.vert
|
||||
#version 330 compatibility
|
||||
#define MAX_JOINT_NUM 36
|
||||
#define MAX_LIGHT_NUM 8
|
||||
uniform vec2 texture_trans = vec2(0., 0.);
|
||||
#endif
|
||||
uniform int skinning_offset;
|
||||
|
||||
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;
|
||||
vec4 ecPos;
|
||||
vec3 normal;
|
||||
vec3 light_dir;
|
||||
float n_dot_l;
|
||||
float dist;
|
||||
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
|
||||
vec4 idle_position = vec4(Position, 1.);
|
||||
vec4 idle_normal = vec4(Normal, 0.);
|
||||
vec4 skinned_position = vec4(0.);
|
||||
vec4 skinned_normal = vec4(0.);
|
||||
|
||||
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);
|
||||
mat4 vertTran = JointTransform[index - 1];
|
||||
// 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;
|
||||
|
||||
index = int(gl_Color.g * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
// 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;
|
||||
|
||||
index = int(gl_Color.b * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
// 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;
|
||||
|
||||
index = int(gl_Color.a * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
// 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;
|
||||
|
||||
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;
|
||||
normal = normalize(gl_NormalMatrix * normal);
|
||||
|
||||
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;
|
||||
*/
|
||||
uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
|
||||
color = Color.zyxw;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ void DrawCalls::clearLists()
|
||||
ListDisplacement::getInstance()->clear();
|
||||
|
||||
ListMatDefault::getInstance()->clear();
|
||||
ListSkinnedSolid::getInstance()->clear();
|
||||
ListMatAlphaRef::getInstance()->clear();
|
||||
ListMatSphereMap::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(0.0f, 0.0f)));
|
||||
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:
|
||||
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
|
@ -176,6 +176,7 @@ void drawRSM(const core::matrix4 & rsm_matrix)
|
||||
void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
||||
{
|
||||
renderMeshes1stPass<DefaultMaterial, 2, 1>();
|
||||
renderMeshes1stPass<SkinnedSolid, 5, 2, 1>();
|
||||
renderMeshes1stPass<SplattingMat, 2, 1>();
|
||||
renderMeshes1stPass<UnlitMat, 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
|
||||
{
|
||||
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<UnlitMat, 3, 1 > (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
||||
|
@ -655,8 +655,8 @@ struct SkinnedSolid
|
||||
typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader;
|
||||
//typedef InstancedShadowShader InstancedShadowPassShader;
|
||||
//typedef CInstancedRSMShader InstancedRSMShader;
|
||||
//typedef Shaders::ObjectPass1Shader FirstPassShader;
|
||||
//typedef Shaders::ObjectPass2Shader SecondPassShader;
|
||||
typedef Shaders::SkinnedMeshPass1Shader FirstPassShader;
|
||||
typedef Shaders::SkinnedMeshPass2Shader SecondPassShader;
|
||||
//typedef ShadowShader ShadowPassShader;
|
||||
//typedef CRSMShader RSMShader;
|
||||
typedef ListSkinnedSolid List;
|
||||
@ -668,7 +668,7 @@ struct SkinnedSolid
|
||||
static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures;
|
||||
static const STK::Tuple<> ShadowTextures;
|
||||
static const STK::Tuple<size_t> RSMTextures;
|
||||
}; // struct DefaultMaterial
|
||||
}; // struct SkinnedSolid
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
struct DefaultMaterial
|
||||
|
@ -359,6 +359,29 @@ Shaders::ObjectPass2Shader::ObjectPass2Shader()
|
||||
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||
} // 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()
|
||||
{
|
||||
|
@ -153,6 +153,24 @@ public:
|
||||
}; // 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
|
||||
|
@ -119,7 +119,7 @@ class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4,
|
||||
// ----------------------------------------------------------------------------
|
||||
class ListSkinnedSolid : public MeshList<ListSkinnedSolid, GLMesh *, core::matrix4,
|
||||
core::matrix4, core::vector2df,
|
||||
core::vector2df>
|
||||
core::vector2df, int>
|
||||
{};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user