1

Problem: The direction of the directional light changes when the position of the object changes.

I watched posts with a similar problem:

Directional light in worldSpace is dependent on viewMatrix

OpenGL directional light shader

Diffuse lighting for a moving object

Based on these posts, I tried to apply this:

#version 300 es
uniform mat4 u_mvMatrix;
uniform mat4 u_vMatrix;
in vec4 a_position;
in vec3 a_normal;
const vec3 lightDirection = vec3(-1.9, 0.0, -5.0);
...
void main() {
    vec3 modelViewNormal = vec3(u_mvMatrix * vec4(a_normal, 0.0));
    vec3 lightVector = lightDirection * mat3(u_vMatrix);
    float diffuseFactor = max(dot(modelViewNormal, -lightVector), 0.0);
    ...
}

But the result looks like this:

enter image description here

Tried also:

vec3 modelViewVertex = vec3(u_mvMatrix * a_position);
vec3 lightVector = normalize(lightDirection - modelViewVertex);
float diffuseFactor = max(dot(modelViewNormal, lightVector), 0.0);

And:

vec3 lightVector = normalize(lightDirection - modelViewVertex);
lightVector = lightVector * mat3(u_vMatrix);

But the result:

enter image description here

What changes need to be made to the code so that all objects are lit identically?

Thanks in advance!

Solution: In practice, creating directional lighting was not such an easy task for me. On Rabbid76 advice, I changed the order of multiplication. On another Rabbid76 advice (post), I also created a custom point of view:

Matrix.setLookAtM(pointViewMatrix, rmOffset:0, eyeX:3.8f, eyeY:0.0f, eyeZ:2.8f,
        centerX:0.0f, centerY:0f, centerZ:0f, upX:0f, upY:1.0f, upZ:0.0f)

Also calculated eye coordinates and light vector, although the camera is set in [0, 0, 0]:

#version 300 es
uniform mat4 u_mvMatrix;
uniform mat4 u_pointViewMatrix;
in vec4 a_position;
in vec3 a_normal;
const vec3 lightPosition = vec3(-5.0, 0.0, 1.0);
...
void main() {
    // transform normal orientation into eye space
    vec3 modelViewNormal = vec3(u_mvMatrix * vec4(a_normal, 0.0));
    vec3 modelViewVertex = vec3(u_mvMatrix * a_position); // eye coordinates
    vec3 lightVector = normalize(lightPosition - modelViewVertex);
    lightVector = mat3(u_pointViewMatrix) * lightVector;
    float diffuseFactor = max(dot(modelViewNormal, lightVector), 0.0);
    ...
}

Only after these steps did the picture become good:

enter image description here

Small differences are probably caused by a big perspective.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
alexrnov
  • 2,346
  • 3
  • 18
  • 34

1 Answers1

1

The vector has to be multiplied to the matrix from the right. See GLSL Programming/Vector and Matrix Operations.

vec3 lightVector = lightDirection * mat3(u_vMatrix);

vec3 lightVector = mat3(u_vMatrix) * lightDirection;

If you want to dot the light calculations in view space, then the normal vecotr has to be transformed form object (model) space to view space by the model view matrix and the light direction hss to be transformed form world space to view space, by the view matrix. For instance:

void main() {
    vec3  modelViewNormal = mat3(u_mvMatrix) * a_normal;
    vec3  lightVector     = mat3(u_vMatrix) * lightDirection;
    float diffuseFactor   = max(dot(modelViewNormal, -lightVector), 0.0);

    // [...]
} 
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • 1
    Thanks You! Strange, but the result is a mirror image of figure 2. I am sure that your answer is right. I guess that mistaken somewhere else. – alexrnov May 23 '20 at 16:05
  • 1
    In case you were wondering, I obtained constant directional lighting as described in the solution. Thanks You for the advices! – alexrnov May 27 '20 at 07:02