title: Normal Rotation in GLSL
body: <p>I have written a basic program that loads a model and renders it to the screen. I'm using GLSL to transform the model appropriately, but the normals always seem to be incorrect after rotating them with every combination of model matrix, view matrix, inverse, transpose, etc that I could think of. The model matrix is just a rotation around the y-axis using glm:</p>
  
  <pre><code>angle += deltaTime;
  modelMat = glm::rotate(glm::mat4(), angle, glm::vec3(0.f, 1.f, 0.f));
  </code></pre>
  
  <p>My current vertex shader code (I've modified the normal line many many times):</p>
  
  <pre><code>#version 150 core
  uniform mat4 projMat;
  uniform mat4 viewMat;
  uniform mat4 modelMat;
  in vec3 inPosition;
  in vec3 inNormal;
  out vec3 passColor;
  
  void main()
  {
      gl_Position = projMat * viewMat * modelMat * vec4(inPosition, 1.0);
      vec3 normal = normalize(mat3(inverse(modelMat)) * inNormal);
      passColor = normal;
  }
  </code></pre>
  
  <p>And my fragment shader:</p>
  
  <pre><code>#version 150 core
  in vec3 passColor;
  out vec4 outColor;
  
  void main()
  {
      outColor = vec4(passColor, 1.0);
  }
  </code></pre>
  
  <p>I know for sure that the uniform variables are being passed to the shader properly, as the model itself gets transformed properly, and the initial normals are correct if I do calculations such as directional lighting.</p>
  
  <p>I've created a GIF of the rotating model, sorry about the low quality:
  <a href="http://i.imgur.com/LgLKHCb.gif?1" rel="nofollow">http://i.imgur.com/LgLKHCb.gif?1</a></p>
  
  <p>What confuses me the most is how the normals appear to rotate on multiple axis, which I don't think should happen when multiplied by a simple rotation matrix on one axis. </p>
  
  <p><strong>Edit:</strong></p>
  
  <p>I've added some more of the client code below.</p>
  
  <p>This is where the buffers get bound for the model, in the <code>Mesh</code> class (<code>vao</code> is <code>GLuint</code>, defined in the class):</p>
  
  <pre><code>GLuint vbo[3];
  
  glGenVertexArrays(1, &amp;vao);
  glBindVertexArray(vao);
  
  glGenBuffers(normals? (uvcoords? 3 : 2) : (uvcoords? 2 : 1), vbo);
  
  glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  glBufferData(GL_ARRAY_BUFFER, vcount * 3 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  glEnableVertexAttribArray(0);
  
  if(normals)
  {
      glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
      glBufferData(GL_ARRAY_BUFFER, vcount * 3 * sizeof(GLfloat), normals, GL_STATIC_DRAW);
      glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, 0);
      glEnableVertexAttribArray(1);
  }
  
  if(uvcoords)
  {
      glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
      glBufferData(GL_ARRAY_BUFFER, vcount * 2 * sizeof(GLfloat), uvcoords, GL_STATIC_DRAW);
      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
          glEnableVertexAttribArray(2);
  }
  
  glBindVertexArray(0);
  
  glGenBuffers(1, &amp;ib);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, icount * sizeof(GLushort), indices, GL_STATIC_DRAW);
  </code></pre>
  
  <p>This is where the shaders are compiled after being loaded into memory with a simple readf(), in the <code>Material</code> class:</p>
  
  <pre><code>u32 vertexShader = glCreateShader(GL_VERTEX_SHADER);
  u32 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  
  glShaderSource(vertexShader, 1, (const GLchar**)&amp;vsContent, 0);
  glCompileShader(vertexShader);
  if(!validateShader(vertexShader)) return false;
      glShaderSource(fragmentShader, 1, (const GLchar**)&amp;fsContent, 0);
  glCompileShader(fragmentShader);
  if(!validateShader(fragmentShader)) return false;
  
  programHandle = glCreateProgram();
  
  glAttachShader(programHandle, vertexShader);
  glAttachShader(programHandle, fragmentShader);
  
  glBindAttribLocation(programHandle, 0, "inPosition");
  glBindAttribLocation(programHandle, 1, "inNormal");
  //glBindAttribLocation(programHandle, 2, "inUVCoords");
  
  glLinkProgram(programHandle);
  if(!validateProgram()) return false;
  </code></pre>
  
  <p>And the <code>validateShader(GLuint)</code> and <code>validateProgram()</code> functions:</p>
  
  <pre><code>bool Material::validateShader(GLuint shaderHandle)
  {
      char buffer[2048];
      memset(buffer, 0, 2048);
      GLsizei len = 0;
  
      glGetShaderInfoLog(shaderHandle, 2048, &amp;len, buffer);
      if(len &gt; 0)
      {
          Logger::log("ve::Material::validateShader: Failed to compile shader - %s", buffer);
          return false;
      }
  
      return true;
  }
  
  bool Material::validateProgram()
  {
      char buffer[2048];
      memset(buffer, 0, 2048);
      GLsizei len = 0;
  
      glGetProgramInfoLog(programHandle, 2048, &amp;len, buffer);
      if(len &gt; 0)
      {
          Logger::log("ve::Material::validateProgram: Failed to link program - %s", buffer);
          return false;
      }
  
      glValidateProgram(programHandle);
      GLint status;
      glGetProgramiv(programHandle, GL_VALIDATE_STATUS, &amp;status);
      if(status == GL_FALSE)
      {
          Logger::log("ve::Material::validateProgram: Failed to validate program");
          return false;
      }
  
      return true;
  }
  </code></pre>
  
  <p>Each <code>Material</code> instance has a <code>std::map</code> of <code>Mesh</code>s, and get rendered as so:</p>
  
  <pre><code>void Material::render()
  {
      if(loaded)
      {
          glUseProgram(programHandle);
  
          for(auto it = mmd-&gt;uniforms.begin(); it != mmd-&gt;uniforms.end(); ++it)
          {
              GLint loc = glGetUniformLocation(programHandle, (const GLchar*)it-&gt;first);
  
              switch(it-&gt;second.type)
              {
              case E_UT_FLOAT3: glUniform3fv(loc, 1, it-&gt;second.f32ptr); break;
              case E_UT_MAT4: glUniformMatrix4fv(loc, 1, GL_FALSE, it-&gt;second.f32ptr); break;
              default: break;
              }
          }
  
          for(Mesh* m : mmd-&gt;objects)
          {
              GLint loc = glGetUniformLocation(programHandle, "modelMat");
              glUniformMatrix4fv(loc, 1, GL_FALSE, &amp;m-&gt;getTransform()-&gt;getTransformMatrix()[0][0]);
              m-&gt;render();
          }
      }
  }
  </code></pre>
  
  <p><code>it-&gt;second.f32ptr</code> would be a <code>float</code> pointer to <code>&amp;some_vec3[0]</code> or <code>&amp;some_mat4[0][0]</code>.
  I manually upload the model's transformation matrix before rendering, however (which is only a rotation matrix, the <code>Transform</code> class (returned by Mesh::getTransform()) will only do a glm::rotation() since I was trying to figure out the problem).</p>
  
  <p>Lastly, the <code>Mesh</code> render code:</p>
  
  <pre><code>if(loaded)
  {
      glBindVertexArray(vao);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
      glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);
  }
  </code></pre>
  
  <p>I think this is all the necessary code, but I can post more if needed.</p>