Lighting a cube

I am trying to learn opengl 2 lighting. I have basic per pixel lighting working, but when I try light a cube, each face is lit separately. Each faces color remains static all over the face, which is not how I want it to look. What is a way fix this?

I bet that you are not interpolating light/vertex position correctly.

Here is my fragment shader, it does not seem like I am doing anything wrong. I am using a static light position since I am just learning.

#version 120
varying vec3 f_color;
varying vec3 f_normal;
varying vec3 f_coord;
uniform mat4 m,v;
uniform mat3 nm; //normal matrix
vec3 ambient = vec3(0.4,0.4,0.4);
vec3 lightcolor = vec3(1.0,1.0,1.0);
void main(void) {
  vec3 lightpos = vec3(0.4,0.8,0.4);
  vec4 coord = vec4(m*vec4(f_coord,1.0));
  vec3 normnorm = normalize(f_normal);
  vec3 dirtolight = normalize(lightpos-vec3(coord));
  float distance = length(dirtolight);
  float diffuse = clamp(dot(normnorm,dirtolight),0.0,1.0);
  vec3 lightweight = (ambient+lightcolor*diffuse);
  vec4 color = vec4(f_color*lightweight,1.0);
  gl_FragColor = color;
}
vec4 coord = vec4(m*vec4(f_coord,1.0));

You are still doing redudant matrix math at fragment shader. This might work but nobody never does that and there is no point to learn wrong things at first becouse then you need to unlearn those next and that can be hard.

You calculate position at vertex shader and then send that to fragment shader. And this will then be interpolated smoothly for fragments.

Also you don’t calculate vector length after normalization becouse normalization is used for setting the length to 1. So you are losing the information before you try to calculate it.

And your “static light position” is static in view space, meaning that it follows the camera (assuming you do light calculations in view space).

Ok so I’ve moved matrix math into the vertex shader. I am still getting the same result though. The light is still flat across each face. Here is my fragment shader:

#version 120
varying vec3 f_color;
varying vec3 f_normal;
varying vec3 f_coord;
uniform mat4 m,v;
uniform mat3 nm; //normal matrix
vec3 ambient = vec3(0.2,0.2,0.2);
vec3 lightcolor = vec3(0.8,0.8,0.8);
void main(void) {
  vec3 lightpos = vec3(0.4,0.8,0.4);
  vec3 normnorm = normalize(f_normal);
  vec3 dirtolight = lightpos-f_coord.xyz;
  float distance = length(dirtolight);
  float diffuse = clamp(dot(normnorm,normalize(dirtolight)),0.0,1.0);
  vec3 lightweight = (ambient+lightcolor*diffuse);
  vec4 color = vec4(f_color*lightweight,1.0);
  gl_FragColor = color;
}

I’ll work on light position as the last steps. At the moment it does not appear to move with the camera.

Normalizing f_coord in the vertex shader seems to help. When I do this the light seems to become static during model rotations. Is this the problem with the static light position, or is this something I should not be doing?

Think a bit what normalization does and how you use f_coord.

Tip: Directions are normalized. Positions not.

Nevermind, I’ve fixed it.

If you want others to benefit, post the source of the whole thing…

Wasn’t this a skateboard movie?

Thing is, I don’t know how I fixed it. I have been trying to recreate the whole thing in libgdx and I am running into the same problem. Anyway, here are the shaders that worked:

#version 120
varying vec3 f_color;
varying vec3 f_normal;
varying vec3 f_coord;
uniform mat4 m,v;
uniform mat3 nm; //normal matrix
uniform vec3 lightpos;
vec3 ambient = vec3(0.4,0.4,0.4);
vec3 lightcolor = vec3(0.8,0.8,0.8);
void main(void) {
  vec3 normnorm = normalize(f_normal);
  vec3 dirtolight = lightpos-(f_coord);
  float distance = length(dirtolight);
  float diffuse = max(dot(normnorm,normalize(dirtolight)),0.0);
  vec3 lightweight = (ambient+lightcolor*diffuse);
  vec4 color = vec4(f_color*lightweight,1.0);
  gl_FragColor = color;
}
#version 120
attribute vec3 coord;
attribute vec3 normal;
attribute vec3 color;
uniform mat4 matrix;
uniform mat4 m,v;
uniform mat3 nm;
varying vec3 f_color;
varying vec3 f_normal;
varying vec3 f_coord;
//varying float diffuse;
void main() {
   //vec3 lightpos = vec3(0.4,0.8,0.4);
   f_color = color;
   f_coord = (vec3(m*vec4(coord,1.0)));
   f_normal = normalize(nm*normal);
   gl_Position = matrix * vec4(coord,1.0);
}

Oh… Figured it out. When the light gets more a certain distance above an object it begins to look like per vertex lighting.