Directional lighting is not constant in OpenGL ES 2.0/3.0

柔情痞子 提交于 2021-01-28 13:42:23

问题


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:

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:

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:

Small differences are probably caused by a big perspective.


回答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);

    // [...]
} 


来源:https://stackoverflow.com/questions/61973160/directional-lighting-is-not-constant-in-opengl-es-2-0-3-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!