This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
Procedural Textures Bring Nature to Internet Explorer 4.0
Charles Mirho |
Based on noise and turbulence theory, procedural textures in Microsoft Internet Explorer 4.0 enable realistic, natural animations by combining a single bitmap with mathematical equations. |
People like to watch things move. Animation is the technique of creating the illusion of motion. One approach is frame animation, in which a series of bitmaps are sequenced rapidly to provide the illusion of motion. Another technique is palette animation, in which the color palette of a single bitmap is manipulated over time to reveal interesting patterns that only become visible as the colors change.
Both techniques have limitations. With frame or cell animation on the Internet, each bitmap in an animation sequence (or at least the changes between consecutive bitmaps) must be downloaded before the animation can be sequenced in the browser. Furthermore, once the frames are created, the animation follows a predictable sequence from start to finish and then repeats itself. Palette animation has a similar limitation. Although the palette can be cycled in different fashions to vary the effect, the range of possible effects is limited by the color content of the bitmap. Natural phenomena such as fire, water, wind, smoke, and clouds look best when endowed with an aspect of randomness. A wisp of smoke just doesn't look right unless it dissipates into random particles, and ripples on water should cause random reflections. Enter procedural textures, a new feature in Microsoft® Internet Explorer 4.0. Procedural textures enable realistic, natural animations using a single bitmap (the texture) combined with one or more mathematical equations (the procedure). The position and color of individual pixels are manipulated by the equations to provide the illusion of motion within the boundaries of the bitmap. Using a single bitmap makes animations download faster. Unlike conventional animations, the effects generated procedurally can be nonrepeating because of the randomness created by the equations. The effects mimic nature because of their basis in noise and turbulence theory, which provide a good model for certain natural phenomena.
How Procedural Effects Work
Creating Procedural Textures
Next, I define the effect by assigning a noise function to the image style property. The noise function is defined as follows:
The effect is additive, meaning it adds pixels to the seed bitmap instead of distorting the pixels that are already there. The noise function has six levels of harmonic complexity; it will be computationally intensive but very smooth and natural-looking (the more harmonics, the fewer jagged edges in the effect). A NoiseScale of 11 is assigned, which causes the flame to jump around quite a bit. Smaller noise scales would produce a more docile flame, and larger noise scales create violent, lashing flames because they pump up the power of the noise function. The NoiseOffset property is a little tricky. Essentially, this property gives you some control over the color of the effect. Large positive values for NoiseOffset (up to 256) cause the lighter colors of the seed bitmap to receive emphasis in the effect. Large negative values (down to -256) emphasize the darker colors. I chose -13 here, indicating a slight bias for the darker colors. Next, I scale the effect by a factor of 2 in the X direction, and by 1 in the Y direction. Essentially, I'm telling Internet Explorer to stretch the effect in the X dimension by twice the scale of the Y dimension. This produces a more vertically layered flame effect to the eye. I want the effect to appear to slowly ripple across the flame from right to left, so I use a TimeX value of -1, causing the flame to ripple horizontally. I don't want to do the same thing in the Y dimension, so TimeY is set to 0. Finally, the Enabled value is set to 1, indicating that the effect is enabled to run when the page loads. As you can see from this example, much of the effect's design depends upon the seed bitmap and the definition of the filter values. The outcome often depends on trial and error, changing the parameters to achieve the optimal visual effect, but the results are worth the effort. Moving back to the top of the Web page, the first script code is the window_onload event procedure, which is executed when the Web page loads. This is the place to do one-time initializations. First, I set up the offscreen bitmap buffer. I tell Internet Explorer to use the same pixel depth for the offscreen buffer as is used for the display. This way when the effect is rendered offscreen and then moved on-screen, it will look correct. |
|
Next, I set the bitmap seed for the effect. The bitmap is seeded here instead of in the tag itself because Internet Explorer expects it to be done in the onload event. By setting the property here, an OnFilterChange event is generated which causes the effect to begin to execute (see Figure 3). You will see how this works in a moment. |
Figure 3: Event procedure executes the effect |
Next, I define an event procedure to be called whenever any of the effect properties are changed. The purpose of this event procedure is simply to rerender the effect each time one of the properties changes. Just as with other tags, an effect's properties aren't static when set in the tag; with Dynamic HTML, the effects can be changed on-the-fly while the code is running. |
|
The event procedure is called theImg_OnFilterChange, and it calls only a single procedure: SetTimeout. First, the SetTimeout call specifies a procedure for Internet Explorer to invoke after the timeout interval expires, in this case 15 milliseconds. The procedure it calls is OnPokeEffect. So a change in the effect properties schedules a call to OnPokeEffect after 15 milliseconds. No big deal. Here's the fun part: the OnPokeEffect procedure simply tinkers with the appropriate effect property, in this case the NoiseScale. It doesn't change the propertyit just reads it in and writes it back. The result is that another OnFilterChange event is generated, which schedules another call to OnPokeEffect, and so on. What is going on here? It turns out that Internet Explorer will only update the effect on the screen when an effect property is writtennot necessarily changed. So to cause the flame to flickeror the clouds to float by, or the water to rippleI must keep tinkering with some of the effect's properties so Internet Explorer thinks it needs to update the display. |
|
Why not just call OnPokeEffect directly from the
OnFilterChange event procedure? If I did this, I would have no control over how fast the effect ran. It would run more quickly on fast machines than on slow ones. Scheduling the call to OnPokeEffect every 15 milliseconds, guarantees that the effect will run at the same speed on all hardware. A more complete VBScript implementation would also include procedures to disable the effect when the window was hidden, and reenable it when the window was displayed again. This would save machine cycles. The effect can be disabled simply by setting the Enabled value to false. Internet Explorer 4.0 supports built-in effects for fire, clouds, and water, with no seed bitmap required. I simply specify the same header and scripting code. The only change needed in the script is in the window_onload subroutine. I also change the <IMG> tag to the following: |
|
Because I'm using a built-in effect, I don't need to specify a seed bitmap, mask, or any of the effect values. Instead, I just specify the dimensions I need for the effect and a seed value of 1 (for fire), 2 (for water), or 3 ( for clouds). Bingo! Instant nature in my Web pages. |
|
I do need to make a small change to the VBScript when using built-in effects. Because no seed bitmap is used, I cannot count on a property change to generate the first call to OnFilterChange. Instead, I must call OnPokeEffect directly from the onload event procedure. This gets the ball rolling, and subsequent calls to OnFilterChange are generated by the property diddling in OnPokeEffect.
Turbulence
Distortion
|
Figure 6: Distortion effect on seed bitmap Test It! |
Other Tricks
|
Figure 7: Mask bitmap |
Figure 8: Mask with flame effect |
Mask bitmaps may be employed to superimpose effects from one bitmap onto another. Combining masks with transparency makes for very interesting possibilities. For example, a mask with a blue background and black block lettering (like the one shown in Figure 7) can be combined with a source bitmap for flames and a black transparency color. The result is an effect in which the black letters of the mask bitmap are animated with the flame effect, as shown in Figure 8. The blue background is left unchanged.
|