Again, for a non-deformable object, you don't have to do anything to gl_Normal. It's already in object space by definition. The only thing you need to do is transform the eye and light vectors from object space to tangent space.
IIRC gl_LightSource[0].position.xyz will be the light direction in world-space. For performance reasons, you should use a custom uniform that defines the light direction in object space. You do that by transforming the light direction at the Java level and pass it to the shader. You do this per-object of course. You could also do it for the camera position, but you can derive it from the MVP matrix (like you do).
My vertex shader code looks like this:
// Pseudo-instancing
vec3 position = vec3
(
dot(gl_MultiTexCoord5, gl_Vertex),
dot(gl_MultiTexCoord6, gl_Vertex),
dot(gl_MultiTexCoord7, gl_Vertex)
);
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
#if CALC_EYE_VECTOR
vec3 eyePos = CAM_POS.xyz - gl_Vertex.xyz;
vec4 eyeVector = vec4(eyePos, dot(eyePos, eyePos));
eyeVector.xyz *= inversesqrt(eyeVector.w); // Normalized vector & distance^2
VAR_fogCoord = getFogCoord(eyeVector.w);
lightingPassVaryings(TANGENT, BINORMAL, gl_Normal, eyeVector.xyz);
#else
VAR_fogCoord = getFogCoord(lengthSQ3f(gl_Vertex, CAM_POS));
lightingPassVaryings(TANGENT, BINORMAL, gl_Normal);
#endif
and the lightingPassVaryings function:
mat3 tangentBasis = mat3(tangent, binormal, normal);
vec4 lightVector;
lightVector.xyz = LIGHT_POS * tangentBasis;
lightVector.w = clamp(lightVector.z * 8.0, 0.0, 1.0);
VAR_lightVector = lightVector;
#if CALC_EYE_VECTOR
eyeVector.xyz = eyeVector.xyz * tangentBasis;
#if PARALLAX_MAPPING
VAR_eyeVector = half3(eyeVector.xyz);
#endif
#if SPECULAR_MAPPING
VAR_lightHalfAngle = half3(normalize(eyeVector.xyz + lightVector.xyz));
#endif
#endif
Other notes:
- You could also use vertex attributes for passing light/camera positions, just like pseudo-instancing. Assuming there are enough available of course.
- You don't need to normalize the incoming normal/tangent in the vertex shader.