Archive for March, 2009

Clouds Part I

This is another article which I plan on writing in a few parts. I have added a pretty simple cloud layerr to Britonia using a distored fBm fractal and improved noise basis function. This is used in a shader to generate a per pixel cloud map, which is then just sampled over a spherical ‘terrain’ which a height of zero.

To be honest, the clouds are actually something I had anticipated implementing much sooner.  The theory is quite simple really

The implementation of the clouds is much the same as the terrain, and if anything it is simpler.  You need just create another sphere with LOD. As far as geometry goes, I am using a smaller vertex grid for each patch (e.g. patches made up of 9×9 grids instead of the usual 33×33), and I am also limiting the depth that the quadtree subdivides to to 4.   The texture to be applied to each patch is generated using perlin noise in the pixel shader and can be setup to use any size, I’m going with 256×256.

As far as rendering goes, we just need to set the radius of the sphere as the height of this particular cloud layer and then render each patch with the generated cloud map.  There are a few things to watch out for, such as the render order of things with alpha blending, and also set the culling, but nothing too difficult.

The distorted noise function which I am currently using for the cloud map generation looks like this:

float3 offsetPoint(float3 p)
{
float3 result;result.x = inoise(p);
result.y = inoise(p*3.33);
result.z = inoise(p*7.77);

return result;
}

float DistNoise(float3 p, double distortion)
{
return inoise(p + distortion * offsetPoint(p + 0.5));
}

// fractal sum distorted noise
float DfBm(float3 p, int octaves, float lacunarity = 2.0, float gain = 0.5)
{
float freq = 1.0f,
amp  = 0.5f;
float sum  = 0.0f;
for(int i=0; i<octaves; i++) {
sum += DistNoise(p*freq, 0.5)*amp;
freq *= lacunarity;
amp *= gain;
}
return sum;
}

/* inoise() function is the improved perlin noise function */

You can then use the return value to mix between two other colours, say, pure alpha and white so you can see the stars at night through the clouds (again look to the screenshots below).

I am not sure at the minute whether generating the colour per frame using noise is the best way to go.  I could probably generate a large texture using the same distorted noise function, which can be applied over large parts of the planet, meaning instead of numerous noise() calls, I just need a tex2D() call (after texture generation).

For the next update I hope to have a bit more variety in the clouds, as well as some changes in cloud cover etc. etc.

Here are a couple of screenshots:

Image

Image

Image

Advertisements

Leave a comment