libnoise logo

A portable, open-source, coherent noise-generating library for C++


Example: Perlin worms

Screenshot

Normally, libnoise is used to generate procedural textures and terrain. This page demonstrates an unusual application of libnoise to render and animate worm-like creatures in real time.

To see this program in action, download the example sources (43 KB) and compile worms.cpp.

To run this program, you'll also need OpenGL 1.1 (or better), and GLUT, a windowing toolkit for OpenGL.

The worms source code is released under the terms of the GNU General Public License.

Keyboard Controls

Esc Exits the program.
Q Increase the number of worms by one (maximum 1024)
A Decrease the number of worms by one
W Increase the number of worm segments by one (maximum 256)
S Decrease the number of worm segments by one
E Increase the worms' speed
D Decrease the worms' speed
R Increase the lateral (thrashing) speed of the worms
F Decrease the lateral (thrashing) speed of the worms
T Increase the worms' thickness
G Decrease the worms' thickness
Y Increase the worms' "twistiness"
H Decrease the worms' "twistiness"

How this program works

Rendering the worms

This program creates a worm object for each worm to render. Each object is instantiated from a Worm class with the following properties:

  • It has a three-octave Perlin-noise module. It uses the coherent-noise values from this module to shape the worm's body.
  • It stores the position of a lookup line segment that it uses to retrieve the coherent-noise values from its Perlin-noise module.
  • It has a unique seed value for its Perlin-noise module so that each worm's shape differs from the others.
  • It can render itself to the program window by calling the appropriate OpenGL functions.

A worm is divided into several worm segments of constant length. A worm object generates coherent-noise values from its Perlin-noise module to determine the angles of each segment. It generates these values along its lookup line segment. Refer to the following diagram:

Lookup line segment within a Perlin-noise module

Note that this line segment is parallel to the x axis.

Referring to the above diagram, the coherent-noise values generated along this line segment look like this:

Coherent noise from the lookup line segment

A worm object divides this line segment into n discrete values, where n is the number of worm segments. It sets the angle of its head segment using the coherent-noise value from the leftmost position of the line segment. It sets the angle of the next worm segment using the value from the next position, and so on.

Lookup line segment divided into discrete values

A worm object draws each worm segment off of the previous worm segment, forming a chain of worm segments. Refer to the following diagram.

Rendered worm

In the above diagram, the segment with the block is the head segment.

Animating the Worms

After a worm object renders itself, it moves its lookup line segment by a small constant amount in the x, y, and z directions. Because these coherent-noise values are very similar to the previous values, the worm will slightly change its position on the next frame.

The following list of images show three frames of the worm. After each frame, the lookup line segment moves in the positive y direction:

  • Frame 1
    Frame 1 of worm
  • Frame 2
    Frame 2 of worm
  • Frame 3
    Frame 3 of worm

Once again, the segment with the block is the head segment.

Moving the Worms

After each frame, the worm object moves its head segment by a short distance along a vector with an angle opposite the angle of the head segment. Also, it shifts its lookup line segment a short distance in the negative x direction, which propagates the previous coherent-noise values over to subsequent worm segments. This causes the worms to exhibit a "slithering" effect.