Understanding ofLight

Hi, I’m trying to understand how ofLight works.

Based on the documentation, it says there are 4 main lighting types that are

  • Spot light
  • Point light
  • Directional light
  • Ambient light.

So there are corresponding setter methods that are

  • setSpotlight();
  • setPointLight();
  • setDirectional();
  • ?

But I couldn’t find any method called “setAmbientLight()”.
I could find there is “setAreaLight()” instead. Is this the right one for setting the ambient light?

Also, what does it mean by “only programmable renderer” in ofLight.h

enum ofLightType {
	OF_LIGHT_POINT=0,
	OF_LIGHT_DIRECTIONAL=1,
	OF_LIGHT_SPOT=2,
	OF_LIGHT_AREA=3 // Only programmable renderer
};

And there are methods such as “setAmbientColor()”, “setDifuseColor()” and “setSpecularColor()” which I can find these in ofMaterial class as well.
I would like to know how they are different from ofMaterial’s methods when applied to ofLight;

And lastly, I wonder what “setSpotlightCutOff()” and “setAttenuation()” do in ofLight.
I tried to find the detailed information about ofLight but this documentation was all I could find.
http://openframeworks.cc/documentation/gl/ofLight/

I tried adding this code below to find out how they work in “OF/examples/gl/singleLightExample”

void ofApp::keyPressed(int key){
    switch (key) {
        case 'w':
            bDrawWireframe = !bDrawWireframe;
            break;
        
        //added below codes
        case 's':
            pointLight.setSpotlight();
            break;
            
        case 'p':
            pointLight.setPointLight();
            break;
            
        case 'd':
            pointLight.setDirectional();
            break;
            
        case 'a':
            pointLight.setAreaLight(100, 100);
            break;
            
        default:
            break;
    }
}

But if I press ‘s’, the lighting becomes weird and dirty looking like the screenshot below.

And once I set it to spotlight mode, it can never return to pointLight setting even if I press ‘p’.
I think this could be a bug. I would appreciate if someone can clarify this issue.
I’m using of_v0.9.8 in Mac OSX 10.11.6.

ambient light is just a small value that is added everywhere to compensate for the fact that you can’t calculate all the light reflections in real time. lighting in OF (and in most real time systems) only calculates the direct reflection from a light bouncing off an object and ending up in the camera which would make anything that is not directly hit by a light source completely dark.

you can 't setup a light as ambient light then, every material can specify how it reacts to ambient light, which color it reflects when hit by ambient light, you usually want to set this, using ofMaterial::setAmbientColor to the same value as the diffuse. and every light adds a bit of ambient light which lights up the whole scene uniformly, again you can set the color of this ambient value per light using ofLight::setAmbientColor and usually it should be the same color as the diffuse but at a much lower intensity. By default the ambient per light is disabled (set to black)

that way if a light emits red light and a material has white reflection it’ll look red when lighten up by such a light. the diffuse of the light is “mixed” with the diffuse of the material, the ambient with the ambient and the specular with the specular.

the specular is the color a material will show in the specular reflections, most of the times you want to set this the same color as the diffuse in the light and white in the material for non metallic objects and the same as the diffuse for metallic objects

and finally the diffuse is the areas where the light hits the object directly from the light source but at an angle where it no longer creates specular reflections

a spot light is a cone of light, the cutoff set through setSpotlightCutOff allows to define the radius of that cone, and setAttenuation the way the light fades out with distance

area lights allow to define a light that has some area as opposed to a point light which has infinitesimal size. it allows to for example create a fluorescent panel or something similar to a diffuse light if there where shadows such a light would create softer shadows than a point light. and as the comments say it can only be used with the programmable renderer, if you setup opengl version 3 or more when creating the opengl context in main.cpp

there are some parameters that are set when a light changes type that are probably not well reset when going from one type to another we should probably have ofPointLight, ofSpotLight… instead of a generic ofLight and so it’s advisable to not change the type of a light once it’s set but instead create several lights and enable / disable them

3 Likes

Hey @arturo Thank you very much for such an amazing explanation :slight_smile:

I played around with ofLight for a while based on your explanation and now I think I understand how things work more or less. And as you said, it wasn’t a bug. it was just wrong parameter settings causing the weird result.