Entropy Fog Tutorial

From LagoonWiki

Jump to: navigation, search

Fog is useful in 3D games for its artistic effect, its role in gameplay, or simply as a means of hiding distant objects that you do not want to render. This tutorial tells how to put fog into a scene for Galaga/Entropy/Ogre3D.

Contents

Creating Fog

This is actually very easy, requiring only a single line of code in the program:

sceneManager->setFog(FOG_LINEAR, ColourValue(0.9,0.9,0.9), 0.0, 1, 500);

For our engine there are certain circumstances that requre this line to appear before the call to -

sceneManager->setWorldGeometry("terrain.cfg");

so put it near the start of your createScene code in ogreApplication.cc. Do that now, and observe its effect on your scene.

Linear Fog

Putting fog into the scene is easy, but there are so many interacting parameters that getting just the right effect can be tedious. The parameters are as follows:

  1. FOG_LINEAR is a symbolic constant that tells the engine how you want the density of the fog to increase with distance. In this example the density is directly proportional to the distance; other options are described below.
  2. The color (notice the British spelling used by the engine's code) is defined by the usual RGB values in the range 0.0 to 1.0. Experiment with this to see the effects you can get.
  3. The third parameter is not used for linear fog.
  4. The fourth parameter is how far from the camera you want the fog to start.
  5. The fifth parameter is how far from the camera you want the fog to reach full saturation. At full saturation everything looks the color of the fog, no matter what is behind it.

Play with these parameters to ensure that you understand how they work, and to see what kind of effects you can get with the scene you are building.

Exponential Fog

You can also make the fog's density increase exponentially with distance, e.g. with this call:

sceneManager->setFog(FOG_EXP, ColourValue(0.9,0.9,0.9), 0.0005);

The parameters are as follows:

  1. FOG_EXP tells the engine to use exponential fog. (There is also a FOG_EXP2 that works the same way, except that the density increases even faster.)
  2. The color definition is as before.
  3. The third parameter controls how quickly the density increases.

The fourth and fifth parameters are not used for exponential fog, and can be omitted from the call as in the example above.

Switch your code to use exponential fog, and play with the parameters to learn their effects.

Fog vs. Skyboxes

In many circumstances fog does not play well with skyboxes. If the fog reaches saturation density before the distance to the skybox (which is a constant distance from the camera, no matter where you move it), then you will not see the skybox at all. However, if the fog is thin enough to see the skybox you will probably see an undesirable artifact. Since the skybox is square, the distances to the corners is farther than the distances to the middles of the sides, so the fog looks denser in the directions toward the corners than it does in the other directions, which spoils the illusion.

Thus fog is not normally used with skyboxes. It can be used to hide the edges of the world completely (i.e., by not allowing the camera to move closer to an edge than the fog's saturation distance), or thinner fog can be used, and the edge of the world can be hidden by terrain such as mountain ranges, forests, buildings, or other game assets.

Temporarily comment out the line of code that loads your skybox, recompile, and observe the effect.

Fog vs. Empty Space

The above probably did not give the result you wanted. To understand the effect you must know how the engine renders fog. It is not some "stuff" that fills the space of the environment you created. Instead, it is a filter applied on top of each polygon that the engine renders.

When rendering a scene the engine does a vast number of geometric calculations in order to determine how each polygon in your scene is displayed. This includes a distance calculation. To apply fog, the engine calculates the density of the fog at that distance from the camera, and paints over the polygon (and its native texture) with the fog color, diluted by an alpha value determined by the fog's density at that distance. This is a mathematically simple trick, and gives exactly the desired effect in front of polygons. However, in the absence of any polygon to block your line of sight, no fog is rendered. Fog obscures your skybox because it is just a big cube rendered with polygons bearing your textures. But when you removed the skybox, nothing above your terrain is blocked by any polygon, so it appears as some predefined background color.

The fix is to set the background color to be the same as your fog at full density. Then any direction you look that is not blocked by a polygon will look like fully saturated fog. The environment we are using already has that color set to black, but you can change it with this call:

this->renderWindow->getViewport(0)->setBackgroundColour(ColourValue(0.9,0.9,0.9));

To make sure your background color and fog always match, it is useful to define the color in a variable, thus:

ColourValue fogColour(0.2, 0.4, 0.2);
this->renderWindow->getViewport(0)->setBackgroundColour(fogColour);
sceneManager->setFog(FOG_LINEAR, fogColour, 0.0, 100, 5000);

Now whenever you want to change the color you only need to change it in one place.

With your skybox still commented out, implement this and observe the effect on your scene.

The effect should now look natural. However, sometimes fog extends far in lateral directions, but is not very deep vertically. To obtain that effect you can use a skyplane.