In my project I have skinned model with bump mapping.
I calculate tangent array in offline. But I dont do Gram-Schmidt orthogonalization (because of the bones
transformations tangent and normal could become not orthogonal to each other, so I do this in the vertex shader after skinning). I pass an unnormalized tangent to the vertex shader. And this is my vertex shader:
uniform mat4 MatrixArray[100];
varying vec3 lightVec;
varying vec3 halfVec;
attribute vec4 Weights;
attribute vec4 Bones;
attribute vec4 tangent;
void main( void )
{
gl_TexCoord[0] = gl_MultiTexCoord0;
vec4 index = Bones;
vec4 weight = Weights;
vec4 normal = vec4( gl_Normal.xyz, 0.0 );
vec4 position = vec4( 0.0, 0.0, 0.0, 0.0 );
vec4 tempNormal = vec4( 0.0, 0.0, 0.0, 0.0 );
vec4 tangent0 = vec4( tangent.xyz, 0.0 );
vec4 tempTangent = vec4( 0.0, 0.0, 0.0, 0.0 );
for( float i = 0.0; i < 4.0; i += 1.0 )
{
// Apply influence of bone i
position = position + weight.x * (MatrixArray[int(index.x)] * gl_Vertex);
tempNormal = tempNormal + weight.x * (MatrixArray[int(index.x)] * normal);
tempTangent = tempTangent + weight.x * (MatrixArray[int(index.x)] * tangent0);
// shift over the index/weight variables, this moves the index and
// weight for the current bone into the .x component of the index
// and weight variables
index = index.yzwx;
weight = weight.yzwx;
if (weight == 0.0)
break;
}
tempNormal = normalize(tempNormal);
// Gram-Schmidt orthogonalization
vec3 resTangent = tempTangent.xyz - tempNormal.xyz * dot (tempTangent.xyz, tempNormal.xyz);
resTangent = normalize(resTangent);
gl_TexCoord[0] = gl_MultiTexCoord0;
// Building the matrix Eye Space -> Tangent Space
vec3 n = normalize (gl_NormalMatrix * tempNormal.xyz);
vec3 t = normalize (gl_NormalMatrix * resTangent);
vec3 b = cross (n, t) * tangent.w;
vec3 vertexPosition = vec3(gl_ModelViewMatrix * position);
vec3 lightDir = normalize(gl_LightSource[0].position.xyz - vertexPosition);
vertexPosition = normalize(vertexPosition);
vec3 eyeDir = - vertexPosition;
// transform light and half angle vectors by tangent basis
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, n);
lightVec = normalize (v);
v.x = dot (eyeDir, t);
v.y = dot (eyeDir, b);
v.z = dot (eyeDir, n);
vec3 eyeVec = normalize (v);
halfVec = normalize(eyeVec + lightVec);
gl_Position = gl_ModelViewProjectionMatrix * position;
}
Check me please. Is it an optimized shader?