Search code examples
javaglsllwjgllight

LWJGL2 Multiple lights not working? All entities are black


So I'm following ThinMatrixs tutorial on multiple lights and point lights. I believe I've followed everything correctly.

enter image description here

I first followed the multiple lights tutorial and none of the entities and terrain were being affected. I thought doing the next tutorial, having to do with attenuation, would resolve this problem. Now all my objects are shaded black.

I'm unsure what could be wrong. Any help would be appreciated.

Code here

Thinmatrix tutorial 25 multiple lights

//FRAGMENT SHADER

#version 400 core

in vec2 pass_textureCoordinates;
in vec3 surfaceNormal;
in vec3 toLightVector[4];
in vec3 toCameraVector;
in float visibility;

out vec4 out_Color;

uniform sampler2D modelTexture;
uniform vec3 lightColour[4];
uniform vec3 attenuation[4];
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 skyColour;

void main(void){


    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitVectorToCamera = normalize(toCameraVector);

    vec3 totalDiffuse = vec3(0.0);
    vec3 totalSpecular = vec3(0.0);

    for(int i = 0; i < 4; i++) {

        float distance = length(toLightVector[i]);
        float attFactor = attenuation[i].x + (attenuation[i].y * distance) + (attenuation[i].z * distance * distance);
        vec3 unitLightVector = normalize(toLightVector[i]);
        float nDot1 = dot(unitNormal, unitLightVector);
        float brightness = max(nDot1, 0.0);
        vec3 lightDirection = -unitLightVector;
        vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
        float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
        specularFactor = max(specularFactor, 0.0);
        float dampedFactor = pow(specularFactor, shineDamper);

        totalDiffuse = totalDiffuse + (brightness * lightColour[i])/attFactor;
        totalSpecular = totalSpecular + (dampedFactor * reflectivity * lightColour[i])/attFactor;
}

  totalDiffuse = max(totalDiffuse, 0.2);


    vec4 textureColour = texture(modelTexture,pass_textureCoordinates);
    if(textureColour.a<0.5) {
        discard;
    }

    out_Color =  vec4(totalDiffuse,1.0) * textureColour + vec4(totalSpecular,1.0);
    out_Color = mix(vec4(skyColour,1.0),out_Color, visibility);

}

VERTEX SHADER:

#version 400 core

in vec3 position;
in vec2 textureCoordinates;
in vec3 normal;

out vec2 pass_textureCoordinates;
out vec3 surfaceNormal;
out vec3 toLightVector[4];
out vec3 toCameraVector;
out float visibility;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[4];

uniform float useFakeLighting;

uniform float numberOfRows;
uniform vec2 offset;

const float density = 0.0035;
const float gradient = 5.0;

void main(void){



    vec4 worldPosition = transformationMatrix * vec4(position,1.0);
    vec4 positionRelativeToCam = viewMatrix * worldPosition;
    gl_Position = projectionMatrix * positionRelativeToCam;
    pass_textureCoordinates = (textureCoordinates/numberOfRows) + offset;

    vec3 actualNormal = normal;
    if(useFakeLighting > 0.5) {
    actualNormal = vec3(0.0,1.0,0.0);
    }

    surfaceNormal = (transformationMatrix * vec4(actualNormal,0.0)).xyz;
    for(int i =0; i< 4;i++) {
        toLightVector[i] = lightPosition[i] - worldPosition.xyz;
    }

    toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;

    float distance = length(positionRelativeToCam.xyz);
    visibility = exp(-pow((distance*density),gradient));
    visibility = clamp(visibility,0.0,0.9);

}

Solution

  • In your StaticShader class:

    for(int i = 0; i < MAX_LIGHTS; i++) {
        location_lightPosition[i] = super.getUniformLocation("lightPosition{" + i + "}");
        location_lightColour[i] = super.getUniformLocation("lightColour{" + i + "}");
        location_attenuation[i] = super.getUniformLocation("attenuation[" + i + "}");
    }
    

    You are using }/{ instead of ]/[, because of that opengl can't find the uniform and the brightness calculation doesn't work.

    If you want to check if a uniform is found just chage this code in your ShaderProgram class:

    protected int getUniformLocation(String uniformName){
        int loc = GL20.glGetUniformLocation(programID,uniformName);
        if(loc==-1) System.err.println("Uniform with name \""+uniformName+"\" not found!");
        return loc;
    }
    

    From the opengl documentation:

    glGetUniformLocation returns an integer that represents the location of a specific uniform variable within a program object. name must be a null terminated string that contains no white space. name must be an active uniform variable name in program that is not a structure, an array of structures, or a subcomponent of a vector or a matrix. This function returns -1 if name does not correspond to an active uniform variable in program, if name starts with the reserved prefix "gl_", or if name is associated with an atomic counter or a named uniform block.

    If it still doesn't work check the individual color values. First check the texture:

    out_Color = textureColour;
    

    Second check the diffuse light:

    out_Color = vec4(totalDiffuse,1.0);
    

    Third check the specular light:

    out_Color = vec4(totalSpecular,1.0);
    

    I hope this helps.