title: Normal mapping GLSL using LibGDX
body: <p>I try to implement normal mapping using LibGDX. So I got some positive results when I calculate diffuse and specular color in vertex shader (at least I think so). </p>
  
  <p><strong>Vertex shader:</strong></p>
  
  <pre><code>attribute vec4 a_position;
  attribute vec2 a_texCoord0;
  attribute vec3 a_normal;    
  
  varying vec2 v_texCoord;
  varying float v_diffuse;
  varying vec3 v_specular;
  varying vec3 v_lightVec;
  
  uniform mat4 u_worldTrans;
  uniform mat4 u_projTrans;
  uniform mat4 u_matViewInverseTranspose;
  uniform mat4 u_matModelView;
  
  const vec3 lightVector = vec3(0.0,0.0,-1.0);
  
  void main()
  {
    // Output the unmodified vertex position. 
    gl_Position = u_projTrans * u_worldTrans * a_position;
  
    mat3 normalMatrix = mat3(u_matViewInverseTranspose);
    // compute the transformed normal
    vec3 n = normalize(normalMatrix * a_normal);
  
    // compute the light vector pointing toward the sun, in model coordinates
    // x,y compose the longitude and z the (seasonal) lattitude of the nadir point.
    //vec3 lightVec = normalize(vec3(u_matViewInverseTranspose * vec4(u_lightVec, 1.0)));
    vec3 lightVec = normalize(normalMatrix * lightVector);
  
    // Calculate a diffuse light intensity
    //v_diffuse = dot(lightVec, n);
    v_diffuse = clamp(dot(n, lightVec), 0.0, 1.0);
  
    vec4 ecPosition = u_matModelView * a_position;
    // compute the reflection vector
    vec3 reflectVec = reflect(-lightVec, n);
    // compute a unit vector in direction of viewing position
    vec3 viewVec    = normalize(vec3(-ecPosition));
  
    // Calculate specular light intensity, scale down and apply a tint. 
    float specIntensity = pow(max(dot(reflectVec, viewVec), 0.0), 8.0);       
    v_specular            = specIntensity  * 
                          //gloss color
                          vec3(1.,.7,.3) * 
                          //gloss intensity
                          .7;     
  
    v_texCoord.y = 1.-a_texCoord0.y;
    v_texCoord.x = a_texCoord0.x; 
  
    vec3 lightDir = normalize(lightVector - u_matModelView * a_position);
  
    vec3 tangent=a_tangent;
    vec3 t = normalize(normalMatrix * tangent);
    vec3 b = cross (n, t);    
  
    vec3 v;
    v.x = dot (lightDir, t);
    v.y = dot (lightDir, b);
    v.z = dot (lightDir, n);  
  
    v_lightVec = normalize (v);           
  }
  </code></pre>
  
  <p><strong>Fragment shader:</strong></p>
  
  <pre><code>precision mediump float;
  
  varying vec2 v_texCoord;
  varying float v_diffuse;
  varying vec3 v_specular;
  varying vec3 v_lightVec;
  
  uniform sampler2D u_texture;
  uniform sampler2D u_normalMap;
  
  void main()
  {   
    vec3 ground = texture2D(u_texture, v_texCoord).rgb;
  
    vec3 normal  = normalize(2.0 * texture2D (u_normalMap, v_texCoord).rgb - 1.0);
    float lamberFactor = max (dot (normal, v_lightVec), 0.0);   
  
    vec3 color = ( ground.rgb * v_diffuse * lamberFactor + v_specular);
  
    gl_FragColor = vec4 (color, 1.0);             
  }
  </code></pre>
  
  <p><strong>Result:</strong>
  <img src="https://i.stack.imgur.com/R2yle.jpg" alt="Correct result"></p>
  
  <p>As you can see the result is rendered correctly. Specular spot behaves like from many examples. But I need to implement specular color in fragment shader to get more impressive picture. So I found example from <a href="http://www.ozone3d.net/tutorials/bump_mapping.php" rel="noreferrer">here</a> and now I'm trying to make it works. </p>
  
  <p><strong>Vertex shader:</strong></p>
  
  <pre><code>attribute vec4 a_position;
  attribute vec2 a_texCoord0;
  attribute vec3 a_normal;
  attribute vec3 a_tangent; 
  
  varying vec2 v_texCoord;   
  varying vec3 v_lightVec;
  varying vec3 v_eyeVec;  //Added
  
  uniform mat4 u_worldTrans;
  uniform mat4 u_projTrans;
  uniform mat4 u_matViewInverseTranspose;
  uniform mat4 u_matModelView;
  
  const vec3 lightVector = vec3(0.0,0.0,-1.0);
  
  void main()
  {
    // Output the unmodified vertex position. 
    gl_Position = u_projTrans * u_worldTrans * a_position;
  
    mat3 normalMatrix = mat3(u_matViewInverseTranspose);
    // compute the transformed normal
    vec3 n = normalize(normalMatrix * a_normal);
  
    v_texCoord.y = 1.-a_texCoord0.y;
    v_texCoord.x = a_texCoord0.x; 
  
    vec3 lightDir = normalize(lightVector - u_matModelView * a_position);
  
    vec3 tangent=a_tangent;
    vec3 t = normalize(normalMatrix * tangent);
    vec3 b = cross (n, t);    
  
    vec3 v;
    v.x = dot (lightDir, t);
    v.y = dot (lightDir, b);
    v.z = dot (lightDir, n);  
  
    v_lightVec = normalize (v);
  
    //Added
    vec3 ecPosition = u_matModelView * a_position;  
  
    vec3 tmp = vec3(-ecPosition);
    v_eyeVec.x = dot(tmp, t);
    v_eyeVec.y = dot(tmp, b);
    v_eyeVec.z = dot(tmp, n);
    v_eyeVec = normalize (v_eyeVec);  
  }
  </code></pre>
  
  <p><strong>Fragment shader:</strong></p>
  
  <pre><code>precision mediump float;
  
  varying vec2 v_texCoord;
  varying vec3 v_lightVec;
  varying vec3 v_eyeVec; 
  
  uniform sampler2D u_texture;
  uniform sampler2D u_normalMap;
  
  void main()
  {   
    vec3 ground = texture2D(u_texture, v_texCoord).rgb;       
    vec3 normal  = normalize(2.0 * texture2D (u_normalMap, v_texCoord).rgb - 1.0);
  
    //Added
    float distSqr = dot(v_lightVec, v_lightVec);
    float att = clamp(1.0 - .25 * sqrt(distSqr), 0.0, 1.0);
    vec3 lVec = v_lightVec * inversesqrt(distSqr);
  
    vec3 vVec = normalize(v_eyeVec);  
    vec3 bump = normalize( texture2D(u_normalMap, v_texCoord).xyz * 2.0 - 1.0);
  
    float diffuse = max( dot(lVec, bump), 0.0 );
  
    vec3 specular = pow(clamp(dot(reflect(-lVec, bump), v_eyeVec), 0.0, 1.0), 8.0 ) *
                          //gloss color
                          vec3(1.,.7,.3) * 
                          //gloss intensity
                          .7; 
  
    vec3 color = ( ground.rgb * diffuse + specular) * att;          
    gl_FragColor = vec4 (color, 1.0);
  }    
  </code></pre>
  
  <p><strong>Result:</strong></p>
  
  <p><img src="https://i.stack.imgur.com/yx43D.jpg" alt="Wrong result"></p>
  
  <p>Specular spot is wrong. I thought it happens because of wrong matrix calculation. If it's true why do first couple of shaders work correctly? 
  How do I get <code>model-view</code> matrix, <code>normal</code> matrix and others in LibGDX?</p>
  
  <pre><code> viewInvTraMatrix.set(camera.view);     
   viewInvTraMatrix.mul(renderable.worldTransform);
   //model-view matrix
   program.setUniformMatrix("u_matModelView", viewInvTraMatrix);
   viewInvTraMatrix.inv(); //inverse
   viewInvTraMatrix.tra(); //transpose
   //normal matrix
   program.setUniformMatrix("u_matViewInverseTranspose", viewInvTraMatrix);
  
   //other matrix
   program.setUniformMatrix("u_worldTrans", renderable.worldTransform);
   program.setUniformMatrix("u_projTrans", camera.combined);
  </code></pre>
  
  <p>So, my question is what is wrong in the last couple of shaders?</p>