The purpose of this project was to provide extensions to Data Explorer for creating realistic landscapes and natural features. The extensions it provides deal mainly with generating and modifying terrain models by different methods. It also provides simple cloud and ocean modeling. Although the title has "fractal" in it, not all the algorithms here use fractal methods, a few algorithms use particle systems while others use mathematical models. There wasn't time to implement other natural features such as trees, grass, etc. But there are some other projects, "Voxel Space Automata" and "L-System Plant Geometry Generator" that can create these features.
All the new modules provided here work on the "positions" component of DX fields. Although most just adjust the heights of each position (i.e. a height-map), some actually modify the x and y positions too. Most of the modules can also be applied additively (i.e. you can run TwoDfbm on the output of Raise (or any other module for that matter). The only exception to this is the SpectralSynthesis module.
This project was written under the instruction of professor
Bruce Land.
The Planet module generates a fractal planet by simulating tectonic evolution.
It works by randomly picking "faults" on the surface of a sphere and raising
or lowering land on either side of the fault. Each fault is defined by a plane
that passes through the origin of the sphere. After a few hundred iterations
the field begins to evolve into continents and oceans. The Planet module also
allows creation of simple polar ice caps which are generated by a 1-d spectral
synthesis procedure (see SpectralSynthesis module for more
info on this process).
This module takes six inputs: a field to store the "planet" in, the radius
of the planet, the number of iterations (or faults), the amount to raise or
lower land at fault lines (as a percentage of the radius), a "seed" number
which randomly seeds the planet's surface with some dummy land masses and a
polar cap size which is given as a percentage of the planet's diameter.
The output is a field containing the new/modified planet. Even though the
output field is flat, it can be warped around a sphere using the Spherify
macro supplied with the example nets. See [2] for more
info.
The Ocean module is used to simulate ocean waves for a particular landscape.
There are four different models used for this simulation. The first is just
a quick and simple flat ocean surface, the second is a simple combination of
sin and cos waves to cheaply simulate a wavy ocean. The third uses a 1/f^3
noise function to simulate the ocean surface (similar to the SpectralSynthesis
module). The last method uses a mathematical model to simulate waves based on
wind speed and underwater terrain features. The inputs are different for each
model but there are three that are common to all: the kind input controls the
type of ocean modeling to be done (either "flat", "simple", "noise" or
"realistic"), the sea level as a percentage of the height of the shore field,
and the shore field.
The "simple" and "noise" models take an additional parameter which is the
wave shape. This value controls the "choppiness" of the waves. For the
"simple" model the wave shape is roughly a percentage of the maximum height
of the shore. This controls the minimum and maximum heights for "simple"
waves. For the "noise" model, the wave shape is related to the frequency
of the noise used to generate the waves. Values for the "noise" model
should probably lie in between 0.0 and 0.6 with 0.3 being the average.
The "realistic" model takes many more parameters which are as follows: the
time factor for the evolution of the ocean waves, the wind speed in m/s,
the wave shape which determines the shape of the waves (a number in [0, 1/pi], usually 0.1, higher values make higher wave peaks), K0 which controls the
effect of the slope of the bottom, Kx which controls the effect of depth on
the horizontal displacement of the waves (e.g. the effects of breakers),
Kz which controls the effect of depth on wave height, and finally the
gravitational constant in m/s^2 (usually 9.8 m/s^2).
The scaling constants (K0, Kx and Kz) should be positive and relatively small.
Values > 10.0 will completely damp out their effects on the shape of the waves.
Also the ratio between Kx and Kz is significant because the effects of Kz on
the wave shape also include Kx indirectly. Note: good values for these values
(K0, Kx and Kz) are hard to determine easily and the paper [4] did not provide
any sensible defaults.
The output of this module is a colored wave field which can be overlayed
with the original shore to form a complete picture. The wave field also has
its opacities set according to the depth of the water at each point. See
[4] for more info.
The Cloud module is used to generate simulations of clouds using functional
textures and a modified lighting model. This module generates two types of
clouds "planar" and "ellipsoid". Planar clouds are used mainly as a backdrop
for a sky scene and ellipsoidal clouds are used for more realistic 3d clouds.
The cloud module takes twenty parameters! This is alot of parameters
and makes it difficult to use but the paper [6] offered no
sensible defaults for any of these parameters. Through trial and error a set
of reasonable defaults was derived for planar and ellipsoidal clouds. The
defaults of the module are only for planar clouds, however. (See the
cloud3d.net for some defaults for ellipsoidal clouds).
The parameters for the cloud module are: the field to store the cloud in,
optional control points P, Q, R, T for definition of 3d cloud, the camera,
the light, the shininess of the clouds (for specular reflection), Ka the
ambient light factor, Kd the diffuse light factor, Ks the specular light
factor, Kt the texture factor (controls how much the texture affects the
image intensity), D, T1 and T2 factors controlling the translucence threshold
for the lighting model and n, C0, Fx0, Fy0 and T0 which control the function
that generates the basic textures.
The control points (for 3d clouds) control a bounding volume that defines the
shape, orientation and position of the cloud. P controls the x-axis,
Q controls the y-axis, R controls the z-axis and T controls the origin
of the ellipsoid. Effects of rotation in terms of angles can be applied by
rotating the basic control points (P, Q, R) before applying them to the module.
I wanted to be able to compute these values from an ellipsoid automatically,
but I didn't have the time to do this.
The translucence constants should all be in the range of [0, 1] with the
exception of D which should be strictly > 0. The relationship between
these values and the translucence (or 1 - opacity) are as follows: for
planar clouds TR = 1 - (It - T1) / D (where It is the
texture value) and TR = 1 - (It - T1 - (T2 - T1) * (1 - g) / D for
ellipsoidal clouds (where g is the proximity to the limb of the the
cloud).
Note: cloud textures can be used for other natural textures as well
(e.g. tree tops, grass, etc.)
The output of this module is a rendered cloud field with an opaciticies
component. See [6] for more info.
The TwoDfbm module generates landscapes using two dimensional fractal Brownian
motion. The method consists of dividing the input field into smaller and
smaller sections and perturbing the corners of these sections by a random
amount. This module uses the diamond-square subdivision model which alternates
between square and diamond shaped sections.
The inputs to this module are: the field to store the landscape in (which
must have sides of equal length that are powers of 2), the level which
controls the number of iterations to perform (usually this is log2(length of
side) but can be less), sigma which controls the size of the perturbations,
H which is a factor related to the fractal dimension which controls the rate
at which sigma decreases/increases at each iteration, and a flag which
controls additional random perturbations to the landscape at each iteration to
prevent possible artifacts in the landscape. The output is a field that
contains the new/modified landscape. See [2] and
[3] for more info.
The SpectralSynthesis module uses a different method to generate a fractal landscape.
It works by generating a field of 1/f^B (where f is frequency
and B is related to the fractal dimension) noise which then goes
through an inverse 2d FFT. After this magical process a realistic looking
landscape appears.
This module takes two parameters: a field to store the landscape in and H
which controls the generation of the noise (the lower H is the more "spiky"
the resulting landscape is). The relationship between H, D (fractal dimension)
and B is: B = 1 + 2H and D = 3 - H. Note: the heights in the input
field to this module are ignored and replaced with new heights, this is
different than most modules which will modify the input field instead of
overwriting it. The output is the new landscape. See [2]
for more info.
The Crater module simulates the impact of craters on a landscape. It works
by randomly picking locations on the input landscape and "punching" crater
shaped holes into it. The crater shape is controlled by a simple function
which relates the slope to the depth and radius of a crater.
This module takes five parameters: the landscape to "craterize", the number
of craters to drop on the landscape, dp which controls the relationship between
crater radius and crater depth (depth ~= rad^dp). db which affects the decay
of depth as a function of the distance from the center, and the slope which
controls the shape of the slope around the crater's edges. The output is a
"craterized" field. See [2] for more info.
The Raise module provides three more methods for landscape generation. These
involve "pushing" differently shaped and sized objects into a field to produce
and terrain-like effect. There are three different basic shapes which can be
used: the cone, hemisphere and pyramid. At each iteration a randomly scaled
permutation of one of these shapes is "pushed" through the field (as if it
were a rubber sheet that retains it's shape). It is similar to the Crater
module but produces much different results. There are three parameters: the
field to store the landscape in, the kind of shape to use "sphere", "cone" or
"pyramid" and the number of iterations to perform. The output is the modified
field.
The ThermalErode module simulates thermal erosion (basically the weakening and
"slumping" of the soil). It works by passing a percentage of the altitude of
each vertex to lower neighboring vertices which differ in heights by a certain
angle (the talus angle).
This module takes four parameters: the landscape to erode, the talus angle
which controls the critical angle for determining which vertices get falling
rubble, the percent of soil that can fall off a vertex during each iteration
and the number of iterations to perform. The output is the eroded landscape.
The HydraulicErode module simulates hydraulic erosion (i.e. erosion by rain).
It works in the same basic way as the ThermalErode module. For each vertex
it passes a certain amount of "sediment" to each lower vertex. The process
works by "raining" an amount of water onto each vertex every so often. Each
unit of water can carry a certain amount of sediment from on vertex to the
next. Also, water can "erode" sediment from the current vertex before passing
to an adjacent vertex. The process iterates over every vertex passing water
and sediment to lower verticies.
The HydraulicErode module takes seven parameters: the landscape to erode,
kc (sediment capacity) which is the amount of sediment a drop of water can
tranfer from vertex to vertex, kd (soil deposition constant) which is the amount
of soil that is deposited by a traveling droplet of water at each iteration,
ks (soil softness) which controls the amount of soil an drop of water can
"pick up" at each iteration, the amount of rain that falls during each rainfall,
the frequency of rainfalls, and the total number of iterations to perform.
The output is the eroded landscape. Note that kc, kd should be proportional to
the range of heights of the input field. If they are too large than very strange
results will occur. See [5] for more info.
The TerrainColormap module generates a colormap suitable for coloring a
landscape with. It takes nine parameters which control the distrubution of
colors: the colormap to store the colors in, the minimum and maximum ranges
for the color indicies, the percentages of sea level, beach, plains, mountain
and snow cap colors contained in the color map, and a darkening factor to
automatically darken the palette. The output is an appropriately initialized
color map.
The TerrainColorize is basically the same except it colors the landscape itself
and outputs the new landscape.
PNM's (or Portable Any Maps) are a type of image file (like .gif, .jpeg, etc.).
They come in three basic flavors: pbm (binary image), pgm (gray scale image) and
ppm (color image). They are provided here since I was saving my generated
landscapes to pnm files before I hooked things up to DX.
The LoadPNM module loads a pnm file into a field. It takes a filename and
outputs the loaded field. The heights of the field are determined by the
intensity of the color of each pixel of the pnm.
The SavePNM module saves a field as a pnm file. If the field hasn't been
colored yet it is gray-scaled and saved as a pgm otherwise it is saved as
a ppm. This module takes a filename as input and has no outputs.
The modules implemented here can produce pretty convincing looking landscapes
but there are still a few things left to be desired (of course). The most
annoying thing about most of the modules is the proliferation of non-intuitive
parameters. This is a serious problem because it is difficult to characterize
these parameters in terms of the output (i.e. how do I get a very "mountainous"
landscape or how do I get cumulous clouds, etc.). Another difficulty is the
fact that many of the methods use random numbers which makes the output
inconsistent from run to run. Here are a few ideas for future improvements
for some of the modules:
Planet: make more convincing polar caps.
Cloud: automatic creation of 2d and 3d cloud clusters, characterize
parameters in terms of things like altitude and wind speed, etc.
Ocean: multiple wave trains, allow rotation of the wave fronts, spray
and foam.
SpectralSynthesis: adding lacunarity to the noise function
(see [5]).
ThermalErode and HydraulicErode: allow variation of parameters according to
altitude as well as rock type (e.g. soft soil and hard rock can appear in the
same landscape). Should also probably allow interleaving of thermal and
hydraulic erosion.
TerrainColorize - more realistic color map + textures for mountains, etc.
more natural features: rainbows, fire, lightning, storms, snow, etc.
error checking and recovery could be made nicer
and last but not least: make it faster!
[6] Gardner, G., Visual Simulation of Clouds, Sigraph, Vol. 19,
No. 3, pp 297-303, 1985.
[8]
Fractal Landscapes by John Alferness
The Planet module
Fig. 1 - fractal planet
The Ocean module
Fig. 2 - simulated oceans. clockwise from right: original landscape,
landscape + simple ocean, landscape + 1/f^3 noise ocean, and landscape +
realistic ocean
The Cloud module
Fig. 3, 3a - planar cloud field over landscape, 3d cloud
The TwoDfbm module
Fig. 4 - landscape generated by fractal brownian motion.
The SpectralSynthesis module
Fig. 5 - landscape generated by spectral synthesis.
The Crater module
Fig. 6 - craterized landscape.
The Raise module
Fig. 7 - landscapes generated with various shapes, clockwise from top:
cones, pyramids and hemispheres.
The ThermalErode and HydraulicErode modules
Fig. 8 - eroded landscapes, clockwise from top: original landscape,
thermal erosion, hydraulic erosion, thermal and hydraulic erosion combined.
The TerrainColormap and TerrainColorize modules
The LoadPNM and SavePNM modules
Getting the code
To get the code to make the new modules you must get:
First uncompress the file using gzip and extract the components using tar.
It will create a directory called "fractal" which has all the code and
documentation needed to build the system. Check out the README file in the
main directory for more instructions. See the examples subdirectory for sample
net files demonstrating the use of the new modules.
Example nets
Macros
Example script
Conclusions and Future improvements
References
Cornell Theory Center