Ray Casting Tutorial – Part 19
May 17, 1996



When an object is farther away from the viewer, the object should appear less/more bright. To accomplish this, a shading effect is needed. But first, we need to know about how colors are represented.

The standard 256 color VGA mode registers contains three numbers between 0 to 63 for every color in the palette which are called the RGB (RedGreenBlue) values. For example, full red color has RGB components of (63,0,0); full green has (0,63,0); and full blue has (0,0,63). Color such as full yellow, can be obtained by mixing full red and full green so that (63,63,0) is yellow.

To change the brightness of the red, green, or blue component of a color, the number representing the color component must be increased or decreased. For instance, to decrease the intensity of a color that have an RGB components (50,10,10) by one half, multiply each component by 0.5. The resulting color will be (25,5,5).

This is quite simple, but how do we know what intensity to use on what distance? The first option is to use an exact light intensity formula which goes something like this:

Intensity = (kI/(d+do))*(N*L)

From a game programmer perspective, this formula is too complicated and will be terribly slow, so we are not going to even bother with it. Our main goal will be to make a shading effect that looks-right (or at least reasonable). We do not particularly care whether the formula that we are using is the correct text-book formula or not.

(Side note.: For game programming, I tend to agree to this principle:
it’s better to have something that is fast and look-resonably-right; that to have something that is exactly-right, but slow.)

Hence, the following formula is used instead (Lampton 406).

Intensity = Object Intensity/Distance * Multiplier

Here, Object Intensityis the intensity that the programmer wish to use (it should be between 0 and 1). This is actually quite simple conceptually. It basically says that as objects gets farther, the intensity of the object gets smaller. Multiplier is a number to prevent Intensity from falling off to fast with distance. This calculation can still be expensive in real time, therefore a distance table such as the following table can be used:

Distance to object Intensity
0 to 500 1
501 to 1000 0.75
1001 to 1500 0.50

Ray-casting process lends itself nicely here because when we cast a ray, we also obtain the distance to the object to be rendered. In an actual implementation, we need to take into account also the number of available colors. Since most games can only use 256 colors, some acrobatics will be needed to make sure that the palette contains the correct color range. A possible solution for this is to use a color matching algorithm and map the result into an intensity table. When rendering, we simply fetch the correct color value from the appropriate table. (This is quite fast because a particular wall slice will have the same intensity for all of its pixels. So we only have to switch table between wall slices.)

Distance to object Intensity Palette Mapping Table Index
0 to 500 1 1
501 to 1000 0.75 2
1001 to 1500 0.50 3

Normally, as the intensity of an object approaches zero, the object will appear darker. However, this does not have to be always the case. We can create in interesting effect, such as fog or underwater effect by altering the “target color.” For instance, to create a fog effect, we can make the palette converges to white.




Demo with source code: