Search code examples
openglglslopengl-3lighting

GLSL OpenGL Each Light Added Get's Darker


I have a scene that works perfectly with one light. However, when I add two more - each new addition becomes dimmer until it is almost unseen. Is the attenuation factors wrong or could it be something else?

    int i = 0;
    for(i=0; i<3; i++){
        if (lights[i].enabled == 1.0){
            //Lighting Attributes
            vec4  light_position    = vec4(lights[i].position,1.0);
            vec4  light_ambient     = lights[i].ambient;
            vec4  light_diffuse     = lights[i].diffuse;
            vec4  light_specular    = lights[i].specular;

            float light_att_constant  = 1.0;
            float light_att_linear    = 0.0;
            float light_att_quadratic = 0.01;
            float light_shine         = 1.0;

            //Object Attributes
            vec3  obj_position      = n_vertex;
            vec3  obj_normals       = n_normal;
            vec4  obj_color         = n_colors;

            //Calc Distance
            vec3  distance_LO       = (obj_position - light_position.xyz);
            float distance          = length(distance_LO);

            //Normalize some attributes
            vec3  n_light_position  = normalize(distance_LO);

            //Apply ambience
            finalColor              *= light_ambient * global_ambient;

            //Calc Cosine of Normal and Light
            float NdotL             = max(dot(obj_normals, n_light_position),0.0);

            //Calc Eye Vector (negated position)
            vec3  eye_view          = -obj_position;

            //Check if Surface is facing the Light
            if (NdotL > 0){
                //Apply lambertian reflection
                finalColor += obj_color * light_diffuse * NdotL;

                //Calc the half-vector
                vec3 half_vector = normalize(light_position.xyz + eye_view);

                //Calc angle between normal and half-vector
                //See the engine notebook for a diagram.
                float NdotHV = max(dot(obj_normals, half_vector), 0.0);

                //Apply Specularity
                finalColor += obj_color * light_specular * pow(NdotHV, light_shine);
            }

            //Calc Attenuation
            float attenuation = light_att_constant / ((1 + light_att_linear * distance) *
                                1 + light_att_quadratic * distance * distance);

            //Apply Attenuation
            finalColor = finalColor * attenuation;
        }
    }

    color = vec4(finalColor.rgb, 1.0);

Solution

  • You multiply in your colours. This means that shadows will get darker.

    If you have an area around some relative brightness 1/2, then you multiply it by 1/2 (contribution from that light), you'll get 1/4.

    If you have Photoshop or Gimp you can test this yourself with the Multiply blending mode, and three circles, pure red, pure green and pure blue and overlap them. Compare Multiply to Linear Dodge (the plus operation in Photoshop.)

    Here's an example.

    Example of RGB operations, plus versus multiply

    You'll most certainly want an additive effect, that is, add the terms together.