title: Normal mapping and phong shading with incorrect specular component
body: <p>I'm implementing normal/bump mapping in world space coordinates (I find those easier to work with) and my lighting worked fine without normal mapping, but when introducing normal mapping (and the new vectors calculated with the TBN matrix) the specular component of my lighting is off.</p>
  
  <p>The specular component is not between the camera and the light where it should be so something is wrong. However, looking at my code I could not find any issues. The tangent and bitangent come from the ASSIMP object loader and the eyePos and lightPos are in world coordinates as well. </p>
  
  <p>Since the lighting seems to look correct at the specular section (with the bump mapping shown) I assume it has something to do with the tangent space transformation?</p>
  
  <p>Here is a picture demonstrating the issue:</p>
  
  <p><img src="https://i.stack.imgur.com/V5ZGX.jpg" alt="Bump mapping with wrong specular component"></p>
  
  <p>Vertex shader:</p>
  
  <pre><code>#version 330
  layout (location = 0) in vec4 vertex;
  layout(location = 1) in vec3 normal;
  layout(location = 2) in vec3 tangent;
  layout(location = 3) in vec3 bitangent;
  layout(location = 5) in vec2 texCoord;
  
  uniform mat4 projection;
  uniform mat4 view;
  uniform mat4 model;
  uniform vec3 lightPos; 
  uniform vec3 eyePos;
  
  out vec3 Position;
  out vec2 TexCoord;
  
  out vec3 tangentLightDir;
  out vec3 tangentViewDir;
  
  void main()
  {
      gl_Position = projection * view * model * vertex;
      // Position
      Position = vec3(model * vertex);
      // Normal
      mat3 normalMat = transpose(inverse(mat3(model)));
      Normal = normalize(normalMat * normal);
      // Texture
      TexCoord = texCoord;
  
      // Normal mapping
      mat3 TBN = mat3(tangent, bitangent, Normal);
      TBN = transpose(TBN);
      // Get direction vectors:
      vec3 lightDir = normalize(lightPos - Position);
      vec3 viewDir = normalize(eyePos - Position); 
      // Now transform them to tangent space
      tangentLightDir = TBN * lightDir;
      tangentViewDir = TBN * viewDir;
  }
  </code></pre>
  
  <p>Fragment shader:</p>
  
  <pre><code>#version 330
  in vec3 Position;
  in vec2 TexCoord;
  
  in vec3 tangentLightDir;
  in vec3 tangentViewDir;
  
  uniform sampler2D texture0;
  uniform sampler2D texture_normal;
  
  out vec4 outColor;
  
  void main()
  {
      // defaults
      vec4 ambient = vec4(0.1);
      vec4 diffuse = vec4(0.4);
      vec4 specular = vec4(0.5);
      vec4 texColor = texture(texture0, TexCoord);    
  
      // Phong shading
      vec3 LightDir = normalize(tangentLightDir);
      vec3 Norm = normalize(texture(texture_normal, TexCoord).xyz * 2.0 - 1.0);    
  
      vec3 ViewDir = normalize(tangentViewDir); 
      vec3 ReflectDir = reflect(-LightDir,Norm);
      float specularContribution = pow(max(dot(ViewDir, ReflectDir), 0.0), 32);
      // Calculate diffuse component
      vec4 I = diffuse * max(dot(LightDir, Norm), 0.0);
      diffuse = clamp(I, 0.0, 1.0);
      // Calculate specular component
      specular = specular * specularContribution;
  
      outColor = texColor * (diffuse + specular + ambient);
  }
  </code></pre>