Question

I've implemented a simple shader with the following properties: - Material (ambient, diffuse and specular) - Base color which defines the color of the object - Light Color

Fragment shader: (vColor is the base color of the object)

  vec3 lightDir = normalize(vec3($uLightPos.xyz - vPosInEye.xyz));
  vec3 viewerPos = normalize(vec3(-vPosInEye.xyz));
  vec3 specularReflection = normalize(-reflect(lightDir, vNormal));

  float diffFactor = max(dot(vNormal, lightDir), 0.0);
  vec4 Id = $uIdColor * diffFactor * vColor ;
  vec4 Ia = $uIaColor * vColor;
  vec4 Is = clamp($uIsColor * pow(max(dot(specularReflection, viewerPos), 0.0), $uIsShininess), 0.0, 1.0);

  gl_FragColor = (Id + Ia + Is) + $uLightColor;

As you can see I multiply the ambient color of the material with the base color of the object. This seems to be right because I want to mix these colors together.

In the book "Open GL ES 2.0 Programming guide" this is implemented the same way. In the last line I add the color of the light.
I tried to multiply the color at first but then I got strange result: yellow * blue resulted in black (which is clear because yellow is (1.0, 1.0, 0) and blue (0.0, 0.0, 1.0) so I replaced * with +. This seems to produce the correct color (white).

So my question is: Is there a rule of thumb when I have to multiply two colors together and when to add them?

Was it helpful?

Solution

You need to multiply when you want to modulate one color by another. For example if you have a blue material, you want to multiply the light falling on it by the color of the material because it should only reflect blue light. If you have yellow light on a blue material you'd expect to get black because blue materials won't relect yellow light. (In real life you never have materials that are this perfect, they might be (0.5 0.5, 0.75) ...

If you have two light sources for example then you'll probably add them as you want to total the contribution from each. The light you see is simply the total of both lights, so add them.

OTHER TIPS

jcoder's answer is correct.

However, I think you could put much more simply.

Multiplies happen when light hits objects. Additions happen when there is light from multiple sources.

The reason why we multiply to work out the object-light interactions because as jcoder says, in this model of lighting 1) Each light colour is independent 2) Objects absorb a fixed-per-colour percentage of the light that hits them.

Tip for the curious: You can try replacing this model with one where objects absorb a fixed amount of light (subtract, not multiply - obviously you need to clip to zero, so you don't get -ve light) The result is when it gets dark, you get a lot more contrast between colours. Not realistic, but a kind of "more real-than-real" effect. A little like a "drugged" effect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top