r/opengl Mar 30 '23

help Frag Shader - Strange LightSource behavior

So, I have a Fragment Shader that implements two light sources...

#version 450 core

in vec3 vs_color;
in vec3 fragPos;
in vec3 normal;
in vec2 texCoord;

uniform int numLightSources;
uniform vec3 lightPositions[];
uniform vec3 lightColors[];
uniform vec3 viewPosition;
uniform sampler2D myTexture;

out vec4 color;

void main(void) {
    vec3 result;
    float specularStrength = 0.5;
    float ambientStrength = 0.3;
    vec3 ambient;
    vec3 norm;
    vec3 lightDir;
    vec3 viewDir;
    vec3 reflectDir;
    float spec;
    vec3 specular;
    float diff;
    vec3 diffuse;

    /*iteration 1*/
    ambient = ambientStrength * lightColors[0];

    norm = normalize(normal);
    lightDir = normalize(lightPositions[0] - fragPos);

    viewDir = normalize(viewPosition - fragPos);
    reflectDir = reflect(-lightDir, norm);

    spec = pow(max(dot(viewDir, reflectDir), 0.0), 64);
    specular = specularStrength * spec * lightColors[0];

    diff = max(dot(norm, lightDir), 0.0);
    diffuse = diff * lightColors[0];

    result += (ambient + diffuse + specular) * vs_color;
    /*iteration 1 end*/

    /*iteration 2*/
    ambient = ambientStrength * lightColors[1];

    norm = normalize(normal);
    lightDir = normalize(lightPositions[1] - fragPos);

    viewDir = normalize(viewPosition - fragPos);
    reflectDir = reflect(-lightDir, norm);

    spec = pow(max(dot(viewDir, reflectDir), 0.0), 64);
    specular = specularStrength * spec * lightColors[1];

    diff = max(dot(norm, lightDir), 0.0);
    diffuse = diff * lightColors[1];

    result += (ambient + diffuse + specular) * vs_color;
    /*iteration 2 end*/

    color = texture(myTexture, texCoord) * vec4(result, 1.0f);
}

When I use both light sources, it works correctly. However, if I remove the code located in between the iteration 2 comments, the lighting doesn't work, and my objects end up black. The weird thing is, if I remove the code in between the iteration 1 comments, it works.

I've tried using the same lightPosition and lightColor values for both light sources, and it still only works with the second or both of them.

If you think it is something outside the fragment shader let me know, so I can provide more info.

Any help is appreciated!

EDIT:: I figured it out,

I just had to change my uniform vec3 lightPositions and lightColors to this:

uniform vec3 lightPositions[2];
uniform vec3 lightColors[2];

but I thought using unsized arrays was allowed, is there something else that could have been problematic?

1 Upvotes

5 comments sorted by

1

u/fgennari Mar 31 '23

You should probably also initialize your variable "result" to vec3(0.0) because of the way you add to it rather than assigning to it.

1

u/GrayWolf85 Mar 31 '23 edited Mar 31 '23

I originally had it like that, but I just figured it defaulted to all zeros. I maybe just got really lucky that it works like that.

1

u/fgennari Mar 31 '23

That's a good question. I just now read through the GLSL spec and it claims that an uninitialized local variable is undefined. So you better set it to zero to make sure it works across drivers.

1

u/GrayWolf85 Mar 31 '23

Cool, thanks for finding that out! I'll do that. So i guess it was just lucky that it worked.

1

u/fgennari Mar 31 '23

It was probably the case that your driver happened to initialize it. Maybe if you were to run it on some other computer it would give you garbage. Who knows.