2
M
o
T
e
Fra
n
Sun
d
Pre
g
day,
real
shy
for
m
laye
r
Fi
gu
Lini
n
2
o
delin
g
e
chniqu
n
k Kane
d
og Software
,
g
enerated sk
y
or games w
h
3D objects,
a
away from,
b
m
ance. This
g
r
s,
t
he simul
a
u
re 2.1. Volu
m
n
g SDK, court
e
g
,Lighti
esfor
V
,
LL
C
y
box texture
s
h
ere the cam
e
a
s shown in
F
b
ut techniqu
e
g
em presents
a
tion of ligh
t
m
etric clouds a
t
e
sy of Sundog
S
ng,an
d
V
olum
e
s
aren’t suffi
c
e
ra may app
r
F
igure 2.1, is
e
s exist to p
r
an overview
t
transport
w
t
dusk rendere
S
oftware, LLC
.
d
Rend
e
e
tricCl
o
c
ient for ga
m
r
oach the clo
u
a challengi
n
r
oduce realis
t
of the proce
d
w
ithin a clou
d
e
d using splatt
i
C
.)
e
ring
o
uds
m
es with var
y
uds. Renderi
n
n
g task that
m
t
ic results wi
t
d
ural genera
t
d
, and sever
a
i
ng. (
I
mage fr
o
y
ing times of
n
g clouds as
m
any engines
t
h good per-
t
ion of cloud
a
l volumetric
o
m the Silver-
21
22 2.Modeling,Lighti ng,andRenderingTechniquesforVolumetricClouds
rendering techniques that may be used to produce realistically lit, volumetric
clouds that respond to changes in lighting conditions and grow over time.
2.1ModelingCloudFormation
Before we render a cloud, we need to know its size, shape, and position. A scene
may contain hundreds of clouds. While requiring a level designer to manually
place and shape each one maximizes artistic control, achieving realistic results in
this manner is time-consuming and challenging. Fortunately, procedural tech-
niques exist to model the size, shape, and position of clouds within a cloud layer.
A designer may simply define a bounding region for clouds of a specific type and
let the simulation handle the rest.
GrowingCloudswithCellularAutomata
While you could attempt to simulate the growth of clouds using fluid dynamics,
doing this at the scale of an entire cloud layer would be slow and overly complex
(although it has been done [Kajiya and Herzen 1984].) Clouds are complex natu-
ral phenomena, and attempting a rigorous physical simulation of their growth and
the transport of light within them is computationally prohibitive. Rather, we seek
techniques that produce results consistent with a viewer’s expectations of what a
cloud should look like, without overthinking the underlying physical properties.
One such shortcut is the use of cellular automata to grow clouds. You might
remember cellular automata from the game Life, where very simple rules about a
virtual cell’s neighbors can produce complex colonies of cells that grow and
shrink over time. Work from Nagel and Raschke [1992] and Dobashi et al.
[2000] applying this same idea to the formation and growth of clouds is summa-
rized here.
There is some physical basis to this technique; in general, we know that
clouds form when a humid pocket of air rises and cools, causing a phase transi-
tion that turns its water vapor into water droplets. We also know that clouds tend
to form vertically and horizontally, but generally don’t grow downward.
We start by defining our cloud layer as an axis-aligned bounding box divided
into cubic regions that represent cells of air. Later, this three-dimensional array of
cells will become the voxels that are volumetrically rendered. Each cell consists
of three states, each represented by a single bit:
VAPOR_BIT, indicates whether the cell contains enough water vapor to form a
cloud.
2.1ModelingCloudFormation 23
PHASE_TRANSITION_BIT, indicates that the phase transition from vapor to
droplets is ready to occur in this cell.
HAS_CLOUD_BIT, indicates that the cell contains water droplets, and should be
rendered as a part of a cloud.
The rules may be summarized simply:
1. A cell acquires the
VAPOR_BIT if it currently has the VAPOR_BIT (which is
initially set randomly throughout the cloud volume) and doesn’t have the
PHASE_TRANSITION_BIT.
2. A cell acquires the
PHASE_TRANSITION_BIT if it does not have the
PHASE_TRANSITION_BIT and it has the VAPOR_BIT, and one of its neighbors
beside or below it also has the
PHASE_TRANSITION_BIT.
3. A cell acquires the
HAS_CLOUD_BIT if it has the HAS_CLOUD_BIT or the
PHASE_TRANSITION_BIT.
Additionally, there is some random probability that a cell may spontaneously
acquire humidity or phase transition or that it may lose the
HAS_CLOUD_BIT as the
cloud evaporates. As the cellular automaton continues to be iterated, this results
in clouds randomly changing shape over time rather than reaching a steady state.
We find that a ten percent probability of acquiring vapor or losing cloud status,
and a 0.1 percent probability of spontaneously hitting a phase transition, produc-
es satisfying results. This logic for a single iteration of the automaton is imple-
mented in Listing 2.1, which assumes the existence of a 3D
cells array for
which each cell includes a character for its states and floating-point values for its
phase transition, vapor, and extinction probabilities.
#define HAS_CLOUD_BIT 0x01
#define PHASE_TRANSITION_BIT 0x02
#define VAPOR_BIT 0x04
for (int i = 0; i < cellsAcross; i++)
{
for (int j = 0; j < cellsDeep; j++)
{
for (int k = 0; k < cellsHigh; k++)
{
char phaseStates = 0;
24 2.Modeling,Lighti ng,andRenderingTechniquesforVolumetricClouds
if (i + 1 < cellsAcross)
phaseStates |= cells[i + 1][j][k]->states;
if (j + 1 < cellsDeep)
phaseStates |= cells[i][j + 1][k]->states;
if (k + 1 < cellsHigh)
phaseStates |= cells[i][j][k + 1]->states;
if (i – 1 >= 0)
phaseStates |= cells[i – 1][j][k]->states;
if (j – 1 >= 0)
phaseStates |= cells[i][j – 1][k]->states;
if (k – 1 >= 0)
phaseStates |= cells[i][j][k – 1]->states;
if (i – 2 >= 0)
phaseStates |= cells[i – 2][j][k]->states;
if (i + 2 < cellsAcross)
phaseStates |= cells[i + 2][j][k]->states;
if (j – 2 >= 0)
phaseStates |= cells[i][j 2][k]->states;
if (j + 2 < cellsDeep)
phaseStates |= cells[i][j + 2][k]->states;
if (k – 2 >= 0)
phaseStates |= cells[i][j][k 2]->states;
bool phaseActivation =
(phaseStates & PHASE_TRANSITION_BIT) != 0;
bool thisPhaseActivation = (cells[i][j][k]->states &
PHASE_TRANSITION_BIT) != 0;
// Set whether this cell is in a phase transition state.
double rnd = random(); // Uniform within 0.0 – 1.0.
bool phaseTransition = ((!thisPhaseActivation) &&
(cells[i][j][k]->states & VAPOR_BIT) && phaseActivation)
|| (rnd < cells[i][j][k]->phaseTransitionProbability);
if (phaseTransition)
cells[i][j][k]->states |= PHASE_TRANSITION_BIT;
else
cells[i][j][k]->states &= ~PHASE_TRANSITION_BIT;
2.1ModelingCloudFormation 25
// Set whether this cell has acquired humidity.
rnd = random();
bool vapor = ((cells[i][j][k]->states & VAPOR_BIT) &&
!thisAct) || (rnd < cells[i][j][k]->vaporProbability);
if (vapor)
cells[i][j][k]->states |= VAPOR_BIT;
else
cells[i][j][k]->states &= ~VAPOR_BIT;
// Set whether this cell contains a cloud.
rnd = random();
bool hasCloud = ((cells[i][j][k]->states & HAS_CLOUD_BIT)
|| thisAct)
&& (rnd > cells[i][j][k]->extinctionProbability);
if (hasCloud)
cells[i][j][k]->states |= HAS_CLOUD_BIT;
else
cells[i][j][k]->states &= ~HAS_CLOUD_BIT;
}
}
}
Listing 2.1. Cellular automata for cloud formation.
You may have noticed that the probabilities for spontaneous acquisition of
the vapor or phase transition states, as well as the probability for cloud extinc-
tion, are actually stored per cell rather than being applied globally. This is how
we enforce the formation of distinct clouds within the automaton; each cloud
within the layer is defined by an ellipsoid within the layer’s bounding volume.
Within each cloud’s bounding ellipsoid, the phase and vapor probabilities ap-
proach zero toward the edges and the extinction probability approaches zero to-
ward the center. Simply multiply the extinction probability by
222
222
x
yz
abc
,
where
,,
x
yz is the position of the cell relative to the ellipsoid center, and
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.253.223