You're
standing on rolling hills beneath a brilliant blue sky. You look
up and see huge spherical white blobs suspended a few thousand feet
in the air. What's wrong with this picture? Perhaps you could use
a better cloud-rendering system.
In
videogames that simulate outdoor reality, realistic clouds can be
one of the most compelling aspects of the scene. Clouds can also
set the mood - dark thunderheads for an ominous scene, light puffy
clouds for a happy mood. Michelangelo spent years perfecting the
heavens on the ceiling of the Sistine Chapel, but we need to render
realistic clouds in milliseconds. Fortunately, we have more advanced
tools to work with. This article describes the cloud modeling and
rendering system that ships with Microsoft Flight Simulator 2004:
A Century of Flight.
Clouds
in the real world consist of many types, such as altocumulus, stratus,
and cumulonimbus, and cloud coverages ranging from a few sparse
clouds to a dense, overcast sky. Our cloud system models this range
of cloud types and coverages. Microsoft Flight Simulator
allows users to download real-world weather and see current weather
conditions reflected in the game graphics, which means we need to
generate compelling visuals to match any scenario that could occur
in the real world.
The
interactive nature of games necessitates that clouds must look realistic
whether the camera is far away, next to the cloud, or traveling
through the cloud. Another requirement is that we need to render
at high framerates. Microsoft Flight Simulator supports a
wide range of machines, from the latest PCs to those dating back
several years, and the performance must scale to this spectrum of
machines.
Clouds
need to be shaded appropriately to emulate both sunlight and light
reflected from the sky, especially for games such as Microsoft
Flight Simulator, which take place over the course of day, spanning
dawn, midday, dusk, and night. We model the dynamic aspect of clouds
by introducing a method to form and dissipate them over time.
Previous
Work
Over
the past 20 years, graphics researchers have modeled clouds in many
ways, including cellular automata, voxels, and metaballs. They also
modeled cloud animation via fluid dynamics. There are two reasons
that these research techniques have not been widely adopted by games.
The first is performance. Many of these systems produced screenshots
that were gorgeous but required multiple seconds to render. The
second is lack of artistic control. Imagine that you create a cloud
by running a set of fluid dynamics equations. You examine the results
and decide you would like a wispier top on the cloud. You must then
iterate through cycles of adjusting variables such as air humidity
and temperature, and recomputing the equations, which can require
hours and still may not produce the visual effect you had in mind.
Realistic
results in cloud shading have been achieved by simulating the scattering
of light by particles as it passes through the cloud, known as anisotropic
scattering. This produces accurate self-shadowing and interesting
effects such as the halo when the cloud lies between the camera
and the sun. We created a simple shading model for our system, forgoing
these effects in exchange for fewer computations and higher artistic
control.
Many
flight simulation games have featured clouds, recent examples being
Flight Simulator 2002, IL-2 Sturmovik, and Combat
Flight Simulator III. A common approach is to paint clouds onto
the skybox texture, which has minimal performance overhead, but
such clouds look two-dimensional and never get closer as the camera
moves toward them. A better solution is to draw each cloud as a
single facing sprite. This solution looks realistic from a stationary
camera but produces anomalies as the camera rotates around it. A
few recent games use clusters of textured particles, similar to
our system. Some use unique textures for every cloud, which has
a high video memory cost as the number of clouds in the scene increases.
Other systems use small blurry textures, which results in clouds
that look volumetric but lack definition. All of these systems also
lack the ability to form and dissipate clouds.
Our
system was inspired after hearing a GDC talk by Mark Harris, who
developed Skyworks, a real-time system that created volumetric clouds
from sprites. Harris dynamically generated an impostor for every
cloud and achieved speeds of 1 to 500 frames per second. He also
modeled the fluid motion behind cloud animation. The limitation
of his system is that it cannot render large clouds, such as cumulonimbus,
or dense scenes of overcast clouds, due to the prohibitively high
video memory cost of generating large impostors. Our system is able
to address this limitation. In addition, we tackle the problem of
scaling to multiple cloud types.
Cloud
Modeling
Given
that we want immediate visual feedback and full control over the
final result, how can we design the artistic pipeline for modeling
clouds? We model each cloud as five to 400 alpha-blended textured
sprites. The sprites face the camera during rendering and together
comprise a three-dimensional volume. We render them back-to-front
based on distance to the camera.
We
wrote a plug-in for 3DS Max that creates cloud sprites based on
a 3D model composed of boxes. The artist denotes a cloud shape by
creating and placing a series of boxes, using default 3DS Max functionality.
The artist can create any number of boxes of any size and can choose
to overlap the boxes.
The
plug-in UI contains an edit field to specify the number of sprites
to generate. To create denser clouds, the artist would set a number
which is proportionately higher than the size of boxes in the model.
Wispier clouds would be created by setting a lower number. There
are generally 20 to 200 boxes for each 16-square-kilometer section
of clouds, and the number of sprites per box can vary between 1
to 100, depending on the density. The UI also allows the artist
to specify a range for the width and height of each sprite, and
choose between categories (such as stratus and solid cumulus) that
determine the textures that will be automatically placed by the
tool onto the sprites. Figure 1 shows a screenshot of the tool UI.
The
artist presses a button in the plug-in UI to generate the cloud
sprites. The plug-in creates a list of randomly placed sprite centers,
then traverses the list and eliminates any sprite whose 3D distance
to another sprite is less than a threshold value (the "cull
distance"). This process reduces overdraw in the final rendering
and also eliminates redundant sprites created from overlapping boxes.
We have found that a cull radius of 1/3 of the sprite height works
well for typical clouds, and 1/5 to 1/6 of the sprite height yields
dense clouds. Figure 2 shows screenshots of a cloud model made of
boxes and its corresponding sprites.
The
plug-in creates an initial model of sprites, and the artist can
now edit them within 3DS Max. Having achieved the desired visual
look, the artist uses a custom-written exporter to create a binary
file containing the sprite center locations, rotations, width, and
height, along with texture and shading information. These files
are loaded during game execution and rendered.
Textures
To
create a dozen distinct cloud types, we mix and match 16 32-bit
textures for both color and alpha (see Figure 3). The flat-bottomed
texture in the upper right-hand corner is used to create flat bottoms
in cumulus clouds. The three foggy textures in the top row are used
heavily in stratus clouds and have a subtle bluish-gray tinge. The
six puffy textures in the bottom two rows give interesting nuances
to cumulus clouds, and the remaining six are wispy sprites that
are used across all cloud types.
By
creating interesting features inside the textures that resemble
eddies and wisps, we are able to create more realistic looking clouds
with fewer sprites. We place all 16 textures on a single 512x512
texture sheet, which spared the cost of switching textures between
drawing calls to the video card. We automatically generate mip-map
levels for this texture from 512x512 down to 32x32. To create more
variations from these 16 textures, the artist specifies a minimum
and maximum range of rotation for each sprite. When the binary file
is loaded into the game, the sprite is given a random rotation within
the range.
In-Cloud
Experience
We
would like a seamless in-cloud experience that looks consistent
with the cloud's appearance as viewed from the outside, which does
not often come with the commonly used technique of playing a canned
in-cloud animation. In our system, as the camera passes through
a sprite, it immediately disappears from view. We encountered a
problem because the sprites rotated to face the camera, and during
the in-cloud experience, the camera was so close to the sprite center
that small movements in the camera position caused large rotations
of the cloud sprite. This resulted in a "parting of the Red
Sea" effect as sprites moved out of the way of the oncoming
camera.
We
locked the facing angle of the sprite when the camera came within
half of the sprite radius. This removed the Red Sea effect but caused
sprites to be seen edge-on if they locked and the camera then pivoted
around them. Our solution was to detect the angle between the sprite's
locked orientation and the vector to the camera, and to adjust the
transparency of the sprite. The negative side effect is that the
section of the cloud near the camera appears less opaque.
______________________________________________________
Page 1 of 3