GLSL Phong light "reversed" (or "inverted")?

Started by
3 comments, last by Ryokeen 8 years, 8 months ago

Hello, everyone!

I have a problem with my Phong shader... I deleted all the textures, normal maps and specular maps to make a clean test for light in the following scene. There are five spheres in a line (each sphere has exactly the same Z and Y coordinates and a different X coordinate). Above and to the right of the spheres there's a light source. It has the same Z coordinates with the spheres, but it is shifted to the right and upwards. Somehow the light is distributed in a strange fashion, so that the sphere closer to the light source 'reflects' less light towards the viewpoint (camera)...

[attachment=28500:problem.jpg]

From what my eyes are used to seeing, the leftmost sphere should look like the rightmost one, and vice versa. But the actual lit area of the spheres seems to be in reverse relation with the position of the light source. I don't really know how to express that in proper terms.
Can anybody explain this? It does not look intuitive, I think the light is actually reversed somehow, but I cannot understand the reason (must be some direction vector in the shader code or something)...

Here's the basic phong shader I'm using:


#version 300 es

in vec3 position;
in vec3 normal;
in vec2 texcoord;

out vec4 normal0;
out vec4 position0;

uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

void main () {
    
    gl_Position = modelViewProjectionMatrix * vec4 (position, 1.);
    position0 = modelMatrix * vec4 (position, 1.);
    normal0 = modelMatrix * vec4 (normal, 0.);
}


#version 300 es

// fragment properties
in highp vec4 position0;
in highp vec4 normal0;

// camera properties
uniform highp vec3  cameraPosition;

// light properties
uniform highp vec3  lightPosition;
uniform lowp  vec4  lightColor;

// material properties
uniform lowp  vec4  emissiveColor;
uniform lowp  vec4  diffuseColor;
uniform lowp  vec4  specularColor;
uniform highp float shininess;

// global ambient light
uniform lowp  vec4  ambientColor;

// output
out     highp vec4  fragmentColor;

void main () {
    
    // emissive component is as it is
    
    // diffuse component
    highp vec4 N = normalize (normal0);
    highp vec4 L = normalize (vec4 (lightPosition, 1.) - position0);
    
    fragmentColor = (emissiveColor +
                     ambientColor +
                     max (dot (N, L), 0.) * lightColor * diffuseColor +
                     pow (max (dot (reflect (-L, N), normalize (vec4 (cameraPosition, 1.) - position0)), 0.), shininess) * lightColor * specularColor);
}

Advertisement

Check your dot product calculations, and you seem to have a 'normalMatrix' in your vert shader you never use.

Try below instead, since at the moment you multiply the normal by the model matrix which translates the normals.


normal0 = mat3(transpose(inverse(modelMatrix)))*normal;

Shouldn't be


normal0 = ve4(mat3(modelMatrix)*normal,0.0);

enough ? Just rotation, no translation

Ryooken that is what the code I gave was doing, but you are forgetting about the scale that is in the modelMatrix, my piece of code is not very efficient but it does deal with non-uniform scales whereas your code does not. My code is also called the normal matrix

Ah sure you're right, totally forgot about scaling

This topic is closed to new replies.

Advertisement