home about gallery publications education links contact

..::raindrop ripples::..

Rain or water affecting a surface is normally a case for some fancy fluid dynamics system such as Next Limit’s excellent set of fluid systems, which generates fluid surfaces using particles and geometry deformation, but even though the solution is extremely effective, it costs money. So what free alternatives have we got?

The best method to create ripples on a surface would be to physically deform the geometry itself to generate the ripples. However, manually placing God knows how many modifiers or Space Warps, then offsetting their animation would be a nightmarish task! So what other solutions do we have?

Apart from scripting a deformation solution, our best bet would be material based, either by using bump mapping, geometry displacement or displacement mapping using an animated sequence. We can control this a lot easier than manually editing every single ripple, and the entire effect can be assigned to the entire surface and/or the entire scene if needs be. Creating an individual ripple isn’t a problem – we can simply animate an object with a ripple displacement texture assigned to it, but to create hundreds or thousands seems like another monstrous task. Not so. As we’re using materials, we can apply this material to an object and then scatter it across a surface to generate the animated map.

The material itself would be a simple radial gradient with a steep crest (but only set to 50% intensity) and feathered-out tail. The lack of full intensity allows us to use additive transparency, which will when two waves combine, the result is a more intense wave (ie higher displacement) at these areas.

The bets way to create such an effect would be to use a particle system – it has a random distribution and an object’s animation (not material animation) can be offset to the birth of the particle. This means that when the particle is born, the animation of the instanced geometry for that particle begins to play. Hence, we can set up a scale of the object with the ripple map assigned to it, and the result would be each “ripple” (with a slight percentage variation) starting small and growing outwards! As the wave needs to fade out with age, using a Particle Age map to mask the gradient out more as the particle gets older. However, Particle Age does not work when the material is assigned to the instanced geometry, then the particle system sourced it’s material from the instanced geometry; it has to be directly assigned to the system itself for it to work.

As we only want our ripples to be applied to a surface to create our animated texture map, we need the result of a particle hitting a surface. For this, we can use particle spawn, namely “Spawn on Collision”. This allows us to generate a new particle when the original collides with a deflector Space Warp that has been assigned to the particle system. Because we only need to see the spawned particles, we do not need to see the original geometry type (which also has to be instanced geometry). Therefore we can create a null object using a Geosphere, then add a DeleteMesh modifier to remove all polygons. Therefore when rendered (and when working in the Viewport) the original particles will not be visible, but the spawned ones will!

We can also create the initial splash displacement by cloning the particle system and plane geometry and assigning a new material to the particle system to create a small white dot when the particle is born, which then quickly fades out. As we do not want the particle to scale this time, we can simply remove the cloned plane’s keys and set a size that suits us, and replace the first plane with the clone in the new particle system’s Object Mutation Queue.

Rendering the animation out is a simple procedure. You may want to increase the amount of particles, speed of the ripple (it is slightly slow in the tutorial opposite to emphasise the ripple animation when assigned to an object), turn on supersampling or increase the size of the rendered animation to create a better quality result when the animation is applied as a bump or displacement map.

And there we have it. Okay, it’s not all that effective at very close quarters, but on a large scale, especially with animated wind methods (see tips column) the resulting effect can be made to look quite convincing.

Enlarge Screenshot Create a Plane primitive in the top viewport and set it’s length and width sizes to 0. Animate the length and width sizes to 600 over 100 frames. Create a new material, label it “Puddle” and enable Face Map. Set Diffuse and Self-Illumination colours to white, and additive transparency. Create a Mask map in the Opacity slot and add a Particle Age map to the Mask’s Mask slot. Set Colour 1 to a mid-grey, Colour 2 to a darker grey and Colour 3 to black. In the Mask’s Map slot add a Gradient Ramp map and use the settings as illustrated.
Enlarge Screenshot Create a Deflector Space Warp and set it’s Length and Width spinner settings to 10000. Set the Bounce to 0 and increase the Friction to 100. This will ensure that the particles do not move once they collide with the deflector, and that the spawned particles remain stationary.
Enlarge Screenshot Create a Geosphere (or any other geometry – it doesn’t matter as it’s just a placeholder to be deleted) in the top viewport and set it’s radius to 10 with 1 segment and set the base type to Icosa. Add a DeleteMesh modifier to the stack.
Enlarge Screenshot Create a Blizzard particle system 8000 wide by 8000 long and place it above the Deflector (approx 1300 units). Assign the Puddles material to it. Set up the particle system as illustrated. Bind the particle system to the deflector. As we only want the particles to be visible when they collide with the deflector, we enable particle spawning on collision, and with Animation offset keying set to Birth, the plane’s animation is offset when the deleted Geosphere particle hits the plane!
Enlarge Screenshot Copy the Puddles material and label the new one Splash. Set the Particle Age map’s colours to Black, Mid-Light grey, Black for colours 1,2 and 3 respectively. Set Colour 2’s age spinner to 5 and Colour 3’s to 30. Clone the Plane and Particle system and assign the new Splash material to them. Select the new plane and delete the keys at frames 0 and 100. Set the length and width sizes of the new plane to 600. In the new particle system, replace Plane01 with Plane02 in the Particle Spawn Object Mutation Queue.
Enlarge Screenshot Finally, centre the top viewport over the particle systems and set the Render Output Size to 640x640. You may wish to enable Show Safe Frame in the viewport’s options menu – this will help you centre the particle systems easier.
Enlarge Screenshot The generated animated bump map has been applied to the sea’s surface. The original scene is from a previous Q&A, in issue 24.
Download the max file! Zip file to accompany.


Unfortunately the resulting map does not tile or loop. However, this should be relatively simple to sort out. By offsetting the animation in AfterFX (or equivalent) or creating 4 copies, we can move the seam to the centre of the frame. Cloning elements of the original animation results in the seam being masked out. To rectify the loop problem, a simple yet effective additive or non-additive cross fade can be used to loop the middle part of the sequence so there are no abrupt changes in the sequence.

You would think that binding a wind spacewarp to the particle system wouldn’t effect the particle’s motion if it was positioned underneath the deflector spacewarp. Unfortunately, as we’re using particle spawn, it does, so to create an appearance of wind, we need to animate the position, rotation of the emitter and the amount of particles to give the impression of a wind blowing them across the scene. This will therefore affect the spawned particles positions at where they appear, which is the effect we are after.

As opposed to containing the initial splash and the ripple(s) in one animated map, try splitting them into two maps, so you can use bump mapping for the ripples and mesh displacement for the splash. However, extra refinement of the mesh will be required to effectively displace the geometry, or use displacement mapping.

As opposed to using one general animated map for a lot of scenes, you will most likely find that you want the actual rain particles to effect the splashes. In this case, you will have to create an animated map based on the surface of the geometry and re-apply that in a second pass render. A little extra work is involved, especially if the geometry is deforming, but worthwhile nevertheless.

Initially published: 3D World magazine, Issue 36, March 2003.

Copyright Pete Draper, March 2003. Reproduction without permission prohibited.