openglglsllightingphong

Ambient and Specular lighting not working correctly in GLSL


In my lighting scene, for some reason the ambient lighting isn't working at all. The whole model is the same brightness, no matter which way it is facing. I tried getting rid of the attenuation but it still has the same results. Along with that, the specular lighting is always shining, no matter where the camera is. It is supposed to shine based on player position. Here is a screenshot of the ambient problem: Imgur.com

As you can see, the part of the sphere that is facing away from the light (located at [0.0,4.0,0.0]) is the same color as the part facing the light. The ambient factor is supposed to be 0.2 of the fragment color.

Vertex shader source:

layout(location = 0) in vec3 positions;
layout(location = 1) in vec2 texCoords;
layout(location = 2) in vec3 normals;

out vec3 new_normal;
out vec3 worldPos_out;
out vec2 pass_texCoords;

struct Matrices {
    mat4 projection;
    mat4 worldMatrix;
    mat4 modelMatrix;
    mat3 normalMatrix;
};

uniform Matrices mat;

void main(void)
{
    pass_texCoords = texCoords;

    vec4 newPosition = vec4(positions, 1);

    vec4 worldPos = (mat.modelMatrix * newPosition);
    mat4 Camera = mat.projection * mat.worldMatrix;
    gl_Position = (Camera *  worldPos);

    new_normal = mat.normalMatrix * normals;
    worldPos_out = worldPos.xyz;
}

Fragment shader source:

in vec3 new_normal;
in vec3 worldPos_out;
in vec2 pass_texCoords;

out vec4 outColor;
uniform vec3 viewPos;

#define MAX_LIGHTS 50

struct Material {
    sampler2D diffuseMap;
    sampler2D specularMap;
    vec3 specular;
    float shininess;
};
uniform Material material;

struct Light {
    vec3 position;
    vec3 color;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float radius;
};
uniform Light Lights[MAX_LIGHTS];
uniform int numLights;

struct Math {
    float constant;
    float linear;
    float quadratic;
} math;

vec3 applyPointLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 surfaceColor, vec3 surfaceSpecular) {
    vec3 lightDir = normalize(light.position - fragPos);
    //Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    //Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    //Attenuation
    float distance = length(light.position - fragPos);
    float attenuation = 5.0 / (math.constant + math.linear * distance +
                        math.quadratic * (distance * distance));

    vec3 ambient = light.ambient * surfaceColor;
    vec3 diffuse = light.diffuse * surfaceColor * light.color;
    vec3 specular = light.specular * surfaceSpecular * light.color;
    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;

    return (ambient + diffuse + specular);
}

void main(void)  {
    vec3 surfaceColor = vec3(texture(material.diffuseMap, pass_texCoords));
    vec3 surfaceSpecular = vec3(texture(material.specularMap, pass_texCoords));

    vec3 unitNormal = normalize(new_normal);
    vec3 viewDir = normalize(viewPos - worldPos_out);

    math.constant = 1.0;
    math.linear = 0.09;
    math.quadratic = 0.032;

    vec3 linearColor;
    for(int i = 0; i < numLights; i++)
        linearColor += applyPointLight(Lights[i], unitNormal, worldPos_out, viewDir, surfaceColor, surfaceSpecular);

    float gamma = 2.2;
    vec3 fragColor;
    fragColor.rgb = pow(linearColor.rgb, vec3(1.0/gamma));

    outColor = vec4(linearColor, 1.0);
}

Solution

  • In your applyPointLight function, you're not using the diff and spec variables, which are presumably the light-dependent changes to diffuse and specular. See if the following works:

    vec3 diffuse = light.diffuse * surfaceColor * light.color * diff;
    vec3 specular = light.specular * surfaceSpecular * light.color * spec;