I already created the basic cloud system when I came across the article
Realistic and Fast Cloud Rendering by Niniane Wang which totally took me back to drawing board. Whilst I'd implemented some of what they said they took things to an altogether higher level. They detail how the clouds in Microsoft Flight Simulator are created, if you havent seen them then check out the article as it has some good screenshots. They include cool stuff like backlighting and better grouping control.
What I'd already implemented incorporated the following:
- Each cloud was a group of 5 billboards, the idea here was that I could then animate them randomly to achieve easy cloud deformations such as drifting apart and fading sections out
- All rotated to camera to hide their 2D reality
- Multiple textures used. Each billboard would have a single random cloud texture applied to it
- A cloud type system. I researched cloud types and created an array of their features. So cumulous clouds would be big and fluffy and others would be long streaks. This allowed me to say create 10 cumulus and 5 altocumulus clouds and each cloud group in that type would apply the correct positioning and spacing needed to achieve the correct look. I created the data but only applied it to cumulus so far.
- Also created a sky data structure so I could say create a stormy day or create a clear nighttime sky. That would control the lighting, the bg color, a sun when one was implemented and the clouds.
So as you can see, it wasnt too complex but it wasnt quite simple. The data for the clouds looks pretty horrid and I'm positive its layout can be improved. This page is going to list the changes I need to make to the cloud system to give it all the abilities detailed in the above linked article. I want to attempt to take it to the next level and implement shaders for some of the work. They suggest trying this themselves at the end of the article, I think that will mainly be for lighting/coloring the clouds correctly although I think a vertex shader could be used to add on the fly deformations to the clouds. Need to read more about shaders for that though. The first step is to build a system comparible to theirs, then aim to improve it :¬)
- each cloud as 5 to 400 alpha-blended textured sprites
- The sprites face the camera during rendering and together comprise a 3-dimensional volume
- Render them back-to-front based on distance to the camera
- There are generally 20 – 200 boxes for each 16 square kilometer section of clouds
- 1 – 100 sprites per box depending on the cloud density
- traverse the list of clouds and eliminate any sprite whose 3-D distance to another sprite is less than a threshold value. This reduces overdraw in the final rendering, and also eliminates redundant sprites created from overlapping boxes. We have found that a cull radius of 1/3 of the sprite height works well for typical clouds, and 1/5 ... 1/6 of the sprite height yields dense clouds.
- mix-and-match 16 textures to create a dozen distinct cloud types
- Textures are 32-bit, and used for both color and alpha
- By creating interesting features inside the textures that resemble eddies and wisps, we are able to create more realistic looking clouds with fewer sprites.
- We keep the video memory cost low by placing all 16 textures on a single 512x512 texture sheet, which spares the cost of switching textures between drawing calls to the video card
- When the binary file is loaded into the game, the sprite is given a random rotation within the range.
- We have found that it looks best to give the cumulus cloud bottoms a narrow range (-5 to 5 degrees) and all other sprites the full range of rotation (0 to 360 degrees).
- We do not apply a rotation to non-square sprites.
- lock the facing angle of the sprite when the camera comes within half of the sprite radius. This removes the Red Sea effect
- detect the angle between the sprite’s locked orientation and the vector to the camera, and adjust the transparency of the sprite, which also produces the side effect of making that section of the cloud appear less opaque
- We control the evolution of a cloud by adjusting the transparency level of sprites
- To do this, we calculate a transparency factor and multiply it into the alpha from the shading equations for each vertex.
- We decide the transparency factor based on the sprite’s position within the cloud.
- When a cloud is beginning to form, we render only the sprites whose center is within half of the cloud radius from the cloud center, and we render them with a high transparency level that we decrease over time.
- After they have reached a threshold opacity, we begin to render sprites whose center is over half of the cloud radius from the cloud center.
- Cloud dissipation is simulated by reversing the process.