My light is positioned at vec3(0, 0, 2) which is in front of an object at vec3(0, 0, 0). If I don't rotate the object, everything seems to look fine:
The problem occurs when I rotate the object, the object's lit area seems to rotate with the object. Instead of just shining the faces looking at the light.
In fact here's another strange example but with specular added. The effect is correct in the first the rotation, the second it's dark, and in the third it's back to good again
I can't seem to figure out what the problem is with my shader. I even tried calculating the normal matrix in glsl, just in case my implementation was wrong, but I get the same results:
nrms = mat3(transpose(inverse(model))) * normals;
// and
nrms = normalMat * normals;
// both get same results.
I really don't think it has to do with the normals, the light calculations visually seem okay, as long as I don't rotate the object though.
In fact, I can translate and rotate the camera and the lighting is still good, again, as long as I don't rotate the object. By the way, camera rotation is not considered in the calculations since I'm passing the camera.transform.position vec3 to calculate the toCam vector I use in my lighting calculations.
There's clearly something I'm doing wrong. I'm guessing it has to do with what space am I calculating against. It's almost like I'm calculating based on the model's local space instead of world.
Hopefully somebody can identify what it is though, I'll share the vertex and frag shaders below. I didn't include the specular portion though. thanks a lot!
Vertex
#version 300 es
#ifdef GL_ES
precision mediump float;
#endif
layout (location= 0) in vec3 vertex;
layout (location= 1) in vec3 normals;
layout (location= 2) in vec2 uv;
layout (location= 3) in vec3 colors;
out vec3 fragPos;
out vec3 baseColors;
out vec3 nrms;
out vec3 camPosition;
uniform vec3 camera;
uniform mat3 normalMat;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 mvp;
void main() {
// nrms = mat3(transpose(inverse(model))) * normals;
baseColors = colors;
nrms = normalMat * normals;
fragPos = vec3(model * vec4(vertex, 1.0));
camPosition = camera;
gl_Position = mvp * vec4(fragPos, 1.0);
}
Frag
#version 300 es
#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.14159265359
#define TWO_PI 6.28318530718
#define NUM_LIGHTS 2
in vec3 fragPos;
in vec3 baseColors;
in vec3 nrms;
in vec3 camPosition;
out vec4 color;
struct Light {
vec3 position;
vec3 intensities;
float attenuation;
float ambient;
};
Light light;
void main () {
light.position.x = 0.0;
light.position.y = 0.0;
light.position.z = 2.0;
light.intensities.r = 1.0;
light.intensities.g = 1.0;
light.intensities.b = 1.0;
light.ambient = 0.005;
vec4 base = vec4(baseColors, 1.0);
vec3 normals = normalize(nrms);
vec3 toLight = normalize(light.position - fragPos);
vec3 toCamera = normalize(camPosition - fragPos);
// Ambient
vec3 ambient = light.ambient * base.rgb * light.intensities;
// Diffuse
float diffuseBrightness = max(0.0, dot(normals, toLight));
vec3 diffuse = diffuseBrightness * base.rgb * light.intensities;
// Composition
vec3 linearColor = ambient + (diffuse);
vec3 gamma = vec3(1.0 / 2.2);
color = vec4( pow(linearColor, gamma), base.a);
}