The Animation Method
As discussed on the first page, to create a realistic snowfall effect we need to create a vector field which determines the acceleration to apply to a snowflake according to its position in space. Our solution is to use Perlin noise to create this vector field. And since Perlin noise can be smoothly altered over time, the vector field can continuously change, representing air that flows and whirls unpredictably.
The basic idea is this: a bitmap is created and filled with Perlin noise, using only the red and blue channels. When a snowflake is at certain position, the acceleration it experiences will be determined by the color of the pixel in the corresponding position of the bitmap. The red component determines the acceleration in the x direction, and the blue component determines the acceleration in the y direction. (Note that we have created a rather small bitmap: it would be wasteful to compute a large bitmap the same size as the display, since the snowflakes will be rather sparsely distributed over the display. The snowflake positions are scaled down accordingly when computing the corresponding acceleration.)
This Perlin noise method works very nicely for a 2D effect, but we decided to go a little further and create a three dimensional snowfall effect. Instead of using native 3D methods in Flash, we decided to simply use a parallax effect, where the distance away from the observer is simulated simply by making objects larger or smaller, and to scale distances accordingly. Since the snowflakes are all white, we didnít worry about depth-sorting. A particle closer to the observer should be drawn over one that is further back, but if they are the same color this wonít make a difference.
But how would we create our vector field, now that we required a three-dimensional one? A simple solution was to use two bitmaps: one to represent acceleration for the particles all the way in the back, another bitmap to represent the acceleration for the particles in the front. For particles somewhere in between, we interpolate the red and blue values of the front and back bitmaps to determine acceleration. Also to simplify matters, the snow only moves in the x and y directions, never in the z direction (towards or away from the observer).
In the first applet we present in this tutorial, you can see the two Perlin noise bitmaps in the lower left corner. Note how small the bitmaps are. This small size is all we need to create our effect.
There are some details we are leaving out in the description here. For example, the average red and blue values are continuously recomputed, and these average values are used to offset the acceleration amounts. Also, since the viewable rectangle in the front represents less space than in the back, we should see fewer snowflakes emerge towards the front. We use a probability trick to make particles more likely to emerge towards the back. The code is fairly well commented, and its inner workings may be clear with careful study.
There are many parameters available which allow you to change the look of the snow effect. For example, how far back the snow falls, how much depth there is, gravity, air resistance, turbulence, and wind. The different radio button examples presented in the first applet on the previous page illustrate the effect of these parameters.
Perhaps a simple two-dimensional snowfall effect is all that we may want for some purposes. This can be created by setting the Boolean make2D property of the SnowDisplay to true. A 2D snowfall effect can be observed in the fourth radio button example in our first applet.
With little air resistance, objects falling towards the Earth accelerate due to gravity. However, objects such as snowflakes fall towards the ground with a fairly constant velocity, called the terminal velocity, which is due to the slowing force of air resistance. We have modeled this behavior in our code, setting parameters for air resistance and gravity, and allowing the snowflakes to move accordingly. In the absence of turbulence, the terminal velocity of the snowflakes will be the square root of gravity divided by the air resistance factor, and you will see in our code that this is how we set the initial velocity of the snowflakes. Thus if you would like to see the snowflakes move, say, more slowly than they do with the default parameters, you can either increase the air resistance factor or decrease the gravity constant.
Placing More Objects in the Display
You may wish to place a graphics object in the snow display at a particular depth, and want nearby snowflakes to pass in front of this object, while far away snowflakes fall behind it. The easiest way to accomplish this is to layer two SnowDisplay objects: one for the snow in the back, one for the snow in the front. Other objects can be placed in between these layers. Of course, you will need to set the z-value parameters of the individual SnowDisplays so that they cover different ranges of depth. We apply this layering technique in the second example on the previous page.
- Download the source files for both examples: snow.zip