1
$\begingroup$

This is what I'm doing:

vertex shader:

#version 400
layout ( location = 0 ) in vec3 vertex_position;
layout ( location = 1 ) in vec3 vertex_normal;

uniform mat4 ModelViewMatrix; //view*model
uniform mat3 NormalMatrix; //transpose(inverse(modelviewmatrix))) //top 3x3 row of model*view
uniform mat4 priv_mat; //projection*view*model

out vec3 normal;
out vec3 position;

void main()
{
  normal=normalize(NormalMatrix*vertex_normal);
  position=vec3(ModelViewMatrix*vec4(vertex_position,1.0));
  gl_Position=priv_mat*vec4(vertex_position,1.0);
}

fragment shader:

#version 400
in vec3 normal;
in vec3 position;

uniform vec4 LightPosition; // *needs to be in view-space* (view*lightpos)
uniform vec3 LightIntensity;

uniform vec3 Kd;            // Diffuse reflectivity
uniform vec3 Ka;            // Ambient reflectivity
uniform vec3 Ks;            // Specular reflectivity
uniform float Shininess;    // Shininess

vec3 ads( ){
    vec3 n = normal;
    vec3 s = normalize( vec3(LightPosition) - position ); 
    vec3 v = normalize( vec3(-position)); 
    vec3 r = reflect( -s, n );
return 
    LightIntensity * 
    ( Ka + 
    Kd * max( dot(s, n), 0.0 ) +  
    Ks * pow( max( dot(r,v), 0.0 ), Shininess ) );
}

void main()
{
     gl_FragColor = vec4(ads(), 1.0);
}

But when I run it, I get this:

shouldn't the light be correct?

Where the light doesn't just come from the wrong spot, but it also doesn't change when I move the planet around, like so

I can spin the asteroid, but the light doesn't come from where it should

Where the diffuse value somehow gets the wrong direction? The math is beyond me however.

So, the diffuse value is calculated by getting the dot(s,n), where s is (lightposition - position), and position is (view * model * vertex_position). But like you can see, the results are not as expected

$\endgroup$
1

1 Answer 1

4
$\begingroup$

It seems to me, to be that your different positions and normals are not in the same space. Having them in the same space is important because else it might think the normal is pointing left while it should point to the right.

If you don't know what I mean with space in this context it's basically a coordinate system. Think about a grid, grid A. On grid A you have a point. Then you have another grid, grid B. You place grid A on grid B. If you move grid A around, the point on grid A does not move relative to grid A. It does however move relative to grid B, so they are different spaces. Hope that clarifies it for you, if not I am so sorry.

You have a few coordinate spaces:

  • Local: This is the vertex locations relative to the model position.
  • World: This is the location relative to the actual world origin.
  • View: This is the location relative to the camera.

You have the light position, vertex position and normal:

  • Light position is in world space.
  • Normal is in world space, since you multiplied it with a model matrix making it go from local to world.
  • Vertex position is in view space, since you put it to world space with the model matrix and then to view space with the view matrix.

Do you see that you have one of the three variables in a different space? I have a strong feeling this is the problem and if you do not multiply the vertex position with the view matrix, in the vertex shader, this should be fixed.

I hope that this helps you and good luck!

$\endgroup$
2
  • $\begingroup$ Yes, you are right. When I multiply position with model only, and not view, I get the right angle. Thank you very much. (I think I understand too) $\endgroup$
    – Charlie
    Mar 21, 2017 at 8:35
  • $\begingroup$ It is worth mentioning that placing lightposition into viewspace was an even better solution ;) $\endgroup$
    – Charlie
    Mar 29, 2017 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.