Professional Documents
Culture Documents
November 2004
Charles Sturt University
David Carr
ii
Many thanks to my supervisor, Jim Geyer for always being available and willing to give up
precious time to assist; and to my parents Paul and Christine Carr, for your support and
patience.
iii
Abstract
This thesis documents research and experimental work conducted in a study
of computational models suitable for representing dynamic clouds of airborne
dust, in real-time computer graphics applications. In this case the dust clouds
under consideration are those created by the movement of an automobile
travelling at speed over an unsealed surface. The modelling of dust clouds on
the computer is an area where there is a distinct lack of published material on
appropriate simulation and rendering techniques. The work conducted here is
intended to address this and open some ways to future development.
Established methods used for simulating and rendering clouds of dust in real-
time applications are examined, as observed in computer games and found in
computer graphics literature. A number of techniques used for the
representation of other types of particle cloud effects are also considered to
supplement this. Several models are implemented using the established
methods, based on particle systems and billboard rendering techniques,
before some new methods for representing the cloud are introduced to the
systems.
A novel and unique technique for representing the dust cloud volumetrically
is developed. The method is based on the use of an octree space-partitioning
system to provide fast and memory-efficient representation of the space
occupied by the cloud. This is combined with the use of a particle system for
speedy resolution of the movement of the cloud. The model provides
grounding for further development with the aim of creating convincing
voluminous dust cloud effects in computer games.
iv
Contents
Introduction .............................................................................................. 1
1.1 Topic Opening .................................................................................................. 1
1.2 Constraints of Real-Time Applications ........................................................ 1
1.3 Modelling and Rendering of Dust Clouds ................................................... 2
1.4 Objectives........................................................................................................... 2
1.5 Thesis Structure................................................................................................. 3
v
4.1.3 Rendering .................................................................................................48
4.2 The Dynamic Octree Model......................................................................... 49
4.2.1 Octree Space-Division ...........................................................................49
4.2.2 Particle System Model............................................................................52
4.2.3 Octree Construction...............................................................................52
4.2.4 Recursive Octree Construction ............................................................54
4.2.5 Search-Principle Octree Construction ................................................55
4.2.6 Rendering .................................................................................................59
4.2.7 Why Two Different Octree Construction Algorithms Were
Implemented: Depth-Sorting by Traversal........................................63
Conclusion..............................................................................................123
6.1 Study of Methods for Dust Cloud Representation ................................123
vi
6.2 New Volumetric Dust Model.....................................................................124
6.3 Suggestions for Further Work....................................................................124
Bibliography...........................................................................................126
vii
List of figures
Number Page
Figure 2.1: Dust clouds from rally cars travelling at speed on different
surfaces. Note the different appearances (colour, granularity,
consistency) of the clouds, and the effect of the turbulent wake in
the bottom image. (Images from ARC website, www.rally.com.au) 6
Figure 2.2: A DirectX 9 program demonstrating a particle system to
animate an explosion of magical sparklies. (Image from 32bits.co.uk
[9]) 9
Figure 2.3: Different types of particle systems and their applications. (Figure
from [2].) 12
Figure 2.4: Tyre smoke effects from cars in EA Games’ 2003 Need For Speed
Underground. The smoke is drawn as a stream of textured billboards
from the wheels. (Image from IGN.com.) 13
Figure 2.5: The billboard is always oriented normal to the camera, so it will
be rendered with its surface parallel to the screen. 14
Figure 2.6: Billboard demo application from the Microsoft DirectX 9 SDK
[18]. Every one of the trees drawn on this landscape is a billboard. 15
Figure 2.7: The way that objects overlap in a scene is one of the fundamental
cues for depth perception. 16
Figure 2.8: These two images show the effect of Z-buffering on rendering a
scene. In the top image, the buildings have been rendered in an
arbitrary order without Z-buffering, resulting in a mess. The bottom
image shows the same scene with Z-buffering; the obscured parts
of far buildings remain hidden by those nearest, preserving the
integrity of the scene. 17
Figure 2.9: Textured billboards in a particle system rendered without Z-
buffering (left) and with Z-buffering. 18
Figure 2.10: Transparent/translucent billboards rendered without depth-
sorting (left), and with depth-sorting. 19
Figure 2.11: Particle effect in the 1996 game Monster Truck Madness, by
TRI/Microsoft. (Screenshot provided by Phineus Gage.) 20
Figure 2.12: As the spaceship comes in to land in Freelancer (2002, Digital
Anvil), it kicks up a dust cloud, represented by billboards. The view
from overhead (bottom image) exhibits a great deal of occlusion
from the polygons of the billboards intersecting the ground surface. 21
Figure 2.13: Screenshots from Codemasters game Colin McRae Rally 04.
(Images from IGN.com and ATARI.com.au) 22
Figure 2.14: Two rendered images of the system for different car speeds,
using about 3000 particles in the system. (Images from [2].) 23
Figure 2.15: A rendering from a high-fidelity (non-real time) implementation
of the model, employing 20,000 fine particles. (Image from [2].) 24
Figure 2.16: Generation of dust particles by the motion of a vehicle. (Image
from [2].) 25
Figure 2.17: Clouds (shown on the right) are built up by layered sprites (left)
in Microsoft Flight Simulator 2004: A Century of Flight. (Image from
[17].) 27
viii
Figure 2.18: Impostors, outlined in the image, are textured polygons oriented
toward the viewer. (Image from [6].) 28
Figure 2.19: A cloud scene from Microsoft Flight Simulator 2004: A Century of
Flight. (Image from [17].) 28
Figure 2.20: Voxelisation divides the simulation space into cubes. (Image
from [13].) 29
Figure 2.21: Renderings of rising smoke created by the simulation models of
[5]. (Image from [5].) 29
Figure 3.1: Application screenshot employing the billboards dust model. 31
Figure 3.2: Screenshot showing specifically the particles created by the
particle system used in the application. 32
Figure 3.3: Texture used for the billboard dust model. The texture employs
an alpha channel for translucency/transparency effect. 33
Figure 3.4: This graphic shows a screenshot from an implementation of the
billboard dust model (top), and then the same image again with
emitter locations, some individual particles and their billboards,
highlighted. 34
Figure 3.5: Application screenshot employing the particle dust system
(bottom); and (top) an image from the model by Chen et al [2]
(image from [2]). 37
Figure 3.6: Because new particles are created at discrete moments in time,
they may appear in small clusters, and gaps occur in what should be
a continuous stream of particles. This problem is illustrated in the
figure above; the circles show the clustering effect of newly created
particles. 39
Figure 3.7: With the particles initial positions interpolated between the
emitters’ previous and current discrete locations, newly created
particles appear in a continuous thin line. 40
Figure 3.8: A combination of interpolating emitter positions and applying a
small random perpendicular variance creates a more believable-
looking stream of particles from each emitter. 40
Figure 3.9: This graphic shows conceptually how the pseudo-airflow effect is
created. First, a given particle must be within a certain distance from
the car, measured from its centre. Second, the particle must be in
the space behind the car. 42
Figure 4.1: Application screenshot employing the voxel dust model. 46
Figure 4.2: Rendering voxels as cubes, versus representing each voxel with a
square that always faces the viewer (a billboard). 48
Figure 4.3: Application screenshot employing the octree-based dust model. 49
Figure 4.4: Two-dimensional space division in a quadtree: initial division
(left), and after three divisions. 50
Figure 4.5: Three-dimensional space division in an octree. 50
Figure 4.6: Example octree node and tree structure. 51
Figure 4.7: This image shows a representation of an octree’s subdivision of
space for approximating the location of a small particle object in the
upper right corner. The octree avoids subdivision in any cells that
the particle is not in, so that memory is not wasted representing
empty voxels. 51
Figure 4.8: This graphic demonstrates how different voxel sizes stored in the
octree (bottom image) are used to create the visual effect of the
ix
dust cloud expanding (top image). The voxel sizes are varied
according to the ages of particles in the particle system. 53
Figure 4.9: Example octree structure utilising the methods described. Voxels
of different sizes can be created by assigning higher up the tree. 54
Figure 4.10: Six steps in constructing an octree by the recursive process. At
each node, a list of particles in each octant is constructed and then
processed for assigning new nodes or voxels. 55
Figure 4.11: This figure shows the correspondence between the data
structure in memory (left) and its representation in three-
dimensional space (right). Concatenating the bits of the coordinates
shown in the table gives the indexes used to traverse the tree and to
find the searched voxel. (Image from [15].) 56
Figure 4.12: Process to embed six particles in an octree by the search-
principle process. For each particle, the location in the tree where
that particle should go is identified and the path to that position, if
it doesn’t already exist, is constructed. 58
Figure 4.13: The final appearance of the textured billboards. 59
Figure 4.14: Traversal order for rendering the (contents of) octants of an
octree in farthest-to-nearest order, for the given eye point and line-
of-sight vector. 63
Figure 4.15: An octree where each individual octant represents, and is
rendered as, a billboard. The image is oriented toward the reader, so
line-of-sight is going into the page. By using a particular order of
traversal through the tree, the octants will be visited in order of
farthest to nearest, and the billboards will be rendered according to
the painter’s algorithm as required. 64
Figure 4.16: This figure presents a similar scenario as the previous, except
this time the billboards are at the second level of the octree instead
of the first (for clarity, only the upper half of the octree is being
used). The traversal sequence is the same, except that we preform
nested traversals to the end of the tree when sub-nodes are
encountered. 65
Figure 4.17: This diagram shows the effect of the variable-size billboards
that were implemented in the dust representation model, by
assigning voxels at different points in the tree (not just at the
bottom level). In this case the octree node represents a billboard at
itself (designated N), as well as one billboard for each of its octants.
The large billboard splits the eight smaller ones around it, requiring
a traversal sequence that inserts billboard N in the middle of
processing the four octants. 67
Figure 4.18: Here a billboard N is stored at a node in the octree, which also
points to a child node containing billboards that are two
subdivisions smaller (i.e. one-quarter size). The large billboard again
splits the smaller ones, with some behind it and the rest in front. It
is more complicated to determine where in the sequence N should
be handled for adding to the billboard list, if it fits in the sequence
at all. 68
Figure 5.1: These four images show the four different models implemented
and compared for dust cloud representation. From top: the
billboards model, the literal particle system model, the voxel grid
based model and the octree space partitioning model. 71
x
Figure 5.2: Screenshot of the ‘Dusted’ base application. Note the ‘Heads-Up
Display’ text readouts of the application state. 74
Figure 5.3: An example of a logical game loop for a multimedia game
application. (Image from 32bits.co.uk [9]) 76
Figure 5.4: Class diagram for the core Dusted application. 77
Figure 5.5: Falcon XR8 utility in the Dusted application. 82
Figure 5.6: Terrain dirt texture file. (Original image by Claes Wikdahl.) 83
Figure 5.7: Screenshots showing the camera views used; ‘far’ chase view
(left) and side-on and zoomed out. 85
Figure 5.8: Screenshot of the Dusted2 application, employing the billboard
dust model. 86
Figure 5.9: Class concept diagram of the billboard dust model. 87
Figure 5.10: This shows the components of the texture used in the billboard
dust model. On the left is the texture image RGB channel, that
defines the colour, and the Alpha channel that defines opacity
(where black is fully transparent and white is fully opaque). These
are combined to give the output ‘puff’ texture on the right, as it
appears applied to the billboards. 89
Figure 5.11: Two screenshots from the Dusted2 application, showing the
effect with the car travelling at different speeds. The results are
consistent with what can be observed in games and models
employing this type of technique; the model exhibits similar
behaviour and visual flaws. 90
Figure 5.12: Graph of the performance of the billboard dust model, with
and without the quick-cull optimisation. 92
Figure 5.13: Screenshot of the Dusted3 application, employing the particle
dust model. 94
Figure 5.14: Class concept diagram of the literal particle dust model. 95
Figure 5.15: These screenshots show the particle dust system in action. In
the bottom picture, the vehicle is crossing through the particle
cloud under acceleration, demonstrating how the drifting particles
have their motion disturbed by the airflow modelling. 96
Figure 5.16: These screenshots show the effect of different viewing distance
on the particle cloud. From moderately far away (top image), most
of the particles are drawn into a small space on the screen, and the
shape of a cloud can be seen. Close up (bottom image), the particles
are spread across a large area of the screen and appear too disperse
to form a recognisable cloud. 98
Figure 5.17: Graph of application performance (FPS) versus the number of
particles in the system. The processing cost of the model scales
close to linearly as the particle count increases. 99
Figure 5.18: Screenshot of the Dusted4 application, employing the
volumetric dust model. 101
Figure 5.19: Class concept diagram of the volumetric dust model. 102
Figure 5.20: Instability in the voxel grid due to dispersion/fade rate
mismatches, causing ‘bubbles’ or ‘pockets’ of density to take on
lives of their own. (Image enhanced for contrast.) 105
Figure 5.21: Screenshot showing the voxel-based dust model in action. 106
Figure 5.22: The recorded performance of the voxel dust model drops off
sharply as the number of voxels active in the simulation increases.
Shown on the graph is an exponential trendline for comparison. 107
xi
Figure 5.23: Screenshot of the Dusted5b application, employing the octree
space-partitioning (search-principle construction version)
volumetric model. 108
Figure 5.24: Class concept diagram of the volumetric dust model employing
a particle system and octree space partitioning. 109
Figure 5.25: The texture used with the billboards in this model defines only
any alpha-channel (left) for transparency and translucency. As with
the previous voxel-based model, the billboard polygons use a set
diffuse colour (centre). This is combined with the alpha-channel
from the texture to create the final billboard appearance of a brown
circle with transparent edges. 111
Figure 5.26: Screenshot of the octree space-partitioning dust system
(recursive construction version). 114
Figure 5.27: This screenshot shows a representation of a typical space
partitioning defined by the octree. The partitions are represented in
the image as a wireframe of cubes within cubes. Those cubes that
enclose billboards correspond to the voxels describing the cloud. 115
Figure 5.28: The appearance of the cloud when using the (failed) tree
traversal depth-sorting algorithm. Artefacts due to Z-buffering are
quite bad, although the algorithm does negate the effect of varying
the camera angle to a degree. 116
Figure 5.29: The appearance of the cloud when using the tried-and-tested
quick-sort depth-sorting algorithm, implemented in the Dusted5
application. The billboards are properly sorted, and the cloud
exhibits zero occurrences of artefacts. 117
Figure 5.30: The appearance of the dust cloud when using the slightly flawed
search-and-insert depth-sorting algorithm, implemented in the
Dusted5b application. The result is not perfect, with some slight
artefacts still occurring. 117
Figure 5.31: As the cloud grows in length, more voxels and therefore more
partitions are needed to represent it; this has the effect of more
nodes being used in the octree. Note that the rest of the empty
space is not partitioned, so memory is not wasted storing empty
voxels. 118
Figure 5.32: The average number of nodes needed to represent a dust cloud
increases as the vehicle speed. The number of nodes representing
voxels (and are hence rendered as billboards) tends to be roughly
half of the total nodes in the octree. 119
Figure 5.33: Comparison of the performance of the two octree-based dust
models. 120
xii
Chapter 1
Introduction
1
rendering of new frames must be fast enough to maintain the illusion of
persistence of vision, which is generally taken to be a rate of 25 frames per
second. Thus, the largest constraint imposed by real-time is the amount of
time available to perform computation and rendering [11].
Computer games, especially those that fall into the category of ‘fast-twitch’
which are oriented around fast or dynamic action, are a particularly illustrative
example of interactive real-time applications. Where a game is challenging the
player’s reflexes and quick decision-making, even momentary pauses in the
display of action and feedback to the player would be disastrous for their
participation in the activity and immersion in the game world. Games
generally represent quite a special application, as they are often required to
simulate a rich and interactive world and intelligent agents, responding to the
effects of player action and all the while present information back to the
player seamlessly and without interruption. Obviously, this places special
considerations on the various computations in use; everything must work
together smoothly. If any one thing takes too long, then the other activities to
be performed by the game may not have time to process, and the application
will not be able to deliver at the required rate.
The most widely used methods for representing dust clouds revolve around
the use of pre-drawn textures mapped to billboards. This approach is fast to
compute, but is very contrived and has not changed in many years. Although
with tweaking billboards can produce good results, the technique is inherently
an inaccurate representation, and the effect it produces can often appear
flawed and obvious.
1.4 Objectives
Given the visual and simulation shortcomings of the most widely-used of the
current methods, the overall aim of the work is to construct a system for
simulating and rendering a cloud of dust to a higher degree of behavioural
and aesthetic believability, and suitable for real-time applications on consumer
hardware. The methods evaluated are considered on the quantitative terms of
processing speed and scalability, and subjective terms of appearance and
2
realistic animation. It is anticipated the systems explored will find use in
computer games and simulations.
In review of the literature, it was found that very little published work could
be found on modelling and rendering techniques of dust clouds. However,
material on techniques for creating realistic rain clouds was abundant. The
problem of rendering realistic clouds in the sky is quite well studied (seeming
to make quite a popular project) and models have been produced that create
very believable renderings of clouds in real-time. The original intention for
this project was to examine what methods that have been developed for real-
time cloud rendering might be adaptable for improving real-time dust
rendering. Appropriate aspects from cloud generation algorithms were to be
used to extend the representation methods of dust, with the aim of creating
more realistic animated renderings.
Unfortunately, this lofty goal came unstuck with the realisation that those
cloud models that run in real-time mostly do so by taking advantage of the
fact that the clouds do not change rapidly (if at all) over time. Additionally, it
was quickly found that current methods of representation of dust were
completely inadequate for doing any such work. As a result of this, the focus
of the project diverted into exploring better representation methods. These
would lay the grounding for future extension, which could include the
adaptation of some rain cloud modelling techniques as originally proposed.
3
• Chapters 3 and 4 cover the details of the methods that were
implemented as dust representation models. In total, four distinct
models were developed. Chapter 3 covers the two ‘established’
methods, using particle systems and textured billboards. Chapter 4
examines the methods that were newly developed to represent the
dust cloud volumetrically.
4
Chapter 2
Sections 2.1 and 2.2 present introduction and context for the project.
Section 2.4 examines and gives examples of the method of billboards, used
widely in games for representing dust and smoke effects.
5
Figure 2.1: Dust clouds from rally cars travelling at speed on different surfaces.
Note the different appearances (colour, granularity, consistency) of the clouds,
and the effect of the turbulent wake in the bottom image. (Images from ARC
website, www.rally.com.au)
6
2.2 Context of Work
In many virtual environments and computer graphics applications, it is often
desirable to accurately represent many natural phenomena. Foremost
examples include fire, water, and smoke effects. These are all effects that have
received a large amount of effort put into developing dynamic modelling and
animated rendering techniques (eg. [11]). But there are other phenomena that
we also frequently wish to include in our representations of outdoor scenes,
such as realistic-looking clouds in the sky, and – the focus of this thesis –
billowing clouds of dust.
The trend to create more realistic and immersive environments has been
driven principally through increasingly advanced and true-to-life visuals. Since
the dawn of computer gaming, graphics have consistently been one of the
fastest evolving facets in each new generation of games. It’s a cliché, but
today’s games are more visually stunning than ever before. One recent
example of a game that set a high graphical benchmark is Far Cry by CryTek,
which is set in a beautifully detailed tropical island with photo realistic
vegetation and reflective, glassy blue water. Two of the most eagerly
anticipated games in recent times, Doom III by id Software and Half-Life 2 by
Valve, each also feature advanced graphics effects. Among other effects, Half-
Life 2 produces realistic facial expressions and animations of characters by
modelling the underlying muscle structures. Doom III takes a fully integrated
approach to lighting effects, to have everything lit correctly. Light sources and
effects properly illuminate everything in the game, and create subtle shadows
and mixed colour. This is as opposed to the usual cheating used in most 3D
games, where shadows are painted onto areas and separate lighting
workarounds for characters that need to roam freely; cheating can fool the
eye, but its transgressions become apparent when you see how things are
7
meant to be [1]. These improvements to graphical realism have been possible
because of the continuing rapid advancements in consumer computer
hardware, particularly the calculating power and rendering capabilities of
graphics cards in recent years.
In the case of dust or smoke clouds, the general approach is to render pre-
drawn textures mapped to billboards (discussed in detail later). This is an
approach that is fast to compute and has been in use for many years (since
before hardware-based 3D graphics acceleration became standard in PCs and
game consoles, in fact). With tuning, billboard methods can produce good
visual results. However, it is very contrived for dust modelling, and suffers
inherently from visual flaws. While many graphical effects have become much
more sophisticated over the years, the techniques for dust and smoke not
changed, and even the latest games still exhibit the same dated faults. The
objective of this project is to investigate alternative methods that are useful to
produce more effective results.
8
2.3 Particle Systems
The particle systems modelling technique was first introduced to computer
graphics in 1983 by William Reeves [2]. They are useful in modelling ‘fuzzy’
objects – dynamic phenomena that are irregular or ill-defined. These include
things such as dust, smoke, water spray, fire, explosions, clouds, or grass
([2],[11]).
9
2.3.1 Particles
The particle objects used in the particle system represent the objects of
interest that make up the system. Over time, particles are created into the
system, move and change form with the system, and then eventually are
removed from the system when their lifetime expires or some other criteria is
met. Particles may have the following attributes:
• Colour (RGB);
• Transparency (alpha);
• Mass;
• Age/lifetime value;
• And others.
The age value accumulates the time elapsed since the particle was created.
Particle systems typically have an upper limit to the particles’ lifespan; if a
particle’s age reaches this value then it is removed from the system. We may
also remove particles from the system according to other criteria; for example,
with particles representing an airborne dust cloud, we may choose to remove
any particles that travel below the ground surface, as they have been reclaimed
by contact with the ground. Usually, however, at any time the particles are
being generated into the system and aged, with none disappearing from the
system. The use of a lifetime limit ensures that all particles are eventually
purged from the system, facilitating the cycle of new particles being created.
10
2.3.2 Emitters
In computational modelling, particle systems usually implement ‘emitter’
objects. The emitter is so called because it is considered to be the source of
new particles in the system [9]. Usually, it is convenient to design the
implementation of the emitter as the representative of the particle system as a
whole. That is, the emitter owns and controls the particles it ‘creates’, and
operations on the emitter are operations on the particle system itself.
3. Any particles that have existed beyond their prescribed lifetime (or
other criteria) are removed;
2.3.4 Modelling
Particle systems have different properties governed by underlying processes.
Figure 2.3 summarises the applications using different particle-based
simulation in computer graphics [2]. Dust is fuzzy and unstructured, and so
belongs to the category of stochastic particle systems as shown.
11
Figure 2.3: Different types of particle systems and their applications. (Figure
from [2].)
12
2.4 Dust and Smoke Effects in Computer
Games
The visualisation of dust and/or smoke effects is a staple of almost any game
that portrays outdoor (and often indoor) environments. Smoke from fires and
fumes from running engines, explosions, weapons fire and projectile impacts,
dust kicked up by the wheels of a vehicle or the footfalls of a character on the
ground, tyre smoke from skidding and ‘burnouts’, and many other occasions
require visual representation of puffs and clouds of tiny airborne particles.
These phenomena are all similar enough that they can be (and often are)
represented using the same technique of a billboard system. Billboards are a
method that is almost totally universally used for these situations, and that has
also remained virtually unchanged in all the years since dust and smoke effects
have been represented in games.
Figure 2.4: Tyre smoke effects from cars in EA Games’ 2003 Need For Speed
Underground. The smoke is drawn as a stream of textured billboards from the
wheels. (Image from IGN.com.)
13
2.4.1 Billboards
In 3D graphics, a billboard is an object that always faces the viewing ‘camera’
of the 3D scene. This means that regardless of where we point the camera
(i.e. how we set the view transform in our 3D application), if the billboard is
visible, it will be drawn as if it were oriented exactly normal to the camera [9].
This means it will always be rendered with its surface parallel to the screen.
Figure 2.5: The billboard is always oriented normal to the camera, so it will be
rendered with its surface parallel to the screen.
We can use billboards to stand-in for objects that may be too difficult,
complex or insignificant to be represented in the 3D scene using conventional
means (i.e. polygonal modelling). For example, a tree has complex shapes and
details. Realistic modelling of a tree would require a large number of
polygons. This representation would then be prohibitively expensive to
render, particularly if (as is likely to be the case) our scene requires multiple
instances of the tree. Using billboards however, we can use a 2D image of a
tree in place of the expensive 3D model in our scene; through billboarding,
the image will always be rotated to face the viewing camera, giving the
impression of a 3D object that we can view from any angle we like. Of
course, the tree (image) will look the same from whichever angle we view it
from and there will be a limited choice of standard trees, but this may be an
acceptable trade-off depending on the application we are developing.
14
Figure 2.6: Billboard demo application from the Microsoft DirectX 9 SDK [18].
Every one of the trees drawn on this landscape is a billboard.
• The world transformation is used to set the location, orientation and size
of objects in the world space;
• The view transformation defines how the scene will be displayed on the
screen by setting the position and direction of the viewing camera;
15
• The projection transformation performs the mathematics for the
perspective effect that creates the illusion of a 3D scene in the 2D
image on the computer monitor.
2. Set the elements of the fourth row of the matrix (the elements
controlling translation) to 0. It’s very possible that the view transform
translates (moves) the camera, which we do not want to apply to the
billboarded object; setting these elements to zero ensures no
translation will occur.
Perception of Depth
One of the fundamental cues for depth perception is the way that we see near
objects obscure objects behind them. When we view a 2D image, if objects
are seen to overlap then we can infer about the near-to-far arrangement of the
objects.
A A
B
B
Figure 2.7: The way that objects overlap in a scene is one of the fundamental
cues for depth perception.
16
For example, consider Figure 2.7. Each image contains two objects of
identical size and shape. In the first image, object B particle obscures object A
and so we assume B to be in front of A. In the second image, A appears on
top of B and we perceive object A to be closer than B.
Figure 2.8: These two images show the effect of Z-buffering on rendering a
scene. In the top image, the buildings have been rendered in an arbitrary order
without Z-buffering, resulting in a mess. The bottom image shows the same
scene with Z-buffering; the obscured parts of far buildings remain hidden by
those nearest, preserving the integrity of the scene.
17
Z-Buffering
Depth-Sorting
Z-buffering can have a particular implication for surfaces that are translucent
or transparent. Because Z-buffering only identifies whether surfaces are
behind or in front of objects already rendered, for simplicity the API
traditionally treats all surfaces as being opaque. While this is almost always the
case with most scene objects, the reverse is true for billboards; very often they
make use of transparencies when using an image as a stand-in for a more
complex object.
18
Figure 2.10: Transparent/translucent billboards rendered without depth-sorting
(left), and with depth-sorting.
Figure 2.10 shows the particle system of Figure 2.9 being used to represent a
dust cloud. The billboards are textured with the likeness of a ‘puff’ of dust.
The texture is transparent around the edge to hide the square shape of the
billboard surface, and the puff of dust itself makes use of translucency for
blending. In this case, the Z-buffering can produce visual artefacts resulting
from hidden-surface removal; although the billboards are ‘see-through’, they
are treated as being opaque, but the removal of the obscured parts of other
billboards means we see ugly gaps and edges right through the cloud.
Following the painter’s algorithm ensures that we will not see artefacts
resulting from billboards blocking one another out. These see-through
surfaces should be among the last things to be rendered in the scene, because
while the depth-sort will stop artefacts from rendering the billboards, they will
still be treated as ‘obscuring’ any other object subsequently rendered behind
them.
19
2.4.3 Depictions in Games and Problems
Billboard systems have been used in computer games to represent dust and
smoke effects for many years – since before hardware-based 3D graphics
acceleration became standard in PCs and game consoles, in fact. It is hard to
find examples of games that use any other technique. The original Monster
Truck Madness (1996, Microsoft) is one. It uses textured billboards for tyre
smoke on hard surfaces, but anywhere the vehicles travel off-road, a particle
system is used to display pick-up being thrown off the tyres. These are
rendered as coloured dots (matching the terrain being driven on) directly over
the scene (Figure 2.11).
Figure 2.11: Particle effect in the 1996 game Monster Truck Madness, by
TRI/Microsoft. (Screenshot provided by Phineus Gage.)
Since then, billboards have been used almost universally in all games for any
kind of particle clouds. The appearance of the effect has been refined over the
years, with improved graphics and animating techniques. The overall
approach has remained unchanged, however, and the same issues still exist.
The in-game screenshots from two popular games given in Figure 2.12 and
earlier in Figure 2.4, as well as the mock-up in Figure 2.10, demonstrate the
issues clearly. Firstly, each billboard is used to represent a single ‘puff’ of dust
or smoke. Built up, these can make a semi-convincing cloud. However, unless
really well disguised, they tend to be quite easily recognisable as obvious
multiples of the same object.
The second problem occurs when the polygonal billboards intersect with
other polygon surfaces. This causes occlusion and ‘cutting-off’ of the
polygons where they intersect. This is bad news for the billboards, as the soft
20
and blended shape suddenly has a line cutting through it and creating a sharp
edge. Sometimes, this does not matter too much – for example, if we are
viewing some low-lying dust or smoke clouds from a low horizontal angle
(like the first image of Figure 2.12), then the cutting-off will make the cloud
simply look like it is sitting above the ground surface. If the camera is
elevated, however (as shown in Figure 2.4 and the second image of Figure
2.12) then these lines can be seen between and through other billboards in the
collection. The dust looks like it has a flat edge on it, ruining the 3D illusion.
Worse, this also inadvertently emphasises the individual billboards in the
cloud further.
Figure 2.12: As the spaceship comes in to land in Freelancer (2002, Digital Anvil),
it kicks up a dust cloud, represented by billboards. The view from overhead
(bottom image) exhibits a great deal of occlusion from the polygons of the
billboards intersecting the ground surface.
21
All that said, billboard dust and smoke clouds can sometimes be made to look
quite good. One recent game (series) that does this is Codemasters’ Colin
McRae Rally 04 (CMR04) rally game. As the action takes place on dirt rally
roads, clearly some thought has gone into creating good dust cloud effects.
Multiple textures are used for frames of animation on each billboard, and in
variant shades of colour. The animation frames and movement of the
billboards smoothly mimic aspects of the visual expansion and dispersion of a
real dust cloud, giving a generally believable result. The design of the system
also guards against the common problem of the clouds intersecting the
ground, unlike the billboards shown in Figure 2.4. The individual billboard
‘puffballs’ can still be picked out, but both in motion and as still images the
renderings look good. This is an impressive implementation.
Figure 2.13: Screenshots from Codemasters game Colin McRae Rally 04. (Images
from IGN.com and ATARI.com.au)
22
2.5 Some Graphical Particle Cloud Models
This section touches briefly on some graphical and simulation models for
various particle cloud effects found in the collected literature. These came
from a wide range of topics, including rain clouds and smoke. The references
given here had a background influence on the models developed in the
project, or presented interesting techniques that were related to the work
being carried out, but is of interest only as background material.
Figure 2.14: Two rendered images of the system for different car speeds, using
about 3000 particles in the system. (Images from [2].)
23
Figure 2.15: A rendering from a high-fidelity (non-real time) implementation of
the model, employing 20,000 fine particles. (Image from [2].)
24
Figure 2.16: Generation of dust particles by the motion of a vehicle. (Image
from [2].)
As a vehicle travels over unpaved ground, the following occurs to cause dust
particles to become airborne:
25
and the properties of the particle will affect the location where it
leaves the tyre surface.
• The movement of the car creates fluid and turbulent airflow around
and behind it. The moving air underneath and behind the vehicle
creates a pressure gradient, and will lift fine particles from the ground
(Figure 2.16b). The dimensions of the vehicle will determine the
pressures and velocities of the air.
Once a particle enters the air, it will become entrained in the turbulent airflow
behind the car. The motion of airborne particles obeys Newton’s law. The
external forces include gravity force, and the air drag force from wind and the
turbulent air created by the movement of the car. Eventually, the turbulent air
calms down and the particle will drift. It will eventually return to the ground
depending on its properties and local conditions. Large particles will fall back
to the ground quickly, while fine particles can become suspended in the air for
an extended period.
26
2.5.2 Cloud Rendering
Rendering believable outdoor scenes can be greatly enhanced by showing
realistic clouds in the sky. The visual appearance of clouds is very complex
and varied. The problem of generating and rendering convincing (and
beautiful) images of clouds on computer graphics hardware is one for which
quite a lot of literature can be found, and a number of references from that
field were collected for this project. Since cloud generation has been so well
studied, and a number of real-time rendering models exist, it was hoped that
there might be some techniques that could be adapted to rendering dust.
Unfortunately, most of the measures and optimisations that allow such
models to run in real time rely on the fact that the clouds change shape only
very slowly, if at all. This is not suitable for a dust cloud, which changes
rapidly, although the models for rendering detail and lighting effects
([6],[7],[13],[16]) may be of future interest.
While the simulation of clouds ([7],[13]) is well outside of the scope of this
text, the methods employed for real-time rendering of clouds in Mark Harris’
SkyWorks cloud rendering engine ([6],[7]) and the game Microsoft Flight
Simulator 2004: A Century of Flight [17] did hold some interest.
Both SkyWorks and MS Flight Sim 2004 create clouds by layering sprites
(similar to small billboards) to build up the volumetric cloud shape and
appearance. In SkyWorks, the sprites are generated according to cloud particle
models and take into account light scattering and illumination. The sprites are
then organised into cloud shapes. For MS Flight Sim 2004, artistic control is
desired, and so the sprites are pre-drawn and organised by an artist into the
desired configurations.
Figure 2.17: Clouds (shown on the right) are built up by layered sprites (left) in
Microsoft Flight Simulator 2004: A Century of Flight. (Image from [17].)
Rendering the sprite collections as-is will result in a large amount of overdraw,
and impair performance. This is improved by the use of impostors. The sprites
27
for part or all of a cloud or clouds are dynamically rendered onto a texture
surface that serves as the impostor. The impostor is then displayed as a large
billboard that ‘stands in’ for the cloud. In this way, the rendering overhead is
greatly reduced.
As the camera moves around the scene, and simulation of cloud formation
and dissipation is performed, the impostors will need to be re-generated as
the appearance of the clouds changes. This is performed with minimal impact
to the frame rate, by spreading the impostor calculation over several frames.
Figure 2.18: Impostors, outlined in the image, are textured polygons oriented
toward the viewer. (Image from [6].)
Figure 2.19: A cloud scene from Microsoft Flight Simulator 2004: A Century of
Flight. (Image from [17].)
28
2.5.3 Simulation of Smoke
Smoke simulation ([5][12][13]) was investigated, as the animation of rolling
clouds of smoke has obvious similarities with billowing clouds of dust. None
of the smoke models were suitable for real-time applications, although the
voxelisation of space employed by them was influential with the development
of the dust models detailed in the rest of this thesis.
Figure 2.20: Voxelisation divides the simulation space into cubes. (Image from
[13].)
Figure 2.21: Renderings of rising smoke created by the simulation models of [5].
(Image from [5].)
29
Chapter 3
• The next chapter for those that were created anew, using techniques
invented or adapted from other areas.
Section 3.1 presents the first of the models, which uses the de facto standard
method of textured billboards to represent the dust cloud. This model was
created to serve both as a reference and an entry-point for the subsequent
development of other models.
30
3.1 The Billboards Model
This system was designed to replicate the technique that can be observed in
use almost universally in computer games (if not any application simulating
virtual environments) for representing dust and smoke, and many other
complex objects and phenomena. It is the technique of using textured
billboards, as described earlier in chapter 2.
This model was developed based on observation of the systems in use across
many games – copying the use of a basic ‘puffball’ dust texture image,
inferring methods of animating the cloud, and other things. It was
implemented here as a basic particle system, with each of the particles being
drawn as a billboard resembling a sphere of dust.
31
Each emitter creates particles at a constant rate while the vehicle is in motion.
That is, generation of new particles occurs only while the vehicle is moving
with speed above a (small) preset threshold, and no particles are created while
the vehicle is moving slower than this limit, or is stationary. The rate at which
new particles are created is modulated to a constant number of particles per
second at each emitter (the exact number could be varied, but 20 particles per
second was good to make a dense cloud). Because billboards are used to
represent the actual bulk of the dust cloud, the particle system can be
relatively low-density (the particles are sparsely spaced).
The particles used in the system have the minimal three attributes:
• Spatial location vector
• Velocity vector
• Age value
At creation, each new particle has its initial location set to that of the emitter
that spawned it. Its initial velocity set to a small random value (speed and
direction), with the restriction that movement on the vertical plane can only
be upwards, to prevent particles travelling below the ground level. The
particle then moves according to these settings, until such time as its age
exceeds the preset lifetime limit and it is removed from the system. The result
is that as the vehicle moves, the emitters at each wheel leave a stream of
particles behind it, which gradually drift in general upward and outwards
directions over time.
Figure 3.2: Screenshot showing specifically the particles created by the particle
system used in the application.
32
3.1.2 Billboards
To render the dust cloud, a textured billboard was drawn at the location given
by each active particle in the system. For the texture, an image representing a
round ‘puff’ or ball of dust was used (Figure 3.3); the texture makes use of
alpha-blending and transparency for effect.
Figure 3.3: Texture used for the billboard dust model. The texture employs an
alpha channel for translucency/transparency effect.
33
Figure 3.4: This graphic shows a screenshot from an implementation of the
billboard dust model (top), and then the same image again with emitter
locations, some individual particles and their billboards, highlighted.
This application included a ‘quick cull’ test for removing such unnecessary
billboards from the cloud. The algorithm is adapted from the example code
provided in the DirectX 9 SDK billboarding demo [18]. The cull test checks
the location of each particle, and removes those that are behind the camera
34
(and therefore not in view). It is carried out prior to performing the depth-
sorting operation, which should further improve the application’s
performance by removing unnecessary billboards from the sort procedure.
The quick cull is performed by iterating through the list of particles in the
particle system, calculating the vector of the particle’s location relative to the
camera. This vector is then projected against the camera’s direction vector (on
the horizontal plane). A negative dot product indicates the particle is behind
the camera, and so we can discard it and not bother rendering a billboard for
it. A pseudo-code outline for this is given in Listing 3.1.
Depth-Sorting
Given two particles, p1 and p2, we take the dot product d1 of p1’s
coordinates with the coordinates of the camera location, and the dot product
d2 of p2’s coordinates with the coordinates of the camera location. We then
compare dot products d1 and d2. If d1 is less than d2, then p1 is closer to the
camera than p2 and so the order must be (p2, p1); otherwise the order is (p1,
p2). In this way all the particles in the array are sorted into the required order.
This is given in Listing 3.2.
d1 = (p1.pos.x * Camera.dir.x) +
(p1.pos.y * Camera.dir.y) +
(p1.pos.z * Camera.dir.z);
d2 = (p2.pos.x * Camera.dir.x) +
(p2.pos.y * Camera.dir.y) +
(p2.pos.z * Camera.dir.z);
if (d1 < d2)
// Particle p1 is closer to the camera.
else
// Particle p2 is closer to the camera.
35
3.2 The Literal Particle System Model
The billboards-based model described previously is based on the use of a
particle system. The billboards are used to make each particle appear to
occupy a much larger space than its single coordinate value really implies,
allowing us to build up the cloud shape from a small number of sparsely
positioned particles. However if the system is too coarse, the result can lack
clarity in appearance and behaviour, and the individual billboards can be easily
identified.
The most obvious way we might address this is to increase the density of the
particle cloud and use smaller billboards at each particle – trading off the
efficiency in number of particles afforded by using billboards to obtain a
more fine-grained representation. Taken to the logical extreme, since the real
dust cloud is made up of many tiny particles, we may decide to use a particle
system where the individual particles correspond directly to the particles of
the real cloud. (Hence the term ‘literal’ used here to name the model, as the
particle system is used directly to represent individual particles.)
Real dust clouds consist of many fine airborne particles, so the representation
method presented here focuses on simulating at the level of the individual
particles using a very fine-grained particle system. Instead of using billboards,
each representing a sizable ‘puff’ of dust, each particle was rendered as a dot
on the screen representing a speck in the cloud. The cloud shape is then
formed from proximity of these many specks. This model was inspired by,
and is based very loosely on, the system by Chen et al [2], although avoiding
the great detail and physics of their model.
36
Figure 3.5: Application screenshot employing the particle dust system (bottom);
and (top) an image from the model by Chen et al [2] (image from [2]).
The particles in this system were given the additional attributes of a colour
value and a mass/weight value. The mass was intended to be used in some
physics calculations for realistic particle behaviour, but was mostly only
utilised in the role of a scaling factor. The colour value defines the colour and
the opacity of the particle for rendering as a dot on the screen. Once set at
initialisation of the particle, the colour component remains constant. The
opacity component is varied according to the particle’s age – changing from
fully opaque at creation, to fully transparent when the particle reaches the
lifetime limit. This means that the particles fade away to invisible at the point
that they are removed from the system.
37
3.2.2 Particle Creation
Again, four emitters are used, following the locations of the vehicle’s wheels.
The emitters in this system create new particles at a rate relative to the speed
of the vehicle, up to a preset maximum at a certain speed. That is, as the
vehicle increases in speed, the emitters increase in the number of particles
being created (up to a point). This helps maintain a steady consistency of
particles as the speed increases and the particle stream becomes further drawn
out from the vehicle covering more ground.
The following initialisation is performed for each new particle created at the
emitters:
• The initial position is set (discussed below).
• As before, the velocity is set to a small random value, with the usual
restriction on downwards movement.
• The colour value is chosen randomly from within a predefined range,
to create some variance in the appearance of the particle cloud. The
opacity part of the colour (controlled according to the particle’s age) is
set opaque.
• The mass is set randomly, again within a predefined range of values.
• Finally, the particle’s age value is increased by a small random amount,
artificially making some particles ‘older’ than others created at the
same time. This is done also to provide some variance to the
appearance of the cloud, so that some particles disappear faster than
others around them.
38
Figure 3.6: Because new particles are created at discrete moments in time, they
may appear in small clusters, and gaps occur in what should be a continuous
stream of particles. This problem is illustrated in the figure above; the circles
show the clustering effect of newly created particles.
This model uses a high-density particle system, so it tends to be the case that
on any given update, for the time elapsed since the previous update, the
system is required to create multiple particles from each emitter at once. Each
emitter occupies a single discrete location; if the vehicle is travelling fast, the
emitter’s current location may have moved an appreciable distance from
where it was on the previous update. If all newly created particles have their
position attribute initialised to the current position of the emitter, this will
cause the particles to appear in a cluster at one location. If the vehicle is
travelling fast, the distance covered in the time between updates will cause
gaps to appear in the particle stream, as shown in Figure 3.6. These gaps,
although short-lived because of the movement of the particles, are not
conducive to a good-looking particle cloud.
This problem can be solved by storing the last location of each emitter prior
to updating. When particles are created, initial positions are determined by
interpolating between the previous and current locations of the emitter. This
means that the particles will be spread out along a line drawn from the
emitter’s previous discrete location to its current, instead of being clustered in
one spot. In this way, gaps do not appear.
39
Figure 3.7: With the particles initial positions interpolated between the emitters’
previous and current discrete locations, newly created particles appear in a
continuous thin line.
40
To make the particles look like they are coming off the tyres of the car, they
should appear spread out within a wide strip rather than in a thin line. This is
achieved by modifying each particle’s position by a small random amount
perpendicular to the direction of travel. Consequently the particles appear in
the space covered by the width of the tyre, rather than originating from a
single point. This is shown by Figure 3.8.
In summary, each newly created particle has its position initialised by:
• Interpolating between the previous and current discrete locations of
the emitter; and
• Applying a small randomly-determined offset perpendicular to the
direction of travel.
Additionally, drawing from [2], a simplified air disturbance effect was added.
This was achieved by modifying the velocities of those particles in close
proximity to the moving car to be dragged along behind it, as if caught in the
turbulent air (see Figure 3.9.). Although not an accurate modelling of the
phenomenon, it produces a pleasing effect as the particles have their drifting
motion disturbed by the movement of the car.
• Two bounding spheres, centred on the car’s location, are used. The
first, larger sphere represents the volume of the ‘low’ airflow, and has
a volume equal to one-fifth the car’s current speed. The second,
smaller sphere is the ‘high’ airflow, with a radius of one-tenth the
speed. In this way, the radii of the spheres are varied according to the
speed of the car, so that the volume of disturbed air grows as the
speed increases.
41
• The locations of active particles in the system are tested against the
volume enclosed by the large sphere. If they are found to be inside
(that is, the distance of the particle from the centre of the sphere is
less than the sphere’s radius), a vector for the particle’s position
relative to the car is calculated and projected against the car’s direction
vector; a negative dot product indicates the particle is behind the car.
If a particle passes these tests then it is in the airflow volume, and we
only need to determine whether it is in the ‘high’ or the ‘low’ volume.
The particle’s location is tested against the smaller sphere; if it is inside
this, then it will be subject to the velocity perturbation for the ‘high’
airflow, otherwise it is treated as in the ‘low’ airflow.
• A particle within either sphere has its current velocity modified over
time in the direction the car is travelling, relative to the car’s speed.
For the ‘high’ airflow area this modifying value is the car’s speed. For
the ‘low’ airflow this value is scaled by the particle’s mass value to
reduce its effect.
Particles that are outside either of these volumes have their velocities
gradually decay, as they drift and hang in the air. They also have their
downward velocity increased, by gravity acting on the particle’s mass.
Figure 3.9: This graphic shows conceptually how the pseudo-airflow effect is
created. First, a given particle must be within a certain distance from the car,
measured from its centre. Second, the particle must be in the space behind the
car.
42
3.2.4 Particle Rendering
As the particles are processed, a list of data for rendering is prepared. The
particles are rendered as dots or ‘points’ on the screen. The data compiled
describes the 3D position and colour of each dot.
Because the colour also describes opacity – decreasing with age so that old
particles fade away to nothing by the time they are removed from the system
– the particles in effect behave like mini-billboards, insofar as they are see-
through (refer to Chapter 2). Therefore, they will be subject to the same Z-
buffering problem (that is, supposedly see-through particles blocking out
other particles that are farther away) if they are not rendered in strict order of
depth.
The particles are processed in the order they were created into the system,
and without depth-sorting, they are rendered in the order they were created.
The order that particles are created at the emitters can be biased to reduce the
occurrence of graphics artefacts from Z-buffering.
If the four emitters are handled sequentially – all the new particles for one
emitter being created before moving on to the next emitter – then particles
will always be created at one emitter before the rest. This can lead to the
particles along one side of the cloud (coming from an emitter on that side
first) blocking out those along the other side when the camera is oriented in a
particular direction.
43
Chapter 4
Section 4.1 presents the third model implemented in the course of the project,
which uses a basic voxel grid to represent dust volumetrically.
The principal philosophy to the new models given here was to represent the
dust cloud by volume, shifting away from the less substantive particle systems
and billboards.
Volumetric Representation
Particle systems have proven useful for simulating the movement in our
clouds of dust, but they work less well for giving the cloud a voluminous
appearance. Thus the idea of using a volumetric representation for the cloud
was investigated as a means for overcoming this.
44
computer screen surface, a voxel represents a unit cube in 3D space. To
represent a 3D object, we construct a three-dimensional grid of these cubes
and fill in (colour) the ones corresponding to the object, leaving the rest
empty (transparent). Thus voxels differ from the other approach of modelling
3D objects – polygons – as they represent the volume the object fills, whereas
polygonal methods represent surfaces.
Although all the models presented in this thesis were only created to fulfil an
experimental capacity, this one in particular never advanced beyond the most
preliminary stage, so its own visual results are extremely crude and
unpolished. However, it laid the grounding for the further direction of the
project, which resulted in the subsequent improved octree system discussed in
the next section.
45
Figure 4.1: Application screenshot employing the voxel dust model.
The simplest way to store the volumetric data is as a volume buffer [14] – a 3D
array of cubic cells where each cell contains either a value (making it a voxel)
or blank space. The drawback of this method is that it requires the most
memory of any storage method, as every voxel in the grid must be stored. A
cubic grid with length n always requires n3 memory to store.
46
opacity for rendering. When this value is zero (the initial state), the volume
represented by the voxel is empty and so it is drawn as transparent.
1. In the initial state, all of the voxels are empty; their density (opacity)
values are set to zero. These are designated ‘inactive’.
4. Each active voxel then has its density value reduced, by an amount
equal to its current value multiplied by a factor for the fade rate over
time. If this brings the density value below the aforementioned
threshold, then the voxel becomes inactive, and no longer passes
density to its neighbours (though it may still receive additive amounts
from voxels adjacent to it, and in due course become active again).
Because a single voxel may receive inputs from up to six neighbours,
the fade rate must be more than six times the dispersing rate to keep
the system stable.
To avoid having to laboriously search through the entire grid for voxels to act
on, a lookup table of the ‘active’ voxels is kept. A voxel is added to the active
list when its density value is greater than the threshold mentioned, and is
removed when its density drops back below the threshold.
47
Although a very simple (if rather mechanistic) model, it produces the desired
behaviour of the density cloud propagating into the voxel mesh from the
vehicle’s wheels, then spreading through it and fading away over time,
representing the cloud expanding and dispersing.
4.1.3 Rendering
Each voxel represents a cube in space, and we can render them as coloured
cubes. Alternatively, to simplify the rendering, as an easy optimisation we can
pretend that the cubes always face the viewer, which turns them into squares.
Because each voxel represents only one piece of information (colour), which
is still effectively displayed by the square, there is virtually no loss of detail
[14].
In 3D graphics terms, an object that always faces the viewer is the definition
of a billboard. Thus, here I use a square billboard to render each voxel, in the
same way that billboards were earlier used in rendering with a particle system.
The billboards are centred on the midpoint of the voxels (so that the axis of
orientation for each billboard is on the centre of the voxel it represents). The
diffuse colour of the billboard polygons is set to a constant for an appropriate
brown, with the opacity component set according to the density value at the
voxel.
Figure 4.2: Rendering voxels as cubes, versus representing each voxel with a
square that always faces the viewer (a billboard).
The use of billboards would allow the use of a texture that can give the
volume the appearance of some other shape (say spherical) instead of
square/cube, but as far as this model was developed the billboards were left
untextured, simply using the flat diffuse colour. Additionally, depth-sorting of
the billboards was never implemented, so they are rendered straight over the
top of the scene.
48
4.2 The Dynamic Octree Model
One of the primary problems encountered with the voxel grid model just
described was the huge amount of memory required for storage of the voxels
in even a small 3D grid. The requirement quickly becomes infeasible for a
fine-grained voxel grid to cover even a moderate area, and in mind of the
intended application of the models in real-time simulation and computer
games, the limitation of this was unacceptable. Alternative techniques exist for
storing volumetric data in more memory efficient ways, and include the
octree, binary space-partitioning tree, linear octree, and P.M. octree [14]. Here
the use of an octree was investigated for representing the volume space in
place of using a ‘dumb’ grid, while retaining the volumetric representation of
the dust cloud.
This model also returns to the use of a particle system for simulating the
movement of the dust cloud; the positions of particles are used to determine
and assign the volume the octree represents. There were two versions of the
octree-based volumetric model created, which differ in the processing they
use to construct the octree structure and prepare a list of billboards
representing the voxels. The first uses a recursive process to work through the
levels of the tree in a straightforward manner, assigning voxels at the end. The
second makes use of the unique searching properties of octrees, to find the
position where a voxel is required and assign it at once.
49
of the voxels are empty at any given time; the grid must cover a large space to
simulate the dust clouds as the vehicle moves around, but any dust cloud will
only take up a small proportion of the total voxels. Thus, storing all these in
memory is largely wasteful. In a case like this, an octree represents a ‘smarter’,
more memory efficient method of dividing space into volume elements.
The method for octrees stems from the 2D quadtree method used for storing
raster images. Quadtrees (Figure 4.4) provide good compression of images
that contain contiguous blocks of colour, by only representing the detail of
the image. They work by dividing the image into four even quadrants. Each of
these quadrants can be further divided into another four quadrants, and the
process continues until either all the cells contain a single type of data (a single
colour, or empty), or a maximum tree depth (specified by the user to define a
maximum resolution for the representation) is reached [14].
An octree (Figure 4.5) works on the same principle, except that each
subdivision occurs in three dimensions, dividing space into cubic octants. As
with quadtrees, each octant can be further subdivided, until all cells contain
individual data or a maximum tree depth is reached.
50
Figure 4.6: Example octree node and tree structure.
51
4.2.2 Particle System Model
This model returns to the use of a particle system for simulating the dust
cloud. The particle system is used to approximate the shape and movement of
the dust cloud, and then a volumetric representation of the cloud is created
with voxels defined by the octree.
The particle system used is adapted from that used in the ‘literal’ particle
system model. The particles used have four attributes:
• Spatial location vector
• Velocity vector
• Age value
• Colour and opacity values
This system has a few changes from the original – mostly discarding a few
of that model’s more esoteric features. It retains the original’s emitter system
and method of interpolating the initial positions of new particles between
frames. The extended modelling for the airflow ‘tow’ behind the car was
removed for simplicity of implementation, although the velocity is still
decayed over time for drifting particles.
The visual appearance of the dust cloud is handled by the octree system, so
the particles are not normally shown. The particle colour attribute was
retained for use with an optional toggle to show or hide the particles. Because
the octree is used to define the bulk of the cloud, a relatively low-density
particle system can be used, as with the billboarding model previously.
One octree is used in this model. The root node of the octree covers the
entire area in which the dust simulation is to take place, which in this case is a
space measuring 1km along a length. The model uses 12 levels of subdivision,
to produce (child) voxels with cubic dimensions of approximately 0.25 metres
at the bottommost level. This is a useful size for representing the cloud in
some detail without becoming overly fiddly.
Two alternative octree construction algorithms were written, and these are
described in the following sections. The general principle is that the octree is
constructed by repeatedly subdividing space to ‘home in’ on the locations of
52
the particles. When we reach the last level, a voxel is assigned at this position
to represent the volume indicated by the particle. The voxel stores an opacity
value relative to the particle’s age, for use in rendering as with the previous
voxel-grid model.
An extra element added to this is that voxels are not necessarily assigned at
the lowest level of the tree: voxels for older particles are assigned higher up
(producing larger voxels), to represent the expansion and dispersion of the
dust cloud. That is, during the construction process, a ‘young’ particle will get
assigned at the bottommost level of subdivision, for the smallest size (0.25m)
voxel. As the particle ages, the subdivision stops progressively higher up the
levels, so that the voxels assigned become progressively bigger. In other
words, essentially the volume represented by each particle grows larger over
time, as a representation of the cloud expanding over time. This exploits the
way the octree divides space into progressively smaller chunks to allow the
expanding volume of dust to be represented, as shown in Figure 4.8 and
Figure 4.9. The system is designed so that a given node may represent a voxel
(that is, an opacity value for a billboard), and can still have child nodes
branching off it (that is, smaller voxels within the space of the larger).
Figure 4.8: This graphic demonstrates how different voxel sizes stored in the
octree (bottom image) are used to create the visual effect of the dust cloud
expanding (top image). The voxel sizes are varied according to the ages of
particles in the particle system.
53
Figure 4.9: Example octree structure utilising the methods described. Voxels of
different sizes can be created by assigning higher up the tree.
1. Firstly, a list of all the active particles in the system is created, and the
root node (which encompasses the entire simulation space) is selected
for subdivision.
4. Each of the cubes is now considered in turn. If the cube’s list contains
no particles, it is ignored. If the list does contain particles, then the
cube is selected as the current node, and the cycle returns to step 2.
54
The process is shown in Figure 4.10. Coded as a recursive function, this
process will traverse a single path down the levels of the tree, operating on
smaller and smaller lists of particles. When the depth limit is reached or there
are no more particles left in the list, it will return to the previous node in the
line that still has particles to investigate, and then branch off from there; again
tracing a path down until the depth limit has been reached or the list of
particles is exhausted. Then it will return upwards and branch off again, and
so on until leaf nodes have been allocated for all particles and the entire tree is
filled in.
Figure 4.10: Six steps in constructing an octree by the recursive process. At each
node, a list of particles in each octant is constructed and then processed for
assigning new nodes or voxels.
Figure 4.11 shows how this works. The data structure in memory is shown on
the left, with a corresponding graphical representation in three-dimensional
space on the right. The tree given contains five levels, each represented in a
55
different colour. The eight voxels stored in the cell of the last level (shown in
the foremost corner of the 3D representation) are represented in pink.
The table in the figure shows the coordinates of the fifth voxel (index 4).
These values are scaled relative to the size and depth of the tree: five levels
deep, the octant cubes are 1/32 of the size of the cube representing the root
node, so in this example the coordinates for searching to this depth of the
tree are in the range 0 - 32. The coordinates of the fifth voxel (x = 30, y = 30,
z = 31) are then shown on the right side in binary. Finally, each column of
coordinate bits in the table corresponds to an octree level. Concatenating the
bits of each column gives the indexes (appearing in the last line of the table)
of each element in a cell for the corresponding level; this can therefore be
used to traverse the tree and find the searched voxel. This is the principle to
search a given voxel in an octree [15].
Figure 4.11: This figure shows the correspondence between the data structure
in memory (left) and its representation in three-dimensional space (right).
Concatenating the bits of the coordinates shown in the table gives the indexes
used to traverse the tree and to find the searched voxel. (Image from [15].)
56
2. Each particle in the list is processed; its coordinate values (and age)
are inspected to determine where in the octree the particle should go.
If the required path does not yet exist in the tree, nodes are added as
necessary to create it. With the path in place, a leaf node (voxel) is
assigned, and an opacity value is stored relative to the age of the
particle. If two or more particles arrive at the same leaf node, the
opacity value that is stored will be for the younger particle (giving the
higher opacity value).
Using this method, the octree can be constructed by a single pass of the
particle list, rather than multiple passes through various lists at each node. An
example is shown on the next page in Figure 4.12.
57
Figure 4.12: Process to embed six particles in an octree by the search-principle
process. For each particle, the location in the tree where that particle should go
is identified and the path to that position, if it doesn’t already exist, is
constructed.
58
4.2.6 Rendering
To render the dust cloud we simply need to render the voxels describing it.
For simplicity, billboards are again used to represent each voxel.
As with the previous voxel-grid model, the diffuse colour and opacity is set at
the billboards; however the billboards used here also employ texture-mapping
to hide the square shape of the surfaces. The texture used defines a circular
‘alpha-map’ where the centre is opaque and the edges transparent, but has no
colour of its own. When applied to the billboards, the diffuse colour and
opacity of the billboard is blended with the texture, so that the billboards still
use their own brown colour and translucency, but appear circular (Figure
4.13) and more natural than the squares used in the voxel-grid model.
The texture tends to make gaps appear between billboards that should
otherwise be adjacent; this was alleviated, by scaling the billboards larger than
the voxels they actually represent. The opacity of the billboard is varied
according to the age of the particle(s) in the voxel that it represents. This
means that as well as the voxels (and the billboards representing them)
becoming larger as the particles grow older, so they also fade away, which
helps represent the dispersion effect of the cloud.
Before billboards can be shown, they must be created. This model employs a
billboard list, which is pre-prepared with all the billboards required, prior to
rendering. In the implementations, preparation of the billboard list occurred
at different times depending on the method employed during construction of
the octree.
For the recursive method, the list of billboards is created as the octree is
constructed. In this method, the construction process works methodically
down the nodes of the tree, operating on groups of particles at each. This
59
means the construction process performs a complete traversal of the tree,
visiting each node once, and assigning each voxel location in the tree once.
This makes it convenient, then, to create the billboard list as the tree is
traversed. After the particle list for the current node has been processed, if a
voxel has been assigned at this node, we can add a billboard to the list
initialised with the size of the voxel and the opacity value written into it.
The same does not hold exactly in the case of the construction method
utilising the octree search principle. Because it works across the entire tree to
process the particles, some nodes may be traversed more than once. A voxel
may be assigned with an opacity value for one particle, then later on another
particle is found to be at the same location that requires the opacity value to
be re-written (as the process stores the highest opacity value for each voxel).
We cannot be sure when a voxel is assigned that it won’t be revisited during
the construction process; if a billboard is added to the list each time an
opacity value is written for a voxel, we may end up with duplicates in the list.
This could be solved by simply adding billboards to the list only when a voxel
is first assigned; ignoring subsequent visits to the voxel that change its opacity.
This may cause some billboards to be ‘out of date’ for the voxels they
represent when the octree construction is completed, but this may be an
acceptable trade-off depending on the application. Alternatively, we can use
some additional system to remember which billboards are created for which
voxels, so that whenever the opacity value at a voxel is changed we can find
its corresponding billboard and update it as well.
Depth-Sorting
60
traversal process to build the octree and create the billboard list, and then
iterates through the contents of the list for the depth sort.
The algorithm first calculates the dot product of the current octree node
(voxel) location with the camera heading. This value is then used in a
modified binary search, comparing with dot product values similarly
calculated and stored for each billboard in the list. A pseudo-code outline for
this algorithm is given in Listing 4.1.
The binary search method maintains upper and lower bounds to the search,
and searches by repeatedly halving this space. Initially, these bounds are the
start and end of the list; the algorithm tests the element located halfway
between the two bounds, so the search begins at the midpoint of the list. The
dot product calculated for the new billboard is compared to that stored for
the billboard at this position in the list. If the new billboard is found to be
further away than the billboard in the list, the search space is halved
downwards; otherwise it is halved upwards. The process continues repeatedly
halving the space being searched and testing the element stored midway
between the two bounds, until the size of the search space reaches zero. At
this point the index variable contains the position in the list where the new
billboard should be inserted. The elements after this position are moved up
the list, and the new billboard and its dot product value are stored. When the
process completes, the list contains the billboards ordered farthest to nearest
ready for rendering.
61
Listing 4.1: Pseudocode for the insertion procedure to create a depth-sorted
billboard list.
index += difference;
}
else
{
// Move search range to lower half
high = index;
index -= difference;
62
4.2.7 Why Two Different Octree Construction Algorithms
Were Implemented: Depth-Sorting by Traversal
The two construction algorithms (recursive and search-principle) described
follow different procedures for constructing the octree. In the
implementation, they also follow a different procedure for preparing the list
of billboards for rendering. The attempt was to use the traversal order of the
octree to perform a ‘free’ depth-sorting of the billboard list as it was built up –
we have to traverse the octree once to create the list, but with a particular
order of traversal through the octree nodes, we can ensure we visit each in a
way that ensures the billboard list constructed is already in depth-sorted order.
Figure 4.14: Traversal order for rendering the (contents of) octants of an octree
in farthest-to-nearest order, for the given eye point and line-of-sight vector.
63
Figure 4.14 shows how subdividing a space with an octree into a hierarchy of
cubes can be used for determining the rendering order of objects in a scene.
We assign each object in the scene to the cube it is within. The eye point and
line of sight of the viewer is shown, passing from right to left through the
bottom left corner of the cube. It is then easy to determine the farthest-to-
nearest order of all the cubes with respect to the viewer, and render their
contents in that order. In the example given in the diagram, cube 1 is the
farthest from the viewer location and 6 is closest, so the contents of 1 would
be rendered first and the contents of 6 last. We can do this by traversing the
nodes of the octree in a particular order – starting at 1 and ending at 6, as
shown.
In the case of the dust model described in this chapter, each cube in the
octree represents a volume of dust, rendered as a billboard. The billboards are
rendered from a list, prepared by performing a traversal of the tree. By
inspection of the camera angle relative to the cubes, we can set the order of
traversal prior to constructing the list. Then when the tree is traversed
according to this ordering, the billboards would be placed into the list in the
required farthest-to-nearest order. This would eliminate the need for a
separate depth-sorting loop, saving us some processing time.
Figure 4.15: An octree where each individual octant represents, and is rendered
as, a billboard. The image is oriented toward the reader, so line-of-sight is going
into the page. By using a particular order of traversal through the tree, the
octants will be visited in order of farthest to nearest, and the billboards will be
rendered according to the painter’s algorithm as required.
64
• We are looking along a diagonal inclined to the base of the octree.
The angle is such that cubes 4 and 6 are closer than cubes 1 and 3;
• The viewer is elevated and looking down, such that cube 7 is the
closest corner, and cube 0 is farthest away.
In the previous example the octree only has a depth of one. Often we have
multiple levels to the octree; in these cases, the sequence for traversing the
tree remains the same, as shown in Figure 4.16. In this illustration, the octree
is being viewed from the same angle, so we have the same 0-1-2-3-4-5-6-7
order of traversal through the elements of each node. When an element that
points to a child node (i.e. the cube is itself subdivided into cubes) is
processed, we start the sequence anew at the child, returning to the parent
node after all the elements at the child have been processed. This means that
when faced with a multi-level octree, the traversal process follows any and all
paths down to the end of the tree as they are encountered.
Figure 4.16: This figure presents a similar scenario as the previous, except this
time the billboards are at the second level of the octree instead of the first (for
clarity, only the upper half of the octree is being used). The traversal sequence is
the same, except that we preform nested traversals to the end of the tree when
sub-nodes are encountered.
65
For example, in the diagram we start the traversal at the root node; first
processing cube a, then cube b. Cube c points to a child node (i.e. it is
subdivided into a further eight cubes) and so we branch off to process cubes
c0-c1-c2-c3-c4-c5-c6-c7. These cubes are the bottom of the tree, so after this
we return to the root node and continue where we left off. The next cube is d,
which is also subdivided, so the traversal moves down again to process the
cubes partitioning d. At the end of the traversal, again we will have a list of
billboards that are already sorted into farthest-to-nearest order.
The above technique was written into the models developed. Both models
include a procedure that inspects the camera’s heading vector and sets a
traversal order accordingly. In the case of the model employing the recursive
octree construction method, the traversal order is set prior to constructing
(and implicitly traversing and creating the billboard list) the tree; the order
determines what order the nodes are visited and built up.
The Problems
So far the method to using traversal order for depth-sorting has been pretty
straightforward. Where it failed and ultimately became too complicated to be
properly realised, was (funnily enough) where the shortcuts and exploits had
been taken in using the octree for volumetric dust representation.
The first fundamental problem occurs when the exploit of using the octree to
represent voxels of varying sizes was introduced. This was the technique of
assigning voxels to intermediary nodes higher up in the tree; voxels so
assigned would be larger in size, the higher up the tree they were positioned.
66
This means we could have a node representing a voxel, and whose children
(or children’s children) also represented voxels, within the space of the parent
node.
Figure 4.17: This diagram shows the effect of the variable-size billboards that
were implemented in the dust representation model, by assigning voxels at
different points in the tree (not just at the bottom level). In this case the octree
node represents a billboard at itself (designated N), as well as one billboard for
each of its octants. The large billboard splits the eight smaller ones around it,
requiring a traversal sequence that inserts billboard N in the middle of
processing the four octants.
This leads to the situation where we have mixtures of different sized and
positioned billboards in the space of one node, as illustrated in Figure 4.17.
Here, there is only one level of subdivision separating the billboard N at the
node, from the eight billboards for its octants. The billboard N is centred on
the node’s midpoint, and splits the smaller billboards that are centred on the
midpoint of the octants. Here the previously given traversal sequence no
longer works. To create the billboards in the right order when the octree is
traversed, we will need to process the four octants (0, 1, 2 and 3) that are
behind N, backtrack to add N itself to the list, then process the other four
octants (4, 5, 6 and 7) remaining. This sequence is relatively easy, because the
symmetry of the octree node means that there will always be four billboards
behind N, and four in front, but this is not the most complicated scenario
that could arise.
67
Figure 4.18: Here a billboard N is stored at a node in the octree, which also
points to a child node containing billboards that are two subdivisions smaller
(i.e. one-quarter size). The large billboard again splits the smaller ones, with
some behind it and the rest in front. It is more complicated to determine where
in the sequence N should be handled for adding to the billboard list, if it fits in
the sequence at all.
Figure 4.18 presents a similar scenario to the previous illustration, except this
time there are two levels of subdivision between the billboard N and the
smaller billboards around it. If N splits these billboards, it will require the
traversal to backtrack up the tree and return down again to ensure the
billboard list is ordered correctly. Determining which of the smaller billboards
are in front and which are behind requires precise calculation of the viewing
angle, and will become correspondingly more complicated the deeper down
the tree we go from N. It may even be that N splits billboards that are not
together in the sequence (as shown in the figure where it is in front of g0 and
g2 and behind g1 and g3), creating ambiguity over where in the sequence it
should be handled.
The second problem is that the billboards used in rendering are oversized for
the voxels they represent (to improve the visual output as discussed in Section
4.2.6 ). This means that a given billboard is not contained within the space of
its voxel but also intrudes (slightly) into neighbouring voxels. As a result,
artefacts from Z-buffering may still occur even when the traversal algorithm
is sound at correctly depth-sorting the billboards.
The third problem is that the octree nodes are usually not viewed at a uniform
angle, and the traversal order may not actually hold everywhere. The octree
partitioning system covers the entire terrain area. The vehicle drives around
within the octree, and so the camera is usually within the octree. In the visible
area of the scene, at any one time there can be many octree nodes that are
being seen from different angles – some are above the camera and seen from
68
below; some are looked at from above; some to either side, etc. In this case,
no single traversal order would work perfectly for all the nodes – and
perfection is required to avoid the occurrence of artefacts.
As a result, it may be that different traversal orders are needed for nodes in
different locations on the viewable part of the screen. This would mean that
at least some of the nodes will need to be considered individually to
determine which traversal order holds for that specific viewing angle. This
would not be an intractable problem, but it is a concern nonetheless. For all
that effort, one may as well just implement a proven, iterative depth-sorting
algorithm to operate on the billboards as a post-process, and be done with it.
69
Chapter 5
Implementation and
Evaluation
In this chapter, the precise implementation of the models as applications is
described, and the results discussed. Although each of the different dust
representation and rendering systems created is covered, the focus is on the
last model as this is where the development was ultimately driving.
Section 5.1 gives images providing a preview and comparison of the four
models developed.
Section 5.2 outlines the development environment used for programming the
models, and the computer systems the applications were run on.
Section 5.3 describes the core application design that each dust model was
implemented on top of.
Sections 5.5 through 5.8 describe each of the models implemented in turn.
70
5.1 Preview of the Models
The four screenshots in Figure 5.1 provide a comparison of the four dust
models developed and described in the following sections.
Figure 5.1: These four images show the four different models implemented and
compared for dust cloud representation. From top: the billboards model, the
literal particle system model, the voxel grid based model and the octree space
partitioning model.
71
5.2 System Used
The majority of programming and testing work was performed using the
second system. This system was also used to collect the results data presented
in this chapter, unless otherwise noted. The first system was only used for
development on occasion, but was primarily included for testing the models
to provide an idea of how the performance scales on this comparatively
slightly older hardware.
The 3D graphics are rendered using the Direct3D library under DirectX 9.0.
DirectX is an API (for Application Programming Interface) that encompasses
a range of programming technologies to allow applications to be developed
that support different hardware makes and models, without requiring the
programmer to write their own code for each model of graphics card.
DirectX provides a suite made up of many components, providing
functionality for high-performance multimedia tasks including graphics,
sound, input, and networking.
72
resources, such as tutorials, available for both in publication and on the
Internet. OpenGL is usually seen as being easier to code, and it is also
hardware independent, allowing applications developed to be run on many
different platforms. On the other hand, Direct3D is more contemporary in its
specification and core architecture, through frequent releases of new versions
of the entire DirectX package. (Indeed, while the specific version 9.0a was
used in this project, revisions have since been issued so that at the time of
writing the latest version is 9.0c.) Direct3D is also being more widely used in
computer games produced for the Windows platform, so for these reasons it
was chosen for use in this project.
73
5.3 Base Application Design
Each model was developed in the context of being applied to simulating and
drawing the flow of a dust cloud created by a moving vehicle. To achieve this,
a base prototype application was developed that serves as the foundation.
Although it naturally evolved over the course of the project, it provides a
common core of functionality for each of the models to be implemented as
individual applications.
The base code was built up as a standalone application, shown in Figure 5.2.
This prototype provided a framework designed so that code specialised for
each new dust representation model could be dropped-in to operate on top of
this base. The application series was named Dusted. From this, a number of
variant applications were produced, each implementing a different model or
system of dust representation. These applications carried the ‘Dusted’ name
with an appended number indicating the different versions. In total, six
versions were produced for the final four dust models created, from Dusted1
(which was still an intermediary development version) through to Dusted5
and Dusted5b for the two versions of the octree space-partitioning system.
Figure 5.2: Screenshot of the ‘Dusted’ base application. Note the ‘Heads-Up
Display’ text readouts of the application state.
74
5.3.1 Program Design Considerations
3D World Scale
In the Dusted series of applications, the metric system was chosen so that the
unit scale was 1.0 unit = 1 metre. This is a familiar day-to-day scale that
provides a convenient and appropriate reference for building the scene and
modelling the real world. The car model is sized according to real-world
values to be roughly 5 units long and 1.8 units wide, and a terrain that is 1
kilometre square is created by using a side length of 1000 units. The use of the
metric system also makes implementation of equations of motion easy.
75
simulation environment, we expect to see the changing effects of the process
being simulated over time – in the case of this project, we want to see a dust
cloud that moves, expands and disperses. In both cases, we cannot code a
program to act only in response to user inputs and other events; it has some
elements that have to run autonomously.
76
the use of OOP, and DirectX is class-based [11]. The use of OOP also assists
in the clarity and organisation of code, and improves the ease of code re-use,
adaptation, and debugging.
To this end, application code is structured into classes, each with discrete
individual roles. These can be summarised as shown in Figure 5.4, and are
described under the following subheadings.
1 1
1 Main 1
CCamera CD3DFont
1 1
Follows
position
of 1 1
CCar CTerrain
1
n (Global)
CXFileMesh CTimer
D3DFuncs
Figure 5.4: Class diagram for the core Dusted application.
Main
The Main module is a code file that specifies the entry-point of execution, and
is essentially the controller of the application. It contains the ‘game loop’ that
specifies the update and rendering cycle, and receives user commands through
the message pump. It is also responsible for the creation, ownership, and
release of Direct3D interfaces that allow 3D rendering to be performed.
The Main module ‘owns’ a top-level interface to all the other classes present
in the application, and sends messages for the initialisation, update processing
and rendering calls to each. All the classes (including each of the dust
simulation models developed) define a similar interface for initialisation,
update, and rendering calls, so that adding a new component to the program
is a matter of declaring calls to these functions in standard places of the Main
file. Although a little specialisation in these function calls is usually required
from one class to another, the commonality of interfaces keeps things
reasonably straightforward within the Main code file.
77
lot of initialisation code, most of which can be organised into a standard
procedure, it is preferable to place this into global functions in a separate file,
and then call these functions from Main. This prevents the Main code file
from becoming cluttered with the large amount of code required to set up
DirectX, and allows the set-up code to be readily re-used between projects.
D3DFuncs also provides a global function for translation and output of
Direct3D error codes to assist with development and debugging, which is
referenced by almost every class of the program that must deal with
Direct3D. The D3DFuncs code file itself is taken from the 32bits.co.uk
DirectX programming tutorials [9], and used here with little modification.
3. Enter the game loop that defines the update and rendering procedure.
This repeatedly performs the following sequence:
a. Check for messages in the Windows message queue. If a
message is found, dispatch to message handler for processing
then repeat this step (a ‘quit’ message will cause the game loop
to halt). If there are no messages, then proceed to b.
b. Perform update calls on ‘updateable’ class objects active
within the world. This will include passing user inputs to the
‘car’ and ‘camera’ objects, and advancing the dust cloud
simulation.
c. Enter the rendering stage; performing render calls on
‘drawable’ class objects, followed by post-rendering of text
labels.
d. Return to a.
Main also defines the application’s message loop for handling (or ignoring)
Windows messages. This has been used for keyboard input handling for the
car, camera and other class objects. For most classes, the processing for a key
event directly calls functions of the class object, asynchronous to the game
loop. In the case of the car, it must respond to keystrokes in real-time:
accelerating for as long as the key is held down, and so on. In this case, the
key events are ‘captured’ into variables that indicate the key’s up/down state,
to be passed to the car class as parameters in the update function call. This is
traditionally the sort of use that DirectInput would be implemented for, as it
is designed for reading the instantaneous state of input devices; as opposed to
78
the way that Windows messages signal a key press or release. However, in this
case the application is simple enough that we can satisfactorily achieve the
desired result just by using the message pump in this way.
Class CXFileMesh
This class is a wrapper to the Direct3D extensions utility library for DirectX
(.X) files. An .X file contains the mesh geometry and effects data for a 3D
model, and supplies a convenient pre-defined means to load and use 3D
model files in Direct3D. This class wraps the .X file methods with useful
functionality for loading of materials and texture files for convenience, and
also performs logical rendering of the model. It is based on tutorial code from
32bits.co.uk [9], which has been encapsulated into a class.
Class CCar
The car class represents the user-controlled vehicle, which can be ‘driven’
around the scene – the action of which we are interested in as the source of
dust clouds. Although it represents the user’s interaction with the simulation,
the car is really only a prop in relation to what the simulation does.
The vehicle is defined conceptually by its current position, speed, and heading
values. It acts according to a simplified model to allow it to increase and
decrease its forward motion, and turn left and right, with a scaling element
added for interest to modify the behaviour with speed (reducing the rates of
acceleration, deceleration and turning as speed increases). The update process
consists of receiving steering and acceleration/deceleration inputs, which are
used to modify its current heading and speed, and then calculating location
from the speed and heading. Its performance is bounded by parameters
stored in and read from a text file, which define its top speed,
acceleration/deceleration rates, and angular turn rate.
The text file also declares other information, including the model files to use
and the size and relative positioning of wheels. The class performs the
rendering task of drawing a representation of a vehicle to the screen, through
the use of instances of the CXFileMesh class, combined with the car class’
own positional and animating logic.
The car class also defines accessor functions for providing position, velocity,
and other information to external code. Of particular interest are the
functions that provide the world-locations of each of the four wheels, which
are used by the dust simulation models for determining the points producing
clouds.
79
Class CTerrain
Class CCamera
The camera class represents the user’s point of view. The viewpoint can be
rotated and zoomed at the user command to provide a variety of angles to
viewing the scene. It encapsulates a viewer (eye-pos) location vector, and view
target (look-at) location vector, and the logic necessary to input these into
Direct3D as the scene view transform. The eye-pos and look-at vectors can
also be obtained from the class, of example if another class needs to perform
depth-sorting. Keyboard commands (generally) allow the camera to be
orbited around the focal point, and moved/zoomed closer or farther away.
Class CTimer
The timer class encapsulates time-keeping logic used to determine the time
elapsed between frames (and from this, the frame rate). This timing system is
used by a number of other objects in the simulation, particularly the car class
and dust simulation systems, for calculating smooth animations and
movement over time. The class was originally written by Luke McConaghey
[11] and is slightly modified for use here.
80
Class CD3DFont
This class encapsulates logic for drawing text onto a Direct3D rendering
surface. Since Direct3D is designed for 3D graphics, it is lacking in inbuilt 2D
text facilities; this class provides a neat package that allows any installed
Windows font to be used to draw text, in any colour, onto the rendering
surface. The class is one of many that can be generated in a ‘Common Files
Framework’ project by the provided DirectX 9 AppWizard for Visual C++.
The CD3Dfont class is included into the Dusted application and used as-is. It
is used here to write information labels and details about the application
processes to the screen, including frame rate and simulation system
parameters, allowing instantaneous program state to be easily read off the
screen.
MemLeak
Parameters Files
The car data are read out of a text file, as described previously. This file
specifies:
• A name for the vehicle (unused in the application).
• The model files to use for the vehicle body, left-side wheels, and
right-side wheels.
• The relative coordinates of each of the four wheels in relation to the
body, and the wheel radius.
• Values for the top speed, and rate of acceleration, deceleration, and
turn rate. These are not real-world values, but chosen to give the
vehicle appropriate handling to play with.
The use of a text file to store data like this allows some aspects of the
application to be easily changed without having to recompile code. In this
case the vehicle appearance and handling can easily be adjusted by changing
the filenames and performance values stored in the text file (although once in
81
place, the same settings were kept here for all the applications developed).
The intent was to offload some other application settings (such as screen
resolution or terrain size) to text files to avoid having such things hard-coded,
but this was not realised in the course of the project.
Model Files
The model used for the vehicle body is a replica of a Ford AU-II series
Falcon XR8 utility (Figure 5.5). This model was scratch-built a couple of years
ago by the author as a hobby project making add-on vehicles for a computer
game, and was converted to .X file format for quick and easy reuse in the
Dusted applications. Separate models are used for the wheels, to enable the
wheels to be animated and rotate with the speed of the vehicle. The body
model is composed of 1789 triangles (1415 vertices), texture-mapped with
three 256x256-pixel texture files. Each wheel is 306 triangles (233 vertices),
mapped to two texture files. As discussed, the vehicle is only a prop in
relation to the whole of the application, but it looks nice nonetheless.
Texture Files
The vehicle model uses five 256-colour texture files, and as with the model,
these were created by the author.
82
Racer by Ruud Van Gaal (http://www.racer.nl); specifically from the bundled
Carlswood racetrack created by Claes Wikdahl. The texture file originally
represented sand; it was recoloured to a more earthy tone, and is tiled over
the polygons of the terrain surface to create a more realistic look.
Figure 5.6: Terrain dirt texture file. (Original image by Claes Wikdahl.)
Two of the dust representation models also use textures for rendering; these
are described under the relevant models.
• Speed, or how fast the application can run while performing the
computations to run the model simulation and draw the results;
83
application to be able to perform its computations, render and display the
frame at least 25 times per second, to sustain persistence of vision.
Benchmarks
The core Dusted application was found to have a maximum frame rate of 518
fps. However, indicative of the effect of rendering load just described, this
was found to vary greatly according to what is on-screen. While the 518 score
was recorded from behind the vehicle, rotating the camera around the side
brings more polygons into play, and the fps dropped to 450. Zooming the
camera out also reduces the frame rate as more textured polygons of the
ground surface come into sight and need to be rendered. This illustrates the
importance of the viewpoint looking at the scene.
Figure 5.7 shows two of the camera views used to test the application. The
first is the second of the two chase views pre-programmed into the camera
class; it is named the ‘far’ chase view because it is elevated and moved back.
This camera view eliminates most of the cloud from appearing on-screen,
which may change the performance values reported. The second view is
intended to create an ‘average’ rendering load. The camera is oriented around
to the side of the vehicle and zoomed out. The vehicle is then driven in a
circle; most of the dust cloud will then appear visible on the screen and the
rendering load ‘should’ remain reasonably constant.
84
Figure 5.7: Screenshots showing the camera views used; ‘far’ chase view (left)
and side-on and zoomed out.
85
5.5 Billboards-Based Model
The billboard model was the first developed, implementing the techniques
currently used widely in games and other applications for representing clouds
of dust or smoke. It was created as a reference for the future models to be
developed. The model was actually developed across two applications; starting
as the nascent Dusted1 application to get the groundwork of a billboard
particle system interacting with the moving vehicle. This was followed by an
almost complete rewrite as Dusted2 to implement refinements such as depth-
sorting.
Figure 5.8: Screenshot of the Dusted2 application, employing the billboard dust
model.
86
5.5.1 Class Model
The model is based on a simple particle system, where the particles are used
to define the positions of the billboards. The particle system was implemented
across two classes – an emitter class, which runs an actual particle system
associated with an emitter object, and a command class that coordinates
emitters and handles the rendering as billboards. Splitting the particle system
across classes like this separates the particle behaviour logic from the
billboard rendering, although with a system this simple it provided no real
advantage and could all have been written into one class.
Main
1
Perform depth-sort for CBillboardParticleSystem
CCamera
Class CBillboardParticleEmitter
87
means that no matter how many requests to spawn a new particle the emitter
is given, it will never spawn particles at a rate faster than one every 0.05
seconds, or 20 particles per second.
Class CBillboardParticleSystem
This class can control any number of emitter class objects from zero up,
although obviously it requires at least one to actually do anything. In this
application, four emitters are used, one for each wheel. The
CBillboardParticleSystem class coordinates the emitters, updating each one’s
position to match the vehicle’s wheels and passing on requests to create
particles while the vehicle is travelling forwards.
88
Figure 5.10: This shows the components of the texture used in the billboard
dust model. On the left is the texture image RGB channel, that defines the
colour, and the Alpha channel that defines opacity (where black is fully
transparent and white is fully opaque). These are combined to give the output
‘puff’ texture on the right, as it appears applied to the billboards.
This means that the world transform is being set for each individual billboard
to be rendered, and the billboards sent to be drawn one at a time. This will be
a time-consuming procedure if there are a large number of billboards to
render, slowing the performance of the application. An improvement is to
prepare a list (vertex buffer) of all the polygons (billboards) to be rendered,
pre-transformed to the required orientation, sizes and positions. Then during
the rendering, the world matrix is set once (and usually set to perform no
transformations) and the entire list of polygons is passed in to be rendered all
89
in one go. This approach was not implemented here for the billboard dust
model, but is used in all the following models.
Figure 5.11: Two screenshots from the Dusted2 application, showing the effect
with the car travelling at different speeds. The results are consistent with what
can be observed in games and models employing this type of technique; the
model exhibits similar behaviour and visual flaws.
90
When rendered at the particle locations, the arrangement and overlapping of
the textured billboards (generally) gives the impression of a single voluminous
cloud, and the movement of the particles makes the individual ‘puff’ elements
drift and disperse over time. The cloud moves and animates more-or-less
appropriately, albeit not entirely convincingly. The layering of the puffball
texture used on the billboards goes some way to resembling the self-similar
detail in a real dust cloud.
The model exhibits the same sorts of flaws inherent with most
implementations of billboard cloud effects, which are apparent in the second
image of Figure 5.11. As the vehicle increases in speed, the individual
billboard puffs start to become strung out over greater and greater distance.
This starts to make them become very obvious as individual puffs, and at high
car speed the appearance of a single voluminous cloud breaks down. The
image also strongly demonstrates the occlusion effect with billboards
intersecting the ground surface and other objects, to be partially blocked out
by the Z-buffer. The straight line of the intersection makes the puffs appear
very two-dimensional.
For starters, only one texture was used for of all the billboards. This leads to
an appearance of sameness to the cloud, and a lack of dynamism. A more
polished version could employ multiple different shapes and colours of
textures for variance, as well as having a number of texture ‘frames’ to be
swapped onto the billboard for animation of each puff expanding and
dispersing, gently fading away over time. As they are, each billboard has a very
static appearance, and hangs in the air for some time before abruptly
disappearing when its corresponding particle’s lifespan expires.
Finally, several other parameters of the model could be tweaked, such as the
movement and expanding behaviours of the billboards. The non-variable rate
at which new particles are created is also probably more than is really
necessary at most times, though as illustrated above, at high car speeds even
this rate of particles is not fast enough to plug the gaps.
As it is, however, the model serves its purpose and is consistent with the
effect seen in professional implementations (eg. in games) both in terms of
how it can be seen to behave and the drawbacks inherent with the method.
91
5.5.4 Performance Results
In terms of computational load, the billboard dust system is very lightweight.
The factor that has the biggest effect on the frame rate of the application is
the rendering process itself, indicating that the model is fast to compute, and
the bottleneck is occurring on the video card.
Because the rate at which new particles are created and removed in the system
is constant, as long as the vehicle is in motion (whether fast or slow) and
creating dust, the system will always reach a steady maximum number of
particles. This maximum number of particles is just over 1000, combined for
all four emitters.
450
425
Frames per Second
400
375
350
325
300
275
250
0 200 400 600 800 1000 1200
Number of Particles Rendered as Billboards
Figure 5.12: Graph of the performance of the billboard dust model, with and
without the quick-cull optimisation.
In the idle situation (i.e. the vehicle stationary, and no active dust) the
application settles to a steady 430-440 fps. As the vehicle is driven and dust
created into the system, the frame rate barely drops 10%, all the way up to the
92
maximum number of particles. The initial dip in frame rate shown on the
graph can be attributed to a large number of billboards appearing in a small
space as the vehicle begins moving. Once up to speed, a large amount of
ground is being covered between the creation of each billboard, which
reduces the rendering load. Swinging the camera around to look backwards
(and bring the entire cloud within sight), the fps drops between 10 and 50%
to an observed low around 200 fps, varying drastically with the distance of the
billboards from the camera. Therefore, the performance limiter of the
application clearly isn’t in the computations required for updating the model
(that is, the particle system), but from rendering the textured billboards.
Recall that this model implements a quick culling algorithm, that removes
particles that are behind the camera from the processes for depth-sorting and
rendering as billboards. With the camera in the ‘chase’ view, a large majority
of the particles will be behind the camera and therefore will be culled. In this
situation, updating the model consists of only updating the particle system,
and has minimal effect on the load for rendering. This in turn means there is
little effect on the performance of the application as a whole, with the frame
rate remaining quite constant. When the quick cull is disabled, the model
shows more natural linear variance in frame rate. With the maximum number
of particles, it drops around 20% to 350 fps when most of the billboard cloud
out of sight.
Also recall that the rendering process is performed by iterating through the
list of particles, setting the world transformation and drawing the polygons
for each billboard individually. This is not the fastest way to render a
collection of billboards, and so when a number of billboards are in view, they
cause that much bigger a performance hit – practically halving the frame rate.
93
5.6 Particles-Based Model
This model, like the last, was also created as a reference of the current ‘visible’
techniques (meaning those that can be seen in commercial applications or – as
in this case – found in literature). In this case it is the ‘literal’ particle system,
where the dust cloud is not just simulated by, but also rendered as, a storm of
very fine particles as inspired by [2]. In the series of applications developed,
this one is Dusted3 (Figure 5.13).
Figure 5.13: Screenshot of the Dusted3 application, employing the particle dust
model.
94
Main
Figure 5.14: Class concept diagram of the literal particle dust model.
Class CWorld
The world class was intended to be analogous to the physical world, handling
all the things ‘in’ it. For this application it was naturally heavily geared toward
running the dust cloud particle system.
The particle system used here was much more finely grained and finely
detailed than that used in the billboard model, although also more specialised.
The class encapsulates the logic of both the emitters and a total particle
system in the one class file. As detailed in an earlier chapter, the particle
system operates as follows:
1. While the vehicle moves, new particles are created at the emitters
located at each wheel. The number of particles created at an emitter is
controlled by a density parameter. This value defines the maximum
number of particles that the system (i.e. all four emitters) produce per
second at a certain speed; in the implementation this was set to 1000
particles per second, at about 60km/h. The actual number of particles
created when the vehicle is travelling less than 60km/h is scaled
linearly according to the vehicle speed, dropping to zero when the
vehicle is stationary. At speeds above 60km/h, the system produces
no more than 1000 particles per second. The new particles are created
in a cyclic iteration between the emitters, rather than spawning all the
particles from a given emitter at once, to improve the consistency of
the particle cloud and reduce the occurrence of Z-buffering artefacts.
95
decreased, to make the particle fade away over time. As the particles
are processed, a list (vertex buffer) is filled with the data for rendering
a coloured dot for each particle.
Figure 5.15: These screenshots show the particle dust system in action. In the
bottom picture, the vehicle is crossing through the particle cloud under
acceleration, demonstrating how the drifting particles have their motion
disturbed by the airflow modelling.
96
The particle system in use produces an attractive result, although not entirely
convincing. Mostly, it lacks volume. Close behind the vehicle it does not fill
the space realistically, although this is partly the result of the simplified model.
It produces a very sharp result however, and as the cloud of particles expands
it fills a more appropriate volume. The way the particles gradually slow down
as they drift, the random variance to colour and lifespan and the gentle fading
out of old particles all works well.
Another factor in the appearance of the particle cloud is that it does not scale
with range: it will appear different as the viewing distance increases or
decreases, as shown in Figure 5.16. When the viewpoint is reasonably close,
the volume of the cloud takes up a large space on the screen. The particles,
being drawn as tiny dots, are spread out over this wide area; the final result
looks very disperse, and does not suggest the volume of a cloud. As the
viewpoint recedes further away, the screen space that the cloud occupies
shrinks, so that the particle dots are drawn into a smaller area. Eventually the
proximity of the dots begins to suggest a cloud shape again. As the viewpoint
continues to move away, the particles as rendered converge into a smaller and
smaller area and more overdraw occurs, resulting in the cloud looking denser.
97
Figure 5.16: These screenshots show the effect of different viewing distance on
the particle cloud. From moderately far away (top image), most of the particles
are drawn into a small space on the screen, and the shape of a cloud can be
seen. Close up (bottom image), the particles are spread across a large area of the
screen and appear too disperse to form a recognisable cloud.
This model was tested using the same ‘far’ chase camera view (Figure 5.7) as
before. Results were first collected by driving around in this forward-looking
view, with most of the dust cloud out of sight. These results were then
compared with values obtained with the camera oriented around in front of
the car looking backwards, putting the entirety of the cloud onto the screen.
98
Figure 5.17: Graph of application performance (FPS) versus the number of
particles in the system. The processing cost of the model scales close to linearly
as the particle count increases.
At idle with no particles in the system, the application runs at a slightly lower
frame rate as compared to the core program and the billboard model; 416 fps
with the camera in the far chase position. As the vehicle was driven around,
the frame rate reading was read off at frequent intervals and used to plot a
graph of performance versus number of particles in the system (Figure 5.17).
At the point where the particle system had reached the capacity of between
35,000 and 36,000 particles, the frame rate was stable at around 140 fps. The
graph shows that the line of the values creates a curve, dropping sharply to
begin with before tapering off to a more linear rate near the maximum
number of particles.
99
of the application considerably, and it is in this guise that the model has been
presented in this thesis. Although no frame rate data is available from the
earlier version for comparison, the equality in performance of the model now
indicates that the figures here are a good indication of the scaling in
computational cost.
100
5.7 Voxels-Based Model
This model was the first of a different approach to the dust modelling. It
discards the particle systems and flat billboards, to represent the dust cloud
volumetrically. This was to be achieved by using a three-dimensional grid of
cubic voxels that would cover the entire terrain to a certain height. The voxels
are each used to represent the density of dust occupying that volume at that
position in space. Dust simulation occurs by gaseous density propagating
through the grid, loosely based on ([5],[12]).
101
Main
Class CWorld
Each voxel stores an opacity value to represent the density of airborne dust
within its volume at that location in space. The dust cloud is propagated into,
and spreads throughout, the grid by the following process:
1. Initially, all voxels are empty: their density (or opacity) values are set
to 0 (fully transparent).
3. All the other voxels in the system are processed. To avoid having to
laboriously search through the entire grid, a lookup list of ‘active’
voxels is kept. A voxel is added to the ‘active’ list when its opacity
value exceeds a certain threshold: this was set to 5 in the
implementation. Each voxel in the active list has the following
processes carried out:
a. The voxel will first disperse, or ‘bleed’, density into its surrounds,
to represent the dispersion of the dust cloud. This is performed
by the current voxel increasing the density value of the
102
neighbouring voxels (to the front, behind, above, below, and
either side) by a value equal to its own density value multiplied by
a ‘dispersing’ factor. This may cause the neighbouring voxels to
increase their density value above the threshold, meaning they will
be added to the ‘active’ list and will be processed in this manner
and influence their neighbours on subsequent updates.
b. To complete the dispersion, the current voxel has its density value
decreased by an amount equal to its current density multiplied by
a ‘fade’ factor. This may cause the current voxel to reduce its
density value below the threshold, meaning it will be removed
from the ‘active’ list for the next update.
For simplicity at the initial development stage, the voxels were each rendered
as a square, untextured billboard. The billboards were positioned on the
voxel’s centre, and their opacity set according to the density value at the voxel.
To avoid having to perform multiple passes, the vertex list for the billboards
was built up during the processing cycle of active voxels, so that each
billboard was constructed at the same time a voxel was processed. As depth-
sorting of the billboards was not implemented, Z-buffering functionality is
disabled for rendering.
Storage
The initial plan was to naively cover the entire 1 sq. km space of the terrain
with cubic voxels of dimensions around 0.25 or 0.1 of a metre, to a height of
five or ten metres. Each voxel would also have a number of attributes besides
its density (opacity) value, such as pointers to its neighbours for rapid
traversal from voxel to voxel through the grid. It was quickly found however
that this would require a huge amount of memory.
As the size of fineness of the grid increases, the memory required to store it
grows at an exponential rate. For example, consider a voxel grid measuring
1km × 1km × 5m, composed of voxels measuring 0.25m. Assume that the
voxels only store a 32-bit integer for the density value. The amount of space
that would be required to store this grid in memory 1,280,000,000 bytes, or
around 1.2GB! This is of course completely unworkable.
103
To compromise, in the implementation, the grid was restricted to 200m ×
200m × 4m, and the size of the voxel cubes was set to relatively coarse 0.5m.
Each voxel stores only a density value (32-bit integer); the other attributes
were dropped from the implementation. The space required for this grid is an
altogether more sane 5,120,000 bytes (5MB); although, the restricted grid size
means that the dust simulation will only take place in a 200 sq. metre sub-area
of the drivable space.
Ultimately, this space issue was the impetus that sparked the subsequent dust
models employing an octree space partitioning system.
The mechanics for making the dust cloud spread through the grid of voxels
and eventually disperse was somewhat tenuous. Depending on its spatial
position in the grid, each voxel can give input to up to six neighbours, as well
as receive input from those same six. This obviously has to be controlled if
the entire simulation is not to spiral out of all proportion.
The rate at which a voxel reduces its density value, and the rate at which it
‘gives’ input to neighbouring voxels, are each controlled by scaling factors.
The ‘dispersion’ factor determines the rate at which a given voxel increases
the density value of its neighbours; and the ‘fade’ factor controls the rate at
which the voxel’s own density is reduced. For a believable dust cloud, we
want it to spread through the grid reasonably rapidly, and hang around a while
before gently fading away. This implies a reasonably fast dispersion rate, with
a gradual fade rate. We also want the system to remain stable. This means that
there are relative limits to the values that can be used for the dispersion and
fade factors.
For a stable system, the relationship between the two factors is that the fade
factor must be at least six times the dispersion factor. Since any given voxel can give
inputs to up to six neighbours (and receive up to six inputs itself), for
conservation of matter it should lose at least six times the amount given to
each neighbour. Otherwise, the system as a whole will be generating more
density than it loses, and unusual things will happen! With a fade rate only
slightly more than six times the dispersion, the system will always remain
stable, and ultimately return to an empty state after the vehicle stops.
104
Figure 5.20: Instability in the voxel grid due to dispersion/fade rate mismatches,
causing ‘bubbles’ or ‘pockets’ of density to take on lives of their own. (Image
enhanced for contrast.)
In the implementation, the final values settled on for dispersion and fade rates
were 0.5 and 3.01 respectively. Some voxels do not have six neighbours to
receive inputs from – those on the bottom of the grid where the density
propagation starts, for example – and likewise those around the outside of the
cloud volume will not receive six inputs. It is actually possible that the fade
factor can be equal to or slightly less than six times the dispersion (eg. 3.0 or
2.9), and the system will still return to empty. This tends to increase the
incidence of unstable behaviour though, such as rogue ‘pockets’ of density
that bubble and race through the grid with a life of their own, or reach some
equilibrium where they become semi-permanent blobs (Figure 5.20). If the
fade rate is much less than six times the dispersion, then the grid will become
saturated – not very realistic dust behaviour at all! Even with the fade rate at
the chosen 3.01 however, these crazy density bubbles still occur, though they
are usually faint and short-lived.
105
Figure 5.21: Screenshot showing the voxel-based dust model in action.
Each voxel is rendered as a square billboard; the billboards are not textured
but make use of diffuse polygon colour and alpha blending to create a dust
cloud appearance, though they look very obviously square. As depth-sorting
of the billboards was never implemented, to avoid the appearance of artefacts
the Z-buffer is disabled during rendering of the billboards, which leads to
overdraw of the billboards on top of the car and other scene objects.
The overall results are moderately successful. The voxels create a voluminous
shape, and mostly avoid the appearance of gaps that occur in the previous
billboard and particle system models. The ‘cloud’ expands and fades
appropriately, though as previously described it is hard to tune the behaviour
to make it last longer before fading away. The grid is very coarse so the
straight lines and edges of the billboards dominate; the colour of the cloud
also looks flat and lacks realistic detail. Finally, it is also subject to weird
behaviour when the system becomes unbalanced.
106
Voxel Model Performance
500
450
350
300
250
200
150
100
50
0
0 500 1000 1500 2000 2500 3000
Number of Active Voxels
Figure 5.22: The recorded performance of the voxel dust model drops off
sharply as the number of voxels active in the simulation increases. Shown on
the graph is an exponential trendline for comparison.
Figure 5.22 shows a graph of the performance of the voxel grid model as the
number of active voxels increases. From the starting point of 436 fps, the
frame rate drops rapidly as the number of voxels increases. For reference,
simulation of the dust cloud even when the vehicle is travelling quite slow will
easily require 1200+ active voxels; at 60km/h, between 1500 and 1700 voxels
will be active in the system, at which stage the frame rate has fallen to 60 fps.
The model is clearly subject to a prohibitive level of complexity for high
numbers of voxels, and because of this the particle system was restored as the
model for simulation in the successor octree-based applications.
107
5.8 Octree Space-Division Model
This model, employing an octree space-division method, was developed to
tackle the problem of large memory requirement encountered using the
‘dumb’ voxel grid. An octree represents a very memory-efficient means of
subdividing space into cubic volumes, when most of our volume space
remains empty. This model also returned to the use of a particle system for
describing the movement and behaviour of the dust cloud, utilising the
octree’s voxel space to represent the volume to be drawn.
108
Main
CCar CTimer
Update
particle- Move
system particles
emitter over time
positions
1
CDustController
1 1
1 1
CDynamicOctree Create structure CParticleSystem
Figure 5.24: Class concept diagram of the volumetric dust model employing a
particle system and octree space partitioning.
Class CParticleSystem
The particles created at the emitters are stored in one array for the entire
system. The class defines an accessor method that returns an array of pointers
to the particles in its array. This allows the octree class to interrogate the
particles for construction of the volumetric representation. For proof-of-
concept, the class also includes functionality that can be toggled on/off for
rendering the particles themselves as dots on the screen.
109
Class CDynamicOctree
1. The octree class receives a list of the particles from the particle system
class, via the controller class.
2. The class sets the tree traversal order based on the current camera
heading (this is a remainder from the attempted depth-sorting by
traversal algorithm, that has no particular impact on the system as it
now stands). It then partitions space for the particles and constructs
its tree representation according to one of the construction algorithms
(recursive or search-principle) outlined.
The class also includes the facility for rendering a representation of the octree
structure itself, as a cubic wire-frame with functionality that can be toggled on
or off.
110
Class CDustController
This class, as its name suggests, is responsible for overall control of the dust
system employed by this application. It owns and directs the octree and the
particle system classes below it. It is also responsible for the dust
representation, storing the texture file and billboard list that are used for
rendering. The texture file and the way it is used with the billboards are
shown in Figure 5.25.
Figure 5.25: The texture used with the billboards in this model defines only any
alpha-channel (left) for transparency and translucency. As with the previous
voxel-based model, the billboard polygons use a set diffuse colour (centre). This
is combined with the alpha-channel from the texture to create the final
billboard appearance of a brown circle with transparent edges.
2. From the particle system, it obtains a pointer list to the particles and
transfers this to the octree class. The octree class uses this for
constructing its volumetric representation of the cloud. The controller
class also provides the octree class with a vertex buffer to be filled
with data for rendering the billboards. After the octree has done its
thing, the vertex buffer owned by the controller class contains the
billboards to be rendered.
3. When the rendering call occurs, the controller class renders its vertex
buffer filled with billboards, with the texture stored.
The controller class also facilitates the various system toggles written into the
application. Features that can be turned on and off are:
• Rendering a representation of the particles by the particle system
class;
111
• Rendering a representation of the space partitioning by the octree
class;
• Depth-sorting of the billboards by the algorithms implemented in the
octree class;
• Z-buffering of the billboards when rendered by this class; and
• Rendering the billboards with texture, also handled by this class.
This recursion process requires memory to store the previous data set each
time it enters a new recursive processing loop (with new data), so that when
the nested recursion process completes, the state can be recalled for the
previous process to continue. This data is stored on a stack (called a ‘last-in
first-out’, or LIFO, queue, since the last element to be stored will be the first
retrieved).
112
maximum depth of the octree is 12, so in the worst-case scenario there will be
11 sets of data stored when the recursion process is at the bottommost level.
Initially, the particle system class provided an array containing copies of its
particles. The construction process would create a further eight arrays for the
eight partitions of space at a node in the octree. Each particle was assigned to
a partition, by copying it from the ‘master’ array into the array corresponding
to that partition. During recursion to process a partition, the old ‘master’ array
is stored into memory and that partition’s array becomes a new ‘master’. This
process means that we are storing duplicates of the particles in memory as we
work down the recursion.
To attempt to reduce the amount of waste, the system was coded to use
dynamically allocated arrays for the partitions. With dynamic allocation, the
programmer writing the code specifies when memory is allocated and de-
allocated, and how much. This allows array that are sized exactly according to
the number of particles assigned to that partition, ensuring we don’t waste
space for empty array elements.
113
As a solution to this, the particle system class was modified so that it provides
an array of pointers to its particles, and the octree class now operates on arrays
of pointers. Each pointer value is only 4 bytes in size, compared the 32 bytes
needed for the multiple values stored in every particles. This way, we can use
statically allocated arrays that are large enough to take all the particles, but the
total amount of memory required for the array is smaller. This will not
exhaust the capacity of the stack, so the application will not fail while
recursively constructing the octree.
The only problem with this is that it is still allocating memory for arrays with a
large number of elements, where most of those elements can be empty.
Though it is freed when the process finishes, this memory is still being
wasted. So the development of the search-principle algorithm for constructing
the octree – which does not need to store copies of particles and arrays, and
waste memory doing so – was partially a pursuit of elegance in the
implementation, to provide an alternative that is not so wasteful in operation.
114
Figure 5.27: This screenshot shows a representation of a typical space
partitioning defined by the octree. The partitions are represented in the image as
a wireframe of cubes within cubes. Those cubes that enclose billboards
correspond to the voxels describing the cloud.
Overall, the visual appearance of the cloud is good, but still falls short of a
truly realistic representation. Funnily enough, it generally looks better as a still
image, than when it is in motion. The use of voxels creates a good (truly
volumetric) representation of a cloud, and limits the appearance of gaps that
occurred in the billboard and particle models. The appearance created by the
textured billboards is plain but believable, perhaps partly because the texture
used is deliberately vague.
The model does not animate well, however. The switching between voxels of
different sizes works well for representing the expanding volume of the cloud.
Because the voxels are at discrete locations in the world space, however, there
tends to be a lot of ‘popping’ of billboards jumping from one cell to another,
instead of the smooth motion we would see in real life. This is most
noticeable with the larger voxels – as is to be expected. Fortunately these are
usually at the end of the cloud ‘train’, farthest from the vehicle, so their
jerking motion is usually no more distracting than the little jumps of the small
voxels immediately behind the vehicle. The fact remains however, that the
model is lacking in this respect for interactive applications.
115
Depth-Sorting
Figure 5.28: The appearance of the cloud when using the (failed) tree traversal
depth-sorting algorithm. Artefacts due to Z-buffering are quite bad, although
the algorithm does negate the effect of varying the camera angle to a degree.
Figure 5.28 shows a screenshot of a version of the model using the early
traversal-based depth-sorting algorithm. Artefacts caused by Z-buffering are
rampant, although the algorithm does help to negate the effects of changing
the camera angle. If the order of traversal (and rendering) was fixed, then the
billboard cloud will appear different as the camera is moved around – there
will be one angle where the impact of Z-buffering is minimised (if not
completely negated), and one angle where it is maximised such that artefacts
practically obscure everything. With the changeable traversal order in place,
the cloud at least looks equally as bad from any angle.
116
Figure 5.29: The appearance of the cloud when using the tried-and-tested quick-
sort depth-sorting algorithm, implemented in the Dusted5 application. The
billboards are properly sorted, and the cloud exhibits zero occurrences of
artefacts.
Figure 5.30: The appearance of the dust cloud when using the slightly flawed
search-and-insert depth-sorting algorithm, implemented in the Dusted5b
application. The result is not perfect, with some slight artefacts still occurring.
Figure 5.29 shows the cloud rendering from the Dusted5 application,
employing the quick-sort algorithm for depth-sorting. This model works
perfectly (as required), with absolutely no artefacts visible.
117
Figure 5.30 similarly shows a screenshot from the Dusted5b application,
which uses a binary search algorithm to identify how the billboards should be
inserted into the list for a depth-sorted order. Though the algorithm seems to
work, there is some slight flaw in it that still causes the occasional appearance
of artefacts in the cloud. Unfortunately, anything less than perfection will
result in artefacts occurring. A deeper review should pick up where things are
going wrong and correct it, but was not possible in the time frame of the
project.
Figure 5.31: As the cloud grows in length, more voxels and therefore more
partitions are needed to represent it; this has the effect of more nodes being
used in the octree. Note that the rest of the empty space is not partitioned, so
memory is not wasted storing empty voxels.
The size of the cloud, and hence the number of nodes in the representative
octree, is dependent on the following:
118
Where the saturation of particles is already high, most or all of the
voxels in that space will already be active, so adding more particles
cannot increase the number of voxels already in use.
800
700
600
Number of Nodes
500
400
300
200
100
0
0 20 40 60 80 100 120 140 160 180 200
Car Speed
Figure 5.32: The average number of nodes needed to represent a dust cloud
increases as the vehicle speed. The number of nodes representing voxels (and
are hence rendered as billboards) tends to be roughly half of the total nodes in
the octree.
Figure 5.32 shows how the node count of the octree changes relative to the
speed of the vehicle. A subset of the total number of nodes in the tree
represents the voxels, which are rendered as billboards. The number of
voxels, and ergo billboards to be rendered, is shown to be roughly half of the
total number of nodes in the octree.
119
For evaluating the performance of the model, the camera was set to face side-
on to the vehicle (Figure 5.7) and the vehicle driven in the circle. This keeps
most of the dust cloud in view, and is intended to replicate a typical operating
and rendering load. The graph of Figure 5.32 presented tallies of the number
of nodes used by the octree to represent clouds of different sizes, which was
achieved with the vehicle travelling at speeds of 0, 20, 60, 100, 140 and 180
km/h. These speeds were used in the performance testing as frames of
reference – that is, the vehicle was driven in a circle at 20km/h and the
number of nodes and frame rate recorded, the speed increased to 60km/h
and the values recorded, and so forth.
400
350
300
Frames per Second
250
200
150
100
50
0
0 100 200 300 400 500 600 700 800
Number of Octree Nodes
The graph of Figure 5.33 shows the results of this testing for both versions of
the application. The frame rates achieved for each model when the billboards
were rendered without the texture are also shown for comparison. The
markers on the lines of the chart correspond to the reference frames of 0, 20,
60, 100, 140 and 180 km/h vehicle speed, as used in the previous graph for
the node counts. The Dusted5 application, employing the recursive octree
construction process, proves to be slightly faster than the Dusted5b
application’s search-principle approach with separate traversal process.
120
The graph shows that, once again, the rendering has probably the greatest
impact on the speed at which the model runs. As the vehicle increases in
speed, the dust cloud becomes longer and requires more billboards to be
rendered. The turning circle of the car also increases, however, which means
eventually the billboards start disappearing off the edges of the screen, and are
also further away from the camera. These factors reduce the rendering load,
so the frame rate begins to climb again even as the octree representation is
using more and more nodes. The application was also tested with the
billboard texture disabled; as can be seen by the dashed lines in the graph, this
results in a further increase to the frame rate. These factors show that the
computational cost of constructing the octree and traversing it to prepare the
list of billboards is acceptably low overall, and the limiting factor is again the
graphics capability of the computer.
5.9 Discussion
Billboard systems are a popular method for displaying complex phenomena
such as these dust clouds because they are easy to implement and impose little
computational overhead. The use of an underlying particle system gives the
model good freedom of movement, and the billboard rendering technique
allows a small number of particles to be used to represent substantial shapes
and volumes. The technique is dated though, and leads to the frequent
appearance of common visual flaws because each billboard acts as an
independent entity. Make no mistake, billboards remain a useful and valued
tool for the 3D graphics programmer; however, their use in this situation is
still imperfect.
With the volumetric models described, an attempt was made to sever the
reliance on the positions and movement of individual particles forming the
cloud, instead representing the cloud as a volume. The octree models
combine a memory-efficient volumetric representation technique with the
particle system approach for fast computation of the movement of the cloud.
The discrete voxel representation of the space occupied by the cloud prevents
the billboards intersecting obviously with the ground surface, and would allow
more information about its structure to be inferred. This offers great potential
for further development to employ lighting, shadowing and detail techniques
around the cloud. The problem of the clunky animation could be solved by
121
storing the volumetric structure and interpolating or cross-fading [17]
between frames.
All of the models presented use weighted randomness as the basis of the
particle system simulation. This is not realistic, but they still obtain adequate
results.
122
Chapter 6
Conclusion
123
6.2 New Volumetric Dust Model
A novel volumetric modelling technique, based on the use of octree space-
partitioning methods, has been developed.
• The appearance of the dust cloud becomes very coarse as the voxel
size increases. The current model is also ‘fixed’ in the way the cloud
expands and lingers, which is very unrealistic for low car speeds.
These could both be improved with a new particle system model as
above, and by making corresponding changes to the way the octree
processes particles and assigns voxels. The system could retain small
voxels at the end of the cloud train to add detail around larger ones.
124
• The animation (or lack thereof) of the dust cloud should be
improved. The discrete size and position nature of the voxels causes
clumsy ‘popping’ behaviour as particles (and the billboards
representing them) move from the space of one voxel to another.
These problems could be tackled by storing the octree structure from
the previous frame or frames, and determining how the voxels have
changed in the new structure. The changes could then be animated by
cross-fading [17] or smoothly interpolating between the different
structures.
• For all the changes from the established billboard system, the voxels
are still being rendered as textured billboards. This is a compromise,
but probably the best way to handle the rendering. One approach to
improving the system would be to modify the textures in real time.
The voxels could be used to determine underlying structures to the
shape of the cloud, which are then used to calculate variable shapes
and details of the textures. This might use Perlin noise [4] or other
techniques.
• The volume only represents those fine airborne dust particles that
make up the cloud. The model could be extended to show heavier dirt
and rocks that is thrown up by the wheels when spinning and sliding.
These would require separate simulation systems to those already
presented.
125
Bibliography
[1] Timothy C. Best. The Next 100 Gaming Moments: 101 And Beyond.
In PC PowerPlay issue 100, pages 60-67, June 2004.
[3] Robert Dunlop, Dale Shepard, and Mark Martin. Sams Teach
Yourself DirectX 7 in 24 Hours. Sams Publishing, 2000.
[4] Hugo Elias. Perlin Noise. The good-looking textured light-sourced bouncy fun
smart and stretchy page, http://freespace.virgin.net/hugo.elias/
models/m_perlin.htm. Last updated 22 November 2003; accessed 9
August 2004. 2000.
[5] Ronald Fedkiw, Jos Stam, and Henrik Wann Jensen. Visual
Simulation of Smoke. Computer Graphics (Proceedings of SIGGRAPH
2001), ACM Press / ACM SIGGRAPH. 2001.
[9] Ian Kayne. DirectX 9 Tutorial Series. 32bits.co.uk – Coding for real
people!, http://www.32bits.co.uk/
modules.php?name=Content&pa=list_pages_categories&cid=4.
Accessed April through November 2004. 2004.
126
[10] Mike Kelleghan. Octree Partitioning Techniques. GamaSutra,
http://www.gamasutra.com/features/19970801/octree.htm.
Originally published in Game Developer, July 1997. Accessed 20
August 2004. August 1997.
127
128