Vertex shader:
varying vec3 v;
varying vec4 VaryingTexCoord0;
varying vec3 vnormal;
varying mat3 TBN;
attribute vec3 tangent;
void main(void)
{
vnormal = normalize(gl_NormalMatrix * gl_Normal);
vec3 ntangent = normalize(gl_NormalMatrix * tangent);
vec3 bitangent = cross(vnormal, ntangent); //get the bitangent perpendicular to the normal and tangent
TBN = mat3(ntangent, bitangent, vnormal); //construct the TBN matrix
v = vec3(gl_ModelViewMatrix * gl_Vertex);
VaryingTexCoord0 = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Important part of the fragment shader:
vec3 finalnormal;
vec3 eyevec = normalize(-v);
vec2 transformedTexcoord;
vec4 ntexcolor;
if(bump_on > 0)
{
vec3 view = normalize(eyevec * TBN);
float height = (texture2D(height_texture, vec2(VaryingTexCoord0)).r * 0.04) - 0.03; //grab height from a heightmap
transformedTexcoord = (height * view.xy) + vec2(VaryingTexCoord0); //transform the texcoord based on the height
ntexcolor = texture2D(normal_texture, transformedTexcoord); //sample the normal map with the transformed texcoord
vec3 normal = normalize(ntexcolor.rgb * 2.0 - vec3(1.0)); //turn that sample into a normal vector
finalnormal = normalize(TBN * normal); //multiply that by the tbn matrix to get the final normal
}






