meta data for this page
  •  

Local Wind Effect

By default, the SpeedTree wind system supports a single uniform wind direction that affects all tree instances the same way. However, support for localized, omnidirectional wind sources is also possible. Think of a helicopter hovering just above a forest’s canopy, for example.

Because the wind system is implemented largely through a vertex shader, it’s possible to efficiently apply unique wind behavior to every instance even without a localized source. This is accomplished primarily through two techniques:

  1. Using each instance’s world position as an offset into the shader noise lookups will keep two identical and adjacent instances from mirroring each other’s wind animation. The offsets keep them out of sync, resulting in a much more natural effect.
  2. Each instance can have a unique orientation to which the wind system will automatically adjust. So, two adjacent identical instances can have different orientations, masking that it’s the same mesh, particularly when the noise offsets are added.

A modification of the second technique can be used to implement an omnidirectional point source. This modified technique is contained in the utility function WindUtil_LocalSourceEffect() in Include/SpeedTree/Core/SpeedTreeWind.h. Given a wind point source position (A) and a tree instance’s position (B), a local wind direction vector (D) is computed as normalize(B - A). The angle of vector D relative to the +X axis is then determined and that’s used to “rotate” the wind vector into place. When this approach is applied per instance, each instance is given a unique wind vector.

WindUtil_LocalSourceEffect() also supports an optional decay effect where the wind strength gets weaker as the distance between the wind point source and the tree instance increases.

Example shaders

The Reference Application ships with the following example vertex shaders: Forward/local_wind_example_vs.hlsl and Deferred/local_wind_example_vs.hlsl. Each one demonstrates how to properly invoke WindUtil_LocalSourceEffect() but uses a hardcoded wind source position of (500, 500, 0), where +Z is the up axis.

Running the sample

An .sfc forest configuration file, sample_local_wind_effect.sfc, is included in the SDK. It loads a single .stsdk model and puts a few hundred randomly-rotated instances into two blocks as illustrated below.

Figure 1. Local wind example scene setup

The left block (closer view below) uses a standard wind approach with the directional wind source blowing from top to bottom of the screenshot. Because every tree is uniquely randomly rotated and a noise offset is used in the wind system, every tree is uniquely animated even if they’re blowing in the same direction.

Figure 2. Close-up of standard wind block

The right block (closer view below) uses a single point wind source, represented by the white sphere in the center. It also illustrates the decay option where the wind strength lessens the further the tree instance is from the source. Each instance still uses the noise offset, so they appear to separately “pulse” away from the wind source.

Figure 3. Close-up of local wind block

When running the local forest example in the reference application, use the number keys to jump to different preset cameras that show different views of each block of trees.