In this little tech demo I experimented a bit on Bump Mapping. For it, I used the Doom 3 model from Fabien Sanglard’s Bump Mapping demo. There’s also a good explanation on bump mapping theory and some source and shader code. I used only the model and textures from his demo, and I only implemented Bump Mapping, with simple lighting and no shadowing.

Here is the code from my Bump Mapping shaders:

Vertex shader:

#version 330

// Attributes per vertex
in vec4 position;
in vec3 normal;
in vec2 texCoord0;
in vec3 tangent;

uniform mat4   MVP;
uniform mat4   MV;
uniform mat3   normalMatrix;
uniform vec3   light_position;

smooth out vec3 vNormal;
smooth out vec3 vLightPos;
smooth out vec2 vTexCoords;

void main(void)
    vec3 n = normalize (normalMatrix * normal);
    vec3 t = normalize (normalMatrix * tangent);
    vec3 b = cross (n, t);

    // Get surface normal in eye coordinates
    vNormal = normalMatrix * normal;

    // Get vertex position in eye coordinates
    vec4 vertexPos = MV * position;
    vec3 vertexEyePos = / vertexPos.w;

    vec3 lightDir = normalize (light_position - vertexEyePos);

    vec3 v;
    v.x = dot (lightDir, t);
    v.y = dot (lightDir, b);
    v.z = dot (lightDir, n);
    vLightPos = normalize (v);

    vTexCoords =;

    // Don't forget to transform the geometry!
    gl_Position = MVP * position;

Fragment shader:

#version 330

out vec4 fragmentColor;

uniform vec4 model_color;
uniform sampler2D color_texture;
uniform sampler2D specular_texture;
uniform sampler2D normal_texture;
uniform int use_color = 0;

smooth in vec3 vNormal;
smooth in vec3 vLightPos;
smooth in vec2 vTexCoords;

void main(void)
    // Lookup normal from normal map, move from [0, 1] to [-1, 1] range,
    // normalize
    vec3 normal = 2.f * texture (normal_texture, - 1.f;
    normal = normalize (normal);

    // Dot product gives us diffuse intensity
    float diff = max(0.0, dot(normalize(normal), normalize(vLightPos)));

    vec4 ambientColor = model_color;

    // Multiply intensity by diffuse color, force alpha to 1.0
    fragmentColor = diff * model_color;

    // Add in ambient light
    fragmentColor += ambientColor;

    // Use diffuse color tecture
    if (use_color != 0)
        fragmentColor *= texture (color_texture,;

    // Specular Light
    vec3 reflection = normalize(reflect(-normalize(vLightPos), normalize(normal)));
    float spec = max(0.0, dot(normalize(normal), reflection));
    if(diff != 0)
        float fSpec = pow(spec, 2.0);
        vec4 specular_mat = texture (specular_texture,;
        fragmentColor.rgb += vec3(fSpec, fSpec, fSpec) * specular_mat.rgb;

And finally, as always, some screenshots showing the result:

About these ads