I've got diffuse lighting working, but it seems to be stuck in world space. I've looked at a few guides and understand that the reason this is happening is because the model is being lit in world space and then once it's transformed to model space, it keeps the lighting it received from world space. Great demonstration of the problem here.

To fix this, I'm doing the following (except it's not working):

Vertex Shader

Code :#version 440 compatibility layout(location = 0) in vec3 position; layout(location = 1) in vec3 normal; layout(location = 2) in float offset; out vec3 theNormal; out vec3 thePosition; uniform mat4 FullTransformMatrix; uniform mat4 ModelToWorldTransformMatrix; void main() { vec4 v = vec4(position, 1.0); gl_Position = FullTransformMatrix * v; theNormal = normal; thePosition = vec3(ModelToWorldTransformMatrix * v); }

Fragment Shader

Code :#version 440 compatibility layout(location = 0) out vec4 outColor; in vec3 theNormal; in vec3 thePosition; uniform vec3 LightPosition; void main() { vec3 lightVector = normalize(LightPosition - thePosition); float brightness = dot(lightVector, theNormal); outColor = vec4(brightness, brightness, brightness, 1.0); }

Part of the update loop

Code :glm::mat4 ProjectionMatrix = mainCamera->getProjectionMatrix (); glm::mat4 ViewMatrix = mainCamera->getViewMatrix (); // Plane glBindVertexArray ( planeVertexArray ); translation = glm::translate ( glm::mat4 ( 1 ), glm::vec3 ( 0.0f, 0.0f, 0.0f ) ); ModelMatrix = glm::rotate ( translation, 0.0f, glm::vec3 ( 1.0f, 0.0f, 0.0f ) ); mvp = ProjectionMatrix * ViewMatrix * ModelMatrix; glProgramUniformMatrix4fv ( program, modelToWorldMatrixLocation, 1, GL_FALSE, &ModelMatrix[0][0] ); glProgramUniformMatrix4fv ( program, fullTransformMatrixLocation, 1, GL_FALSE, &mvp[0][0] ); glDrawElements ( GL_TRIANGLES, planeIndices.size (), GL_UNSIGNED_INT, ( void* ) ( planeVertices.size () * sizeof ( GLfloat ) ) ); glBindVertexArray ( vertexArray ); // Object 1 translation = glm::translate ( glm::mat4 ( 1 ), glm::vec3 ( 2.0f, 2.0f, -2.0f ) ); ModelMatrix = glm::rotate (translation, 180.0f, glm::vec3 ( 0.0, 1.0f, 0.0f ) ); mvp = ProjectionMatrix * ViewMatrix * ModelMatrix; glProgramUniformMatrix4fv ( program, fullTransformMatrixLocation, 1, GL_FALSE, &mvp[0][0] ); glProgramUniformMatrix4fv ( program, modelToWorldMatrixLocation, 1, GL_FALSE, &ModelMatrix[0][0] ); //glDrawElementsInstanced ( GL_TRIANGLES, suzIndices.size (), GL_UNSIGNED_INT, nullptr, 3 ); glDrawElements ( GL_TRIANGLES, suzIndices.size (), GL_UNSIGNED_INT, ( void* ) (suzVertices.size() * sizeof(GLfloat)) ); // Object 2 translation = glm::translate ( glm::mat4 ( 1 ), glm::vec3 ( 0.0f, 2.0f, 2.0f ) ); ModelMatrix = glm::rotate ( translation, 0.0f, glm::vec3 ( 0.0f, 1.0f, 0.0f ) ); mvp = ProjectionMatrix * ViewMatrix * ModelMatrix; glProgramUniformMatrix4fv ( program, fullTransformMatrixLocation, 1, GL_FALSE, &mvp[0][0] ); glProgramUniformMatrix4fv ( program, modelToWorldMatrixLocation, 1, GL_FALSE, &ModelMatrix[0][0] ); glDrawElements ( GL_TRIANGLES, suzIndices.size (), GL_UNSIGNED_INT, ( void* ) ( suzVertices.size () * sizeof ( GLfloat ) ) );

What gives?