racer home

Waving flags for tracks


Home Animation makes your track more dynamic. gt500

Dolphinity Organiser - free planning, project management and organizing software for all your action lists


Racer v0.8.3 added 2 new Cg shaders; standard_wave_v.cg and standard_wave.f.cg. For basic information on Cg shaders, check the GPU shader page. The shader can be used to get a wavy effect which is especially suited for flags.

The image below shows an animated flag, which is based on a static flat flag.

waving flag

Creating the flag - shaders & model

Create a 3D flag model in your favorite 3D modeler (3D Studio Max is preferred, using ASE as the output format). Your flag may have 2 materials for example: the pole and the cloth. For the cloth, the lateral texture coordinate is important; the laterla (U) coordinate is used to scale the flag deformation. So to keep the flag attached to the pole, make sure that is the place where U=0. Near the far end of the flag, U becomes 1, so there you get the maximum wave amplitude.

To be able to wave gracefully, make sure you tesselate the flag; only the vertices will have a sine-wave applied so if you make the flag to coarse, the polygons will show. See also the screenshot below of a tesselated flag model.

Next, in the track's track.shd file, create a shader for the cloth part that references the wave Cg shaders. It is often beneficial to split the shader in a Cg part and an actual shader part, so that you can share vertex/fragment Cg shader usages for multiple shaders.

shader_flag~vf_wave_flag { cull=none ; Amount of wave (v0.8.15+) scale=0.7 layer0 { map=holland.tga depthwrite=0 } }

The image below displays the flag after running the script command 'wireframe on'. Notice the tesselation. Also notice the subtle effect of the flag being squeezed a bit vertically at the end part, which looks a bit more realistic.

waving flag wireframe


The standard_wave_v.cg shader is meant for horizontal flag. A vertically (hanging) flag will need a slightly modified shader. Also, a banner, tied between 2 poles, will require a slightly modified wave shader as well. That is future work.

Hardcore information

You can skip this section, unless you want to understand the technological background a bit better.

The following wave pattern is used inside the standard_wave_v.cg shader (found in data/render/shaders_hdr/ or shaders_ldr/). It may change without notice just incase I find a nicer way, or tweak the frequencies etc, but the idea stays the same.

float3 Wave(float time,float3 pos,float2 uv)
// Returns world offset based on time and texture coordinates
  float3 off;
  float sinOff=pos.x+pos.y+pos.z;
  float t=-time*3;
  float sin1=sin(t*1.45+sinOff);
  float sin2=sin(t*3.12+sinOff);
  float sin3=sin(t*2.2+sinOff);
  float fx=uv.x;
  float fy=uv.x*uv.y;
  return off;

The wave uses 3 sine curves, each with varying frequency to give a somewhat natural look. The 'sinOff' variable is used to create a phase difference between objects in a different place. It takes the world location of a vertex and adds that to the sine input. So 2 flags close to eachother will have a different wave pattern.

The fx & fy variables are the influences based on the UV coordinates. Close to the pole, uv.x (U) will be close to 0 so little deformation results (fx~0). The fy is used as a vertical influence; depending on both U and V means its effect will be greated at the top of the far end of the flag. This is used in the Y (vertical) direction to squeeze the flag vertically a bit.

Waving banners

Banners are mostly the same as flags, but they keep their edges intact and only wave the inside part. Racer v0.8.11 adds standard_wave_banner_v.cg which you can use for banners. The rest stays the same. See below for Swiss Stroll's starting banner with this shader applied (and standard_transparent_f.cg for the fragment shader).

waving flag racer


Dolphinity Organiser - free planning, project management and organizing software for all your action lists

(last updated November 13, 2012 )