Download as pdf or txt
Download as pdf or txt
You are on page 1of 12

Cloud Cover

Cloud Cover
The Cloud Cover program was written for the Educated Programming Contest
(now since closed down), on the subject of clouds. Against stiff competition from
various marshmallows and cottonwool, we (Matt and I) won. It was written in two
weeks flat, and coincided with our second year Maths revision, which may explain
how come we managed to fail so many exams. We were supposed to win £25, but
It's never turned up. Never mind.

I coded the realtime Perlin Noise to generate the clouds, and all the rest of
the graphics stuff, and Matt designed the overall program, and wrote the all
important inner loop which actually makes the clouds as good as they are.

Quite a few people have expressed an interest in the program, and asked
Requires DOS4GW how it was done. I promised to write an article on the subject, so here it is.

I intend to be a little vague in this article. This is for a couple of reasons, but mainly because I don't want
anyone to feel they have to follow our program exactly. The way we did it was just one possible way of many (and
not an especially good way at that). I would much rather people experimented themselves, rather than
just blatently copied our algorithms. So I shall go as far as telling you why we made each step, and how it was
based on real clouds, but probably won't give a lot of pseudocode.

General Information
We thought a good deal about what screen mode to render the clouds in, eventually coming to the
decision that an 8-bit mode would be very restrictive, and not really do the clouds justice. We settled,
eventually, for a truecolour (24-bit) mode, rather than Hicolour (16-bits). Firstly it would look better, and
secondly it would be easier/faster to program.

Not being a wizard, and being unable to communicate with the VESA 1.5 BIOS from within the 32-bit .EXE,
I initially had some trouble getting the program to autodetect the graphics card. Eventually I gave up, and
http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (1 of 12) [25/10/2010 20:39:31]
Cloud Cover

decided to place the burden on the user. The trouble is this. Truecolour modes come in two flavours, 24-bit or
32-bit, but it's up to the graphics card which it supplies you with. It's possible to query the number of bits per
pixel, but I was having serious trouble calling the Real Mode VESA functions. In the end, we had to write two
inner loops, one to render to a 24-bit screen, and one to render to a 32-bit screen, and let the user
choose whichever one doesn't look like nonsense.

As I said before, this program was written in just two weeks, so it's a bit of a mess, and many things
could have been done a lot better. Everything is software rendered, and little attempt was made to optimise it.
It uses a good deal of look up tables, so the more cache you've got, the faster it'll run. However, I expect that
it would be possible to speed it up a great deal with 3D graphics hardware. It should even be possible to make
a version that allows you to look around freely. Anyway, I'll leave that up to you, and get on with the article.

About Cloudscapes
The first thing you should do if you're going to simulate clouds is to rush outside and look at some
real clouds. Make as many observations about the clouds as you can. However, if you're anything like me,
you're probably reading this at night, so I'll tell you some things about clouds.

1. The sun is very bright and it is making you squint !


2. The clouds near the sun are glowing much brighter than clouds far from the sun.
3. Luckly the clouds are moving across the sky, and occasionally block out the sun,
making it easier to see, so you don't have to squint as much.
4. The clouds are also changing shape as they move across the sky.
5. Not all the sky contains cloud. Some areas of sky are completely cloud free.
6. The clouds do not continue into the distance forever. The furthest clouds are often
obscured by haze.

All of these things happen in a real life cloudscape, and lots more besides. The more things we can
simulate, the more realistic our clouds will look.

Creating Clouds
If you have not already, I suggest you read the article on Perlin Noise.

Perlin Noise is great for creating cloudy type things, and can produce very realistic results. However, it is
far too slow to be used for a realtime graphics application like this, and a faster alternative must be found.

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (2 of 12) [25/10/2010 20:39:31]


Cloud Cover

In the end, we settled for comopsition of four octaves of animated noise at various frequencies
and amplitudes.

Each octave (four in total) was calculated seperately, and they were all added together to create a
cloud texture. A sheet of noise was handled like this:

Smooth
Create an array of noise Resample it up.
it

This was done for four arrays of noise to


create noise textures of size 32x32,
64x64, 128x128 and 256x256.

Imagine now that these noise textures are


tiled together to create four maps each of
size 256x256. (see left).

The white lines have been added as a


http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (3 of 12) [25/10/2010 20:39:31]
Cloud Cover

guide just to help you see the tiling.

Now, add these four maps together:

CloudMap = Map1 + (Map2 / 2) + (Map3 / 4) + (Map4 / 8)

It doesn't look a great deal like the cloud cover in the program yet, but it's getting
there. Importantly, observation number 5 (above) has not been satisfied. This entire
texture contains cloud to some extent. What we really want is areas of cloud, and areas of
totally empty sky.

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (4 of 12) [25/10/2010 20:39:31]


Cloud Cover

There is a fairly simple function you can use to


transform the plasma into something that looks a lot like
clouds. The exponential function is the mother of all
functions. You will find uses for it everywhere.

function CloudExpCurve(v)
c = v - CloudCover
if c < 0 then c=0

c
CloudDensity = 255 - ((CloudSharpness ) *
255)

return CloudDensity
end function

Values of CloudCover between 0 and 255 give total cloud cover and empty sky respecitvely.
CloudSharpness controls how fuzzy or sharp the clouds are. Lower values give sharper,
denser clouds, and values closer to 1.0 give fuzzier, thinner clouds. Do not use values any
greater than 1.0.

You should agree that these look a lot more like clouds than the previous image.

Putting the clouds in the sky


If you hadn't already noticed, the sky is curved . It's amazing how many computer
generated images of the sky fail to take this into account. If you have a totally flat sky, the clouds will appear to
go forever into the distance. You will notice that this does not happen with the real sky, so it should not
happen with our simulation.

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (5 of 12) [25/10/2010 20:39:31]


Cloud Cover

So, we shall take our little square of clouds, and lay it over a sphere to represent the curvature
of the earth.

The camera is then positioned, not in the centre of the sphere, as this is not realistic. We live on
the surface of the earth, not in the centre. So, put the camera somewhere near the top of the sphere,
and point it at the clouds. Sorry that the diagram doesn't really show the correct position of the
camera, but it would have been too cluttered.

Colouring it in nicely
Right, now that the clouds are in place, they're going to need to be coloured like clouds. You might
be tempted to colour the sky blue, and the clouds white, and leave it at that. You're more than welcome, but
it would look lame.
Firstly, we'll render the backdrop to the clouds. The sky directly overhead is blue, but if you look into
the distance, you will see that it becomes a pale blue / grey.

Blue Sky

To do this, we needed the know the distance to the cloud dome at each pixel.
Knowing this information, we kind of bodged together an algorithm to produce a blue/
grey gradient across the sky. I'm sure you can figure out something similar, so I
won't go into detail here.

Glow from the Sun


http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (6 of 12) [25/10/2010 20:39:31]
Cloud Cover

Since the light from the sun scatters in the atmosphere, you get a bright glow
around it. We modeled this glow with an exponential function. See there it is again.
Also, a constant value was added to light up the atmosphere to make the atmosphere
calculations work correctly.

This was stored as a 320x150x8bit texture map to be used later to make the
clouds glow near the sun.

In the pseudocode at the end of this page, I shall refer to this as the Glow
map.

Mixing the two

Now, the blue sky and the glow were combined to create a bright glowing
atmosphere.

Since the camera never moved, this was stored as a 320x150x24bit texture
map.

In the pseudocode at the end of this page, I shall refer to this as the BlueSky
map.

Lens Flare

Lastly, a lens flare texture was created. You can use any lens flare map you
like. This one was created in much the same way as the glow map, but six lines were
added as well. The lines are the width of the sun, and fade off exponentially.

In the pseudocode at the end of this page, I shall refer to this as the
LensFlare map.

Combining it all into a finished image

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (7 of 12) [25/10/2010 20:39:31]


Cloud Cover

There are a couple of things going on every frame. Firstly, the cloud map must be animated. Then the
blue sky, sun glow, cloud map, and lens flare are all combined to create the final image.

Animating the clouds

If you read and understood my very brief explanation of how the clouds were created, then it is a
simple task to animate them. All you need to do it to animate the original noise maps.
You will remember that there are basically 4 noise maps. The ones we used were 32x32 pixels
each. Animating them is simply a matter of interpolating them from one noise map to another.

Animating a single noise map

50% Noise 1 50% Noise 2

Noise map 1 Crossfade between Noise 1 and Noise 2 Noise map 2

NoiseMap1 : map of 32x32 pixels


NoiseMap2 : map of 32x32 pixels Pseudocode to animate an octave of noise
AnimMap : map of 32x32 pixels
Hopefully this small fragment of code will help to convey
Initialise NoiseMap1 something which I am finding very hard to explain in words. The
Initialise NoiseMap2 idea is to use this code to maintain four octaves of animating
noise. The four octaves will need to animate at different speeds.
time = 0 The noise map responsible for producing the the largest amplitude
timestep = something less then 1 of noise should animate the slowest.

loop forever The Initialise Noisemap procedure should fill a noise


map with random pixels, then apply a smoothing filter.
if time >= 1 then
time = time - 1 The noise maps are thes used as explained in the Creating
NoiseMap1 = NoiseMap2 Clouds paragraph.
http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (8 of 12) [25/10/2010 20:39:31]
Cloud Cover
Initialise NoiseMap2
end if

p2 = time
p1 = 1 - time

AnimMap = (NoiseMap1 * p1) + (NoiseMap2 *


p2)

time = time + timestep

end loop

Rendering the Image

Any finally, you will have to actually take all this information (BlueSky, Glow, Lensflare and Clouds),
and combine them into an image. Now, we took a look at the original code, and we can't figure out what some of
it does, so we haven't included it here, for the sake of simplicity. This fragment of pseudocode will probably
not produce nice clouds straight off, so don't write to me complaining. It's only really meant as a guide to how
we achieved it, to point you in the right direction. You may have to do a lot of fiddling around and rearranging,
and lots of optimising. Basically, don't copy out this code. read it, try and figure out vaguely what's going on,
and write your own version from scratch.

Take a look at the Exposure article for information on the ExposureFunction.

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (9 of 12) [25/10/2010 20:39:31]


Cloud Cover

function HazeExpCurve(d)

c = a couple of hundred. Depends on how far away the sky dome is


Hazyness = about .95

p = d2 / c
return Hazynessp

end function

FlareStrength = Cloud Density over sun

for each pixel

c = pixel from CloudMap


gl = pixel from GlowMap
fl = (pixel from FlareMap) * FlareStrength
h = HazeExpCurve(Distance to cloud dome)

Start with Blue Sky Map


HazeRed = Red Component of pixel from BlueSky map
HazeGreen = Green Component of pixel from BlueSky map
HazeBlue = Blue Component of pixel from BlueSky map

Add simple shading to clouds


shading = simple bump mapping on cloud

Apply the bright glow on the clouds from the sun


shading = shading * gl

Fade the amount of cloud by the haze (according to distance)


CloudVal = c * h

Alpha-Blend the clouds with the blue sky using CloudVal


Red = Red + (CloudCol-Red) * CloudVal
Green = Green + (CloudCol-Green)* CloudVal
Blue = Blue + (CloudCol-Blue) * CloudVal
http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (10 of 12) [25/10/2010 20:39:31]
Cloud Cover

Add Lens Flare


Red = Red + fl
Green = Green + fl
Blue = Blue + fl

Now, use the exposure function, since values of Red, Green and Blue may be quite
high
Red = ExposureFunction(Red)
Green = ExposureFunction(Green)
Blue = ExposureFunction(Blue)

Draw this pixel

end loop

References
LIGHT (in C++) ! : http://math1.uibk.ac.at/~werner/light/

Interesting sky / clouds / landscape renderer written in C++.

Mapping Reality: Simulating Clouds : http://patate.virtualave.net/clouds/index.html

Information on rendering plasma clouds.

Convective Clouds : http://www-imagis.imag.fr/Membres/Fabrice.Neyret/clouds/index-eng.html

Research into models of convecting clouds.

Radiant lense flare render engine : http://www.geocities.com/SiliconValley/Ridge/7251/


radiant.htm

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (11 of 12) [25/10/2010 20:39:31]


Cloud Cover

Pretty self explanatory.

Intel Developer Site : http://developer.intel.com/software/idap/games/index.htm

Kim Pallister has written an article, based on this one, explaining some methods of using
hardware acceleration to speed up the rendering of clouds. However, I get the feeling that hardware acceleration
is not appropriate for all aspects of these clouds. I think that, until graphics cards get more advanced, or allow
you to program your own routines, some of this will still have to be done in software.

Noise Machine : http://www.noisemachine.com/

Ken Perlin's course notes from the GDCHardCore gamers workshop, San Francisco, Dec 9, 1999.

Return to the Good Looking Textured Light Sourced Bouncy Fun Smart and Stretchy Page.

http://freespace.virgin.net/hugo.elias/models/m_clouds.htm (12 of 12) [25/10/2010 20:39:31]

You might also like