# Bump mapping and skinning (tangent)

In my project I have skinned model with bump mapping.
I calculate tangent array in offline. But I don`t 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?

May be something is wrong?