I am learning OpenGL (and learning the math behind it) and I'm making a simple OBJ viewer, nothing fancy. I have diffuse, specular and ambient light/texture working fine and now I am implementing the bump mapping. I based my code on what I learned with the OpenGL 4.3 Redbook and "Mathematics for 3D game programming and computer graphics" book.

There is probably something I didn't understand correctly, I just hope you will be able to help me :)

Anyway this is the result I get (from a free asset used just for testing -- the results are fine in blender) : Results

This is the diffuse texture and the bump map : Diffuse texture Bump texture

Fragment shader code :

void main() {
    vec3 normalDirection = normalize(tangenteSpace*(texture2D( bump_tex, f_texcoord ).rgb*2.0 - 1.0));
    //vec3 normalDirection = normalize(mat3(invTransp)*vertNormal);
    vec3 viewDirection = tangenteSpace*normalize(vec3(invView * vec4(0.0, 0.0, 0.0, 1.0) - position));

    float attenuation = 1.0;//none
    vec3 vertToLightSource = vec3(light.position - position*light.position.w);
    float distance = length(vertToLightSource);
    attenuation = mix(1.0,1.0/(light.constantAttenuation +
                    light.linearAttenuation *distance +
    vec3 lightDirection = tangenteSpace*(vertToLightSource/distance);

    //spotlight if spotCutoff <= 90
    float clampedCosine = max(0.0, dot(-lightDirection, normalize(light.spotDirection)));
    float tempMix = mix(attenuation * pow(clampedCosine, light.spotExponent),0.0,clampedCosine < cos(light.spotCutoff * 3.14159 / 180.0));//if outside of spotlight nothing
    attenuation = mix(attenuation,tempMix,light.spotCutoff <= 90.0);

    //should there be any attenuation ?
    attenuation = mix(attenuation,1.0,light.position.w);

    //------------------------------ ambiant light
    vec3 ambientLight = vec3(ambientScene)*vec3(mat.Ka);

    //------------------------------ specular light
    //get the reflection
    vec4 specularMapPixel = texture2D(spec_tex, f_texcoord).rgba;
    vec3 specularColor = specularMapPixel.rgb;
    float shininess = specularMapPixel.a;
    vec3 specularReflection = mix(
    attenuation * vec3(light.specular) * vec3(mat.Ks)* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)),mat.Ns*shininess) *specularColor.rgb,
          vec3(0.0, 0.0, 0.0),
          dot(normalDirection, lightDirection) < 0.0

    vec3 diffuseReflection = attenuation*

    vec4 Color = vec4(vec4(specularReflection,1.0) + vec4(ambientLight,1)*texture2D(amb_tex, f_texcoord) + vec4(diffuseReflection,1.0)*texture2D(dif_tex, f_texcoord));

    FragColor = Color;

Vertex Shader Code :

void main()
    //comnpute tangent space
    tangenteSpace[0] = mat3(mv)*normalize(tangent.xyz);
    tangenteSpace[2] = mat3(mv)*normalize(vertNormal);
    tangenteSpace[1] = mat3(mv)*normalize(cross(tangenteSpace[0],tangenteSpace[2])*tangent.w);
    tangenteSpace = transpose(tangenteSpace);

    //position in world space
    position = m * vertCoord;
    f_texcoord = vec2(texCoord);

    gl_Position = mvp * vertCoord;
  • \$\begingroup\$ I haven't read the code, but it seems like the alpha component of the colors is getting zeroed. \$\endgroup\$ Oct 31, 2014 at 14:11

1 Answer 1


The reason you are getting artefacts is because you are not using a bump map shader; You are using a normal map shader, with a displacement map.

A normal map (often confused with bump map) looks like this:

enter image description here

The colour represents the surface normal, which you then transform from tangent space to view space.

The texture you have shown is a height, or displacement map, which is used to generate the normal map.

If you are using GIMP, there is a nice plugin available here, which will convert a height map to a normal map, and once you bind that resulting texture instead, your artefacts should disappear.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .