When a bike races over a wet surface, its rear wheel sends a lot of water flying backward. Most goes up into the air as spray, but some shoots sideways across the road, creating a visible wake.
The spray part was easy. We had an efficient particle system, and were not afraid to use it!
The wakes used a similar technique to our skidmarks, but animated the geometry so they got wider and faded out over time. The CPU was responsible for recycling wake segments when they reached zero alpha, but the animation was done in the vertex shader, so the CPU cost was very low.
It wasn't always easy to tell where the wake ended and spray began. The sum of these two effects was greater than the parts:
But this broke down if you drove right behind another bike, inside its spray trail. When you got too close you could see the particle system was just a handful of point sprites. We needed some kind of volumetric fog effect to make the up-close-and-personal experience look good.
Have you noticed we were fond of abusing the fog settings? Yep, we did that here too :-)
float sprayAmount = currentCamera->HowCloseBehindAnotherBike();
if (sprayAmount> 0)
{
skyTint = new Color(sprayColor, sprayAmount);
fogColor = Lerp(regularFogColor, sprayColor, sprayAmount);
fogStart -= sprayAmount * TweakableIntensitySetting;
}
Is that not an evil hack?
But it worked surprisingly well. As you weaved your way through the pack, overtaking bike after bike, the screen would flash gray any time you got on the tail of the guy in front and picked up a face full of his spray plume. To make it even more convincing, we hooked this up so the droplet effect would splatter a load of new raindrops on your camera lens at the same time. But that's getting ahead of myself...