Chapter 8. Lighting and Fog

This chapter discusses two features implemented by subclasses of csEnvironment, lighting and fog.

This chapter describes first how to use lights, change the shadow modeling, and change the screen to one color. It then discusses how you can use fog for atmospheric effects such as smoke, haze, or mist.

This chapter contains the following sections:

Using Lights in Scenes

Cosmo 3D provides a variety of light types. This chapter describes the light types presented in Cosmo 3D in addition to the virtual light class, csLight, from which you can create your own light objects.

csLight

csLight is an abstract base class for light sources. It provides the following methods for setting light values:

void setOn(csBool on);
void setIntensity(csFloat intensity);
void setAmbientIntensity(csFloat ambientIntensity);
void setColor(const csVec3f& color);
void setColor(csFloat v0, csFloat v1, csFloat v2);

There is a corresponding set of get...() methods that return each of the light settings.

setOn() turns on the csLight object.

setIntensity() sets the brightness of the csLight object.

setAmbientIntensity() sets the brightness of the ambient color. The ambient intensity is how bright the light makes all objects appear.

setColor() sets the color of the csLight object.

csDirectionalLight

csDirectionalLight is a directional light source that approximates distant light sources, such as the sun, and can improve rendering performance over local light sources, such as csPointLight and csSpotLight. Use csDirectionalLight to set the direction of general lighting for a scene using one of the following methods:

void setDirection(const csVec3f& direction);
void setDirection(csFloat v0, csFloat v1, csFloat v2);

There is a corresponding set of get...() methods that return the lighting direction.

A csDirectionalLight has no range limitations so it affects all children of a csEnvironment object when included in a light array.


Note: A csDirectionalLight object's direction is affected by all csTransform nodes above it in the scene hierarchy.


csSpotLight

csSpotLight is a directional light source. Because csSpotLight is subclassed from csPointLight, csSpotLight can be positioned.

The light emanates as a cone; the axis of the cone specifies the direction of the spot light and is defined in the following methods:

void setDirection (const csVec3f& direction)
void setDirection (csFloat v0, csFloat v1, csFloat v2)

The intensity distribution and the cut off angle of the light are set with the following methods:

void setExponent(csFloat component);
void setCutOffAngle(csFloat cutOffAngle);

csPointLight

csPointLight is a point light source that radiates equally in all directions. The range of a csPointLight's effect is localized to a csEnvironment object when the csPointLight is included in its light array.

All descendants of a csEnvironment object that lie within the csPointLight's shining radius are affected by the csPointLight. csTransform objects affect the location and shining radius of each csPointLight.

Use the following methods to define a csPointLight.

void        setLocation(const csVec3f& location);
void        setLocation(csFloat v0, csFloat v1, csFloat v2);

void        setRadius(csFloat radius);

void        setAttenuation(const csVec3f& attenuation);
void        setAttenuation(csFloat v0, csFloat v1, csFloat v2);

There is a corresponding set of get...() methods that return the current point light settings.

setLocation() defines the location of the csPointLight.

setRadius() defines the maximum range of the light.

setAttenuation() defines how quickly the intensity of the light declines over distance.

Limiting the Scope of Lights

csEnvironment defines the scope of environmental effects, such as how far light from a csLight object can travel. When you create a virtual room, the goal is to make a lamp in the room shine in the room only—not leak through walls into the hallway. When you make a csLight part of the light array in csEnvironment, the lamp light stops at the walls of the room.

Another application of csEnvironment is rendering headlights on a car. The goal is to have the lights move with the car and extend only a couple of hundred feet in front of the car. To do that, you add a csPointLight to the csEnvironment light array and limit the csPointLight to several hundred feet.

The Scope of the Light Array

The csEnvironment node serves as the root node for the effects of all lights in its array. csEnvironment uses an array of lights because you might have more than one csLight in a room, but the light from all of the lamps should end at the walls of the room. All csLights in the light array have the same range limitations.

csEnvironment Methods

csEnvironment contains the following method that specifies an array of lights:

csMFRef* light() const;

For example, if you wanted to add two lights but remove a third, you would use code similar to the following:

// create an Environment
csEnvironment* park = new csEnvironment;
...

// find and remove light #3
csLight* badLight = park->getLight(3);
park->light()->remove(badLight);

//create two lights
csSpotLight* spot = new csSpotLight;
csPointLight* flood = new csPointLight;

// add the lights to the environment light array
park->light()->append(3, spot);
park->light()->append(4, flood);

Using Fog in Scenes

Fog is generated by setting up a csFog node and adding it to the csEnvironment. This fog description will affect all children of the csEnvironment. Subsequent csFog nodes will override the current fog description. Fog should also be globally enabled via csContext::setFogEnable() and can be overridden with csAppearance::setFogEnable(). If csContext::FogEnable is FALSE, it is disabled for the entire scene graph (unless overridden by csAppearance::fogEnable regardless of the value of csFog::on.

This section discusses the following fog-related topics:

Uses of Fog in Cosmo 3D Applications

Computer images sometimes seem unrealistically sharp and well defined. You can make an entire image appear more natural by adding fog, which makes objects fade into the distance. Fog is a general term that describes similar forms of atmospheric effects; it can be used to simulate haze, mist, smoke, or pollution. Fog is essential in visual-simulation applications, where limited visibility needs to be approximated. It is often incorporated into flight-simulator displays.

When fog is enabled, objects that are farther from the viewpoint begin to fade into the fog color. You can control the density of the fog, which determines the rate at which objects fade as the distance increases, as well as the fog's color. Since fog is applied after matrix transformations, lighting, and texturing are performed, it affects transformed, lit, and textured objects. Note that with large simulation programs, fog can improve performance because you can choose not to draw objects that would be too fogged to be visible.

All types of geometric primitives can be fogged, including points and lines. Using the fog effect on points and lines is also called depth-cuing and is popular in molecular modeling and other applications.

How to Use Fog in Cosmo 3D Applications

Fog is generated by setting up a csFog node and adding it to the csEnvironment. The csFog class has the following fields, which determine its effects:

Table 8-1. Fields in csFog

Type

Name

Enumerant

Default

csSFBool

on

ON

false

csSFEnum

mode

MODE

FOG_EXP

csSFFloat

density

FOG_DENSITY

1.0

csSFFloat

start

FOG_START

0.0

csSFFloat

end

FOG_END

1.0

csSFFloat

index

FOG_INDEX

0.0

csSFVec4f

color

FOG_COLOR

{0.0, 0.0, 0.0, 0.0}

The effects of the different fields are parallel to those of OpenGL glFog(), and can be examined in the OpenGL Reference Manual or the glFog manpage.

Enabling Fog

There are three different fields that determine whether fog is enabled or not:

  • csContext::fogEnable

  • csAppearance::fogEnable

  • csFog::on

In general whoever is OFF has precedence.

  • If csContext::fogEnable is OFF, no fog is drawn unless there is a csAppearance that has fogEnable ON. In this case, fog is enabled for that shape only if it is within the scope of a fog node that is turned on (that is, under a csEnvironment that has fog enabled).

  • If the csFog node is OFF, there will be no fog drawn in any circumstances, even if the fogEnable in the csAppearance or csContext is TRUE.

The fog description will affect all children of the csEnvironment. Subsequent csFog nodes override the current fog description.

How to Use Fog

The following code fragments from the csFog manpage illustrates how to use of fog:

static csVec4f fogClr(0.2f, 0.2f, 0.2f, 1.0f);

     <...>

     // Create environment node for scene
     csEnvironment *env = new csEnvironment;

     // Add enabled fog node to environment
     csFog* fog = new csFog;
     fog->setOn(TRUE);
     fog->setColor(fogClr);
     fog->setEnd(400.0f);
     fog->setMode(csFog::LINEAR_FOG);
     env->setFog(fog);

     // Enable fog for default state
     ctx->setFogEnable(TRUE);

     <...>

     // In frame function
     ctx->clear(csContext::COLOR_CLEAR | csContext::DEPTH_CLEAR,
                fogClr[0], fogClr[1], fogClr[2], fogClr[3]);