Loopable Chaos

I've been working on a Stargate (see a few pictures) and one of the primary problems is the open wormhole. It's supposed to look like a water surface. The problem is it takes too long to render all that detail. I wanted to make an image sequence and then use that as a simple texture on a single polygon. The sequence had to be long enough that viewers can't notice the loop yet short enough that it doesn't take up too much disk space or too much time to render out.

This tutorial will cover how to make an image sequence that can be looped, yet still present the illusion of ongoing chaotic change. It will be a tutorial, not a recipe. Some amount of your own creativity is required.

Lightwave comes with many different flavors of fractal noise, and animating that noise in some way is pretty easy. Let's start with an example. Start Modeller and create a rectangle that's perpendicular to the Z axis:

OK, save it. Load that into Layout. Open the surface editor and set Double Sided (not strictly necessary, but it saves us the effort of properly aligning the polygon to the camera). Change the surface color to black. Assign a procedural color texure, and pick one of the myriad fractal noise functions. Set the scale to something appropriate so you can see some level of detail. Set the procedural texture color to white and do a test render. You should see something like this:

If you were to render several frames, they'd all come out the same since we haven't animated it yet. Since the rectangle was built perpendicular to the Z axis, changes in the texture's Z position will provide the best illusion of random variation. Moving the texture's position along the X or Y axes will only give the illusion that the texture is sliding around and not really changing.

Go back to the texture editor and click the Position tab. Then click on the E button to the right of Z. The graph editor will open with the Z axis selected.

Decide how many frames the animation will last. Note that if you plan on using the Ripples texture in your mix of procedurals, it will dictate how many frames you should use. The wavelength divided by the wave speed gives you the number of frames before the texture repeats itself. Be sure to choose useful values here so that the division results in an integer! Or, if you're going to use multiple Ripples textures, use the least common integral multiple for all instances to determine the frame count.

I'm not going to use Ripples in my mix so I'm going to arbitrarily use 60 frames. At frame 60, create another key and assign it a value:

Render out frames 1 through 60 (not 0 to 60) and you'll get something like this (you will need Windows Media Player v9 to view). However, there's a problem. The last frame rendered isn't the same as frame 0 would have been (had we rendered it) and so it won't "lead in" very well to frame 1. In fact, the whole tail end of the sequence has no relationship with the front end of the sequence. Consequently, the loop has abrupt jumps in it.

The solution is to use the Oscillator motion modifier. Delete the key at frame 60 and then click on the modifiers tab. Add Oscillator and open its property page. Set it up like so:

Note that the cycle time is 2 seconds (I'm using 30 fps), so the whole cycle will last the 60 frames. Also note that the start of the cycle is frame 0, but we'll be rendering starting with frame 1. This way, mathematically, frame 60 is the same as frame 0, and it'll loop nicely. Here is the result, and here is the loop.

It's better, in as much as the sequence loops nicely. However, this isn't good enough. It looks like it's see-sawing. The sinusoid is ridiculously obvious. We need to add to this to get rid of those pauses where the texture turns around. Go back to the texture editor and clone this layer twice. Set the two top layers' blending mode to additive and set all three layers' opacity to something between 30 and 50 percent (otherwise it'll get all washed out). To maximize the effect, we need to move all three textures to different base x,y positions (exact location is pretty much irrelevant - just as long as they're not overlapping):

Now change the oscillator settings so that the first one has a phase of zero (it should have that already), the 2nd has a phase of 120 degrees, and the third has a phase of 240 degrees. Looking at just the Z axes will show this:

The important thing to note here is that while any one of the textures is at a crest or a trough, the other two are changing rapidly. You can use any number of texture layers, as long as it's an odd number. I'll leave it as an exercise to determine why using an even number isn't helpful. The phase values for each layer should be L*360/C, where C is the count of layers and L is the layer number. When we render this out, the noise should be devoid of any noticable pattern. Here is the result, and here is the loop.

So there you have it. Now you know how to make a small sequence of apparent randomness that will actually loop for you. Watch for movies of my stargate that exploit this technique. You can apply it to clipmaps, bump maps, deformation maps - anywhere you can use a procedural texture.

UPDATE - It occurred to me that this can be done with just two layers where one has a phase of zero, and the other has a phase of 90. Any other even number of layers doesn't buy you anything (again, think this through for yourself).

ANOTHER UPDATE - There's an even easier way to do this. See my new tutorial for accomplishing this with whole volumes here.