The atmosphere is complex. Very complex. Now I know that's a bit like saying an atomic blast is a bit noisy, but it is very true. Whole arrays of super computers are used to attempt to model our planets atmosphere, and they still cannot tell you if it is going to rain tomorrow.However we all can look at the sky and recognise features. There are many types of clouds, and we spend most of our life looking at them, so when we see a game with clouds in the sky we can tell if they look right or not.Most people just use noise for clouds, Perlin is the favorite, but I wanted to see if we could do better. Which kicked off three weeks of intense coding. I am still not 100% happy with the results, but it is starting to look good and maybe someone out there can build on this. So here we go.

Building blocks

There are many physical factors that affect cloud formation, if you are good at math, get a copy of Cloud Dynamics by Houze and scare yourself.We are going to take the most important ones and then cheat.The basic building blocks we need to start with are...

Terrain

Heat

Friction

Pressure

These are pretty easy to generate so I will skip over them quite quickly.

TerrainFor this, just to make it more familiar for you, I have grabbed a heightmap of the Earth.

HeatThe heat map is a function of the terrain and the amount of star light that lands on the terrain. We can do this very easily with a shader. Note that water has a very high specific heat capacity, so I have adjusted the heat map in the water areas.esun is a variable passed in from the planet definition and represents the amount of energy the star is throwing at the planet.This texture is included for you to use in your own research. I ended up cheating in the simulation and I didn't need it, but I will explain it's potential uses later.

PressureWe define a new variable in the planet definition PlanetWeatherIntensity.This is a representation of how violent the planets weather system is.I am just using this as the number of weather systems to add to the planet.We start by adding this number of random points to a list.

To turn this into something we can use we need to add up all the pressure contributions from each point for each pixel.This would require a lot of passes in a shader. You would need to do a pass for each point, then recover the texture and use it in the next pass.So I chose to do this in C#.

Note that I have used a floating point format for this texture to give us some accuracy.Now we have the basic building blocks, we need to calculate the velocity of the atmosphere.The intial velocity is calculated based on the four maps above.The primary force is due to differences in pressure, so we calculate the average pressure difference by looking at all the pixels around the current one

// atmospheric pressure at the current point
float4 here = tex2D(HeightMapSampler,texCoord);
float2 uv = float2(0,0);
for (int i = 0; i < SAMPLE_COUNT; i++)
{
// for all the points around the current point,
// calculate the pressure difference and use that as a force
float2 samplePoint=texCoord + SampleOffsets[i];
float4 localPressure=tex2D(HeightMapSampler,samplePoint);
float pressureDifference=localPressure.x-here.x; // -1 to +1
uv+=pressureDifference*SampleOffsets[i]; // -gridsize to +gridsize
}
uv*=200000;

The next factor we need to estimate is friction. We have the base value from the map above so we can add it fairly easily.

One of the major factors we need to add is the corriolis effect, this is what gives us our circular weather systems.This is proportional to the speed relative to the axis of rotation of the planet, so we can cheat and just use the X velocity.We also need to scale the result to fit in the range 0-1, so we might as well do that now.

// estimate the coriolis force
uv.y+=(uv.x-uv.y)*0.5;
uv/=2;
uv+=0.5;

The end result of this shader is the initial velocity of the atmosphere we can feed into the next stage of the simulation.

As you can see it has nice circular artifacts which will lead to weather systems in the finished map.

Now we start to get into the interesting bit. We treat the atmosphere as a great big ball of fluid. We use the velocity map to move this ball of fluid around. Fluid simulation is another complex subject, but thankfully there has been quite a lot of work published we can draw on to make this work. The first thing we have to do is advection. This is the process of moving the atmosphere around based purely on the velocities. We start with the initial velocity we calculated earlier and use this to advect the velocity, and a density map. Both results need to be stored in new textures. I will skip over the supporting C# code here, it's in the zip anyway so you can look at it at your leisure, but it basically just creates a render target, runs the shaders, and recovers the results. These are the pixel shaders for advection.

Now we use the newly modified velocity map to calculate the divergence.Divergence is the amount of stuff being moved by the velocity field.This is the really important bit for me as I use the divergence directly as my clouds.The idea I had was simple, if the planet started off with a uniform density field, then the change in density IS the divergence.So I can cheat and just use this as the final density field. I know this is a bit of a stretch, but it will do for me for the time being.

Nice?You could just stop here and use this as your cloud map, but I find you have some artifacts in the display because the fluid hasn't settled down yet. So I do a bit more work. The next stage is to perform a Jacobi relaxation step on the divergence map and the pressure map. You need to do this in a loop, really you should do about 50 passes, but I find 10 works for me.

Few.To get the fluid simulation to settle into a fairly steady state, we need to loop over all those shaders a few times.The more you loop the smoother the result. I use 50 iterations.At the end of all that you have something like this.

A lot of work has gone into getting the simulation this close, but it's not right yet.If you look at the pacific off the coast east of the Philipines you can see linear artifacts, I would like to get rid of them.Secondly, although a lot of this work is based on the real physical systems, I have cheated by just using the divergence field.What I would like to do at some stage is to use the height and heat maps to inject water vapour into the density map, then allow the system to run for a while and see what turns up.Then I want to use the heat, pressure, and denisty maps to model rainfall.But that can wait for another day.New zip with all this rubbish integrated into the planet renderer. hereAfter all that I would like to move onto a nice easy subject, but sadly the next stage in our planetary creation quest is atmospheric scattering.