4
\$\begingroup\$

I have looked this up, and found some answers and people said that if uniforms aren't important to the final output than they get thrown away by the compiler. However, in my case they are being used but still being returned -1. I have spent hours trying to figure this out, but each time it happens. It is weird because I have other uniforms used in the exact same context but don't get thrown away.

My problem is that my shader compiles and runs perfectly until I try to use the applyDirLight function in my fragment shader. The uniforms being used for the variables are always -1 when I use glGetUniformLocation. My uniforms for point lights are working fine. I don't get compile errors from it, but instead I get program linking errors. Every single uniform inside the struct DirLight always returns -1 in my Java code.

My Java integer array of uniforms is all -1 in the directional light array, but not the point light array.

    pointLights = new int[amtPointLights*6];
    for(int i = 0; i < amtPointLights; i++) {
        int index = i * 6;
        pointLights[index+0] = shader.getUniformLocation("PointLights["+(i)+"].position");
        pointLights[index+1] = shader.getUniformLocation("PointLights["+(i)+"].color");
        pointLights[index+2] = shader.getUniformLocation("PointLights["+(i)+"].ambient");
        pointLights[index+3] = shader.getUniformLocation("PointLights["+(i)+"].diffuse");
        pointLights[index+4] = shader.getUniformLocation("PointLights["+(i)+"].specular");
        pointLights[index+5] = shader.getUniformLocation("PointLights["+(i)+"].radius");
    }

    System.out.println(Arrays.toString(pointLights));

    dirLights = new int[amtDirLights*5];
    for(int i = 0; i < amtDirLights; i++) {
        int index = i * 5;
        dirLights[index+0] = shader.getUniformLocation("DirLights["+(i)+"].direction");
        dirLights[index+1] = shader.getUniformLocation("DirLights["+(i)+"].color");
        dirLights[index+2] = shader.getUniformLocation("DirLights["+(i)+"].ambient");
        dirLights[index+3] = shader.getUniformLocation("DirLights["+(i)+"].diffuse");
        dirLights[index+4] = shader.getUniformLocation("DirLights["+(i)+"].specular");
    }

    System.out.println(Arrays.toString(dirLights));

If you know why it is being return -1 it would help me a bunch.

#version 330 core

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

out vec4 outColor;
uniform vec3 viewPos;

#define MAX_LIGHTS 25

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

struct PointLight {
    vec3 position;
    vec3 color;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float radius;
};
uniform PointLight PointLights[MAX_LIGHTS];

struct DirLight {
    vec3 direction;
    vec3 color;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform DirLight DirLights[MAX_LIGHTS];

uniform int amtPointLights;
uniform int amtDirLights;

vec3 applyPointLight(PointLight 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 = 1.0 / (1.0 + light.radius * pow(distance, 2));

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

    return light.color * (attenuation * (ambient + diffuse + specular));
}

vec3 applyDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 surfaceColor, vec3 surfaceSpecular) {
    vec3 lightDir = normalize(-light.direction);
    //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);

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

    return light.color * (ambient + diffuse + specular);
}

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

    vec3 unitNormal;
    if(material.usingNormalMap == 1) {
        unitNormal = normalize(texture(material.normalMap, pass_texCoords).rgb);
    } else {
        unitNormal = normalize(new_normal);
    }
    vec3 viewDir = normalize(viewPos - worldPos_out);

    vec3 linearColor = vec3(0,0,0);
    for(int i = 0; i < amtPointLights; i++) {
        linearColor += applyPointLight(PointLights[i], unitNormal, worldPos_out, viewDir, surfaceColor.rgb, surfaceSpecular);
    }
    for(int i = 0; i < amtDirLights; i++) {
        linearColor += applyDirLight(DirLights[i], unitNormal, viewDir, surfaceColor.rgb, surfaceSpecular);
    }

    if(amtPointLights == 0 && amtDirLights == 0)
        linearColor = surfaceColor.rgb;

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

    outColor = vec4(fragColor, alpha);
}
\$\endgroup\$
  • \$\begingroup\$ There are many reasons for that, but can you make sure (1) that the string looks to be OK, and that (2) your shader is active (glUseProgram)? \$\endgroup\$ – MaKo Oct 24 '15 at 19:54
  • \$\begingroup\$ I know that the shader is active because all of the other uniforms inside the shader are working just fine. It's only the directional light ones that won't work. I triple check the Strings because that was my first guess. I even copied them straight from the shader, and still not working. \$\endgroup\$ – andrew3ds Oct 24 '15 at 19:58
1
\$\begingroup\$

My assumption is that when you add the applyDirLight you are exceeding the limit of the accepted number of uniform components per shader stage which is implementation dependent. Once you activate applyDirLight you are adding more than 25 uniform variables, that said vec4 is 4 components, vec3 is 3 components, so in your case you are adding around 25*3*5 components. I highly suspect this is the reason.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.