2

I have a comp... one null with an expression slider and the rest are image layers. the null with this expression, controls a random animation of the images beneath the null:

Math.abs(Math.round(wiggle(4, thisComp.numLayers-2)))+2

each image layer has this expression attached to the opacity:

if (thisComp.layer("Control").effect("Slider Control")(1) == index) 100 else 0

it all works great BUT...

say I duplicate that random comp 20 times... but matte each duplication with a separate puzzle shape. thus giving me a puzzle comprised of the 20 shapes all spiting out a random frame from that comp. How do I make the twenty duplications behave random of each other? at the moment, they are all random in unison.

cheers

r

3

The random number generator in AE seems to be linked to the layer index, but generates the same results for every composition. To demonstrate here's a comp with a shape layer where the vertices of the shape are generated by the wiggle() function:

enter image description here

Here's the expression:

var newPath = [];
for (var i=0; i<=160; i++){
    x = i*thisComp.width/160;
    y = transform.position.wiggle(1, 100, octaves = 1, amp_mult = .5, t = i)[1];
    newPath[i] = [x,y];
}
createPath(points = newPath, inTangents = [], outTangents = [], isClosed = false)

if I duplicate that layer in the same comp I get two different paths (I've given each a different colour, but the expression is the same):

enter image description here

If I add layers to the comp before the shape layer, so that the shape layer's index changes this also changes the shape of the path. You can also explicitly set the index of the layer generating the wiggle, e.g.:

var i = math.floor(effect("Slider Control")("Slider"));
var w = thisComp.layer(i).transform.position.wiggle(1,2);

So the index of the layer is used to generate random values for the wiggle() function. Quod erat demonstrandum.

This means that if I duplicate my comp, each duplicate comp produces the same result. Here I've duplicated the original comp three times and brought them into another comp. I've offset each layer a little on the Y axis so you can see them all:

enter image description here

So you can see that the wiggle() function is deterministic, and produces the same results for the same layer index across different comps. This is the problem you're experiencing.

Fortunately there is a way of overriding the seed for the random number generator. That's the seedRandom() function. It's more commonly used for the random() and gaussRandom() functions, but it works for wiggle() and noise() too. The seedRandom() function takes two arguments, the first being a number, which seeds the random number generator, and the second a boolean which set whether the random number generator changes with time or if it stays the same. If you use the same seed the generator will always produce the same results, so usually on a layer you use the layer's index to set the seed. Since that won't work we can seed it with a unique number, derived from the comp's name.

Here's the same comp with the three subcomps, only this time I've added the line

seedRandom(thisComp.name[thisComp.name.length -1], timeless =true);

before the wiggle() function. The term thisComp.name[thisComp.name.length -1] returns the last character of the comp name. And since my comps are called comp 1, comp 2 and comp 3 it returns the characters "1", "2", and "3". Since javascript is loosely typed, these characters get cast to ints for the seedRandom() first parameter, meaning that when I duplicate the comp I automatically get a unique random seed (I'd have to use regex or get the Ascii values of the letters or something if there were more than one digit, and it would break if I renamed the comps). Here's the final comp now

enter image description here

Interestingly adding the seedRandom() for the first layer also effected any other layers in that comp. So if the first layer has a random seed based on the comp name, other layers using wiggle() will now get identical results. So overriding the random number generator is global within the scope of each composition (I just learned this). Here's the second comp, but with seedRandom() on the first layer (red), but not on the second layer(green) offset 1 pixel for visibility:

enter image description here

to avoid this gotcha, you can add back the index to the random seed:

seedRandom(index + thisComp.name[thisComp.name.length-1],timeless = true);

TL;DR

if your comps are named comp 1, comp 2, comp 3, etc., adding this line to any layers with a wiggle expression will generate unique wiggles:

seedRandom(index + thisComp.name[thisComp.name.length-1],timeless = true);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.