Simple Volumetric Clouds

Hi,
Decided to toy around with clouds yesterday, ive been meaning to for a while now every since I saw the Far Cry videos and such. I read a few articles that seem to over complicate things; for example this tries to mimic realistic cloud behaviours such as the probability that water vapour will go to water droplets when the pressure falls before a certain level. However, it also allows “shaft light” phenomenon to occur. this also doesn’t allow light to move around freely without oncurring heavy computation, however, it does use naiver stoke equations to solve densities at certain points (from what I can understand from it) and is thus more accurate than my method, but its about 100x harder, it also doesn’t allow for “shaft” light, whereas my method does.

Fudge all that!

What I did was rather simple, and produces good enough results for games, worst case scenario, it produces as good results as 4d perlin noise. This is the algorithm; note that im going to be talking about 1 cloud at the moment, but the algorithm can be extended for N clouds and the clouds to merge together upon collision. Also, im going to describe the method that works without shaders, although with shaders, its still simple, and is probably faster.

Algorithm

  1. Create a 3D grid (that will be converted to a 3D texture).
  2. Create N point masses, try and keep them initially together within the regions of your cloud, a pseudo-random generator should do the trick fine. These point masses have a mass and a constant C.
  3. Loop through every cell in the grid and find the nearest point mass.
  4. Set the value of the current grid to be equal to NearestPoint.C * distanceToNearestPoint (this is effectively a voronoi diagram with 1 distance function).

The above will create clouds that are ok looking, if you get you constant C right, all is nice, you have to experiment a little to get that nice fluffy feeling of clouds.

  1. Using some movement function, be that a simple x += velocity, or complicated fluid dynamics, move the point masses along and update the field, this will cause the animation of clouds. Obviously, if you used fluid dynamics, the animation of the clouds is realistic, but a verlet integrator taking into account influences from other point masses around it would work well too; a mixture of force and point gravity.
  2. Vary the C constant with a probability function, what you effectively doing there is increasing the probability of water vapour changing to water droplets and vice versa thus creating and destroying clouds. A 1/x function is a good decay algorithm, simple and produces nice results too.

Rendering the actual clouds can use anything really, marching-cubes algorithm for volumetric tesselation is good, but since I already have the 3d grid, i just converted that to a 3D texture and did a glTexSubImage3D on updates, pretty nifty. Shaders are also possible, you can calculate the voronoi diagrams and do the calculations on a per-fragment bases, just pass the point masses in as uniforms. Its better off splitting the point masses into grids and using the hanging-moss algorithm before passing the uniforms to the shaders.

Shaft Light is pretty simple with grid based approach. In the 3D texture, add a light factor to every cell, then when sample the light and attenuate the light factor from the cells above it (above, above left and above right cells, scale down the left and right too). You then have the silhouette to extrude the shaft from, use the common stencil shadows alogrithm for extrusion and stencil masking.

If anyone has any improvements, let me know.

DP

screenshots damnit, we want screenshots :slight_smile:

Endolf

Ok, ive been instructed quite heavily to explain more, or cyanide will flow through my veins, so here goes:

The point masses are continuous. The grid space is discrete, the values in the cells of the grid are linear functions relating to the distance between the current cell and the nearest point mass to that cell.

The voronoi diagram algorithm is described between steps 1 - 4, its a sort of voronoi diagram, its also a sort of meta ball simulation; whichever you want to think of it like.

The verlet integrator is just a way to animate the point masses, it doesnt’ have to be that way, you can use LCP instead. I used fluid dynamics, you can use whatever. Google for verlet integrator to find out, theres a good article about that on gamasutra regarding Hitman physics. Also use some sort of function to attract and repel the point masses from each other, i.e. a sweet spot for the position of the current point mass with regards to its neighbours, a sort of joint if you will so that the point masses dont come too close and dont go too far, but allow for them to escape easier than the are to overlap. I’ll have to think of a function for that…

I think i better call 0800-Cyanide-helpline before its too late.

As for screenshots, the clouds look crap at the moment because I dont have a decent card for HDR. Wait for VZ3 (you know who you are!)

DP

O_o

Point sprites that are scaled according to C centered on the point mass with blending works fine too, not as good looking, but perfect for FPS shooters and such.

DP

code, we want code. clean. and documented.

please ;D

Hahaha, you wont get clean documented and understandable code out of me

but at least some screenies … pleeeeeease :-*


[i]there is not enough space to write down the complete proof, but I have a really nice one.

Fermat
[/i]
(hundrets of years later they found one - very ugly)

You don’t want it to end like this - do you? :wink:

Your forgetting to mention that the there was a 1Million USD dollars for whomever solved Fermat’s theorm :stuck_out_tongue:

All im saying is wait for my next game, it may never come, but it will have fluid dynamics and volumetric clouds (and some kick ass spherical terrain and a mixture of 3D and 2D gameplay all at once!)

DP