Lesson 16 - Fog



This final lesson in the first 16 NeHe lessons is very simple. This is because the support for fog in three.js is very simple. There are two types of fog support:

  • Linear Fog - where the density of the fog increases linearly with distance
  • Exponential Fog - where the density of the fog increases exponentially with distance

In both cases, the fog acts on all objects in the scene and obscures only those objects, i.e. it is not like a particle-system fog or clouds that drift across the landscape on their own.

Linear fog seems less useful in general since the only real parameter one can set is the color of the fog. It is not very dense, either, so you need to create a large scene or the effects will be hard to discern. Exponential fog, on the other hand, has a density parameter so the density can be varied independent of the scale and position of objects.

Both can be optimized slightly be setting the near and far parameters, which lowers the computing needs.

Finally, fog must be set when the scene is created. the only way to change it would be to re-create the whole scene. And you cannot change the type of fog after it is created. However, if you use exponential fog, you can set the density to zero which effectively eliminates it.


In this demo, we set exponential fog in the constructor of the scene. You can vary the density and color of the fog with the keyboard. So the call to create the scene in this demo is

var gfxScene = new GFX.Scene( {
    canvasWidth : 768,
    canvasHeight : 1024,
    fogType : fogType,
    fogDensity : fogDensity,
    fogColor: 0xffffff });

In order to demonstrate the effects of fog we use another feature available in the scene: checkerboard floor. The checkerboard is a simple 256x256 pixel image:

The code that renders this is in gfx-scene.js:

var image = this.floorImage == null ?
                    '../images/checkerboard.jpg' : this.floorImage;
var texture = new THREE.ImageUtils.loadTexture( image );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( this.floorRepeat, this.floorRepeat );
var floorMaterial = new THREE.MeshBasicMaterial( { map: texture, side: THREE.DoubleSide } );
var width = this.floorX == 0 ? 10 : this.floorX;
var height = this.floorZ == 0 ? 10 : this.floorZ;

var floorGeometry = new THREE.PlaneGeometry(width, height, 1, 1);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = 0.0;
floor.rotation.x = Math.PI / 2;

As you can see, the checkerboard is the default, but the user can supply their own image if they wish. floorRepeat is the number of times the texture is repeated (in both X and Y). width and height are the width (in X) and the height (in Z) of the "floor" that is created, in the current coordinate system.

The mesh is created by creating a PlaneGeometry, which is a flat, planar surface. It is oriented parallel to the X-Z plane at Y=0.

In order to provide something to demonstrate the fogginess, the demo creates a set of 21 cubes (1x1x1) oriented along the X and Z axes. The cubes use the crate texture.

You can increase and decrease the density of the (exponential) fog with the '+' and '-' keys and change the color of the fog. The default is white, but you can set red, green, blue or black.

And that's it! Click on this link to see the actual rendered demo in all its foggy glory!

As always, the original sources are on github here.

About Us | Contact Us | ©2017 Geo-F/X