Original Post
Hi all, I'm having a problem with the lighting in my engine which uses OpenGL and GLSL. My test scene has one infinite directional light which points downwards and the problem is that when the camera moves away from the 0,0,0 world position the specular lighting is incorrect. When the camera is near 0,0,0 all lighting appears accurate. (as shown in the first image)
The light and camera positions are passed to the shader in world space and the tangent, bitangent and normal vectors are precalculated and updated through the gl_MultiTexCoord variables. Vertex shader: Fragment shader: Any help or ideas would be great. Thanks all
The light and camera positions are passed to the shader in world space and the tangent, bitangent and normal vectors are precalculated and updated through the gl_MultiTexCoord variables. Vertex shader:
uniform vec3 lightPosition;
uniform vec3 cameraPosition;
varying vec2 texCoord;
varying vec3 lightDirection;
varying vec3 cameraDirection;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 dirLight = lightPosition;
lightDirection.x = dot(dirLight, gl_MultiTexCoord1);
lightDirection.y = dot(dirLight, gl_MultiTexCoord2);
lightDirection.z = dot(dirLight, gl_MultiTexCoord3);
vec3 dirCamera = cameraPosition - gl_Vertex.xyz;
cameraDirection.x = dot(dirCamera, gl_MultiTexCoord1);
cameraDirection.y = dot(dirCamera, gl_MultiTexCoord2);
cameraDirection.z = dot(dirCamera, gl_MultiTexCoord3);
texCoord = gl_MultiTexCoord0.xy;
}
varying vec2 texCoord;
varying vec3 lightDirection;
varying vec3 cameraDirection;
uniform sampler2D texture_0;
uniform sampler2D texture_1;
uniform sampler2D texture_2;
uniform float parallaxScale;
void main()
{
vec3 light = normalize(lightDirection);
vec3 camera = normalize(cameraDirection);
float height = texture2D(texture_2, texCoord).x;
vec2 offset = texCoord + camera.xy * (height - 0.5) * parallaxScale;
vec4 base = texture2D(texture_0, texCoord);
vec3 normal = texture2D(texture_1, offset).xyz * 2.0 - 1.0;
float diffuse = max(dot(light, normal), 0.0);
float specular = pow(clamp(dot(reflect(-light, normal), camera), 0.0, 1.0), 32.0);
gl_FragColor = base * diffuse + specular;
}