Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSL calculating color vector from multiple lights

Tags:

opengl

glsl

I'm using my own (not opengl built in) light. This is my fragment shader program:

#version 330

in vec4 vertexPosition;
in vec3 surfaceNormal;
in vec2 textureCoordinate;
in vec3 eyeVecNormal;

out vec4 outputColor;

uniform sampler2D texture_diffuse;
uniform bool specular;
uniform float shininess;

struct Light {
    vec4 position;
    vec4 ambientColor;
    vec4 diffuseColor;
    vec4 specularColor;
};

uniform Light lights[8];

void main()
{
    outputColor = texture2D(texture_diffuse, textureCoordinate);
    for (int l = 0; l < 8; l++) {
        vec3 lightDirection = normalize(lights[l].position.xyz - vertexPosition.xyz);
        float diffuseLightIntensity = max(0, dot(surfaceNormal, lightDirection));

        outputColor.rgb += lights[l].ambientColor.rgb * lights[l].ambientColor.a;
        outputColor.rgb += lights[l].diffuseColor.rgb * lights[l].diffuseColor.a * diffuseLightIntensity;
        if (specular) {
            vec3 reflectionDirection = normalize(reflect(lightDirection, surfaceNormal));
            float specular = max(0.0, dot(eyeVecNormal, reflectionDirection));
            if (diffuseLightIntensity != 0) {
                vec3 specularColorOut = pow(specular, shininess) * lights[l].specularColor.rgb;
                outputColor.rgb += specularColorOut * lights[l].specularColor.a;
            }
        }
    }
}

Now the problem is, that when i have 2 light sources with say ambient color vec4(0.2f, 0.2f, 0.2f, 1.0f) the ambient color on model will be vec4(0.4f, 0.4f, 0.4f, 1.0f) because i simply add it to the outputColor variable. How can i calculate a single ambient and a single diffuse color variables for multiple lights, so i would get a realistic result?

like image 424
Qualphey Avatar asked Mar 20 '13 22:03

Qualphey


1 Answers

Here's a fun fact: lights in the real world do not have ambient, diffuse, or specular colors. They emit one color. Period (OK, if you want to be technical, lights emit lots of colors. But individual photons don't have "ambient" properties. They just have different wavelengths). All you're doing is copying someone who copied OpenGL's nonsense about ambient and diffuse light colors.

Stop copying someone else's code and do it right.

Each light has a color. You use that color to compute the diffuse and specular contributions of that light to the object. That's it.

Ambient is a property of the scene, not of any particular light. It is intended to represent indirect, global illumination: the light reflected from other objects in the scene, as taken as a general aggregate. You don't have ambient "lights"; there is only one ambient term, and it should be applied once.

like image 149
Nicol Bolas Avatar answered Oct 21 '22 04:10

Nicol Bolas