Random layer position constrained by another layer's alpha
by Chris Coleman (finder0)
on
Jan 6, 2008 at 3:51:13 am
I am trying to create a 2.5D landscape with several hundred layers randomly positioned all over the landscape. I see how to have the position be random, but is there a way to limit the positions to only within the "island" of the landscape as defined by its alpha channel? This is something simple to do with trapcode's particulate, but i need the shadows cast onto the ground and thats where trapcode is failing me.
thanks
Re: Random layer position constrained by another layer's alpha by Mike Clasby on Jan 6, 2008 at 6:26:45 am
This modified Dan Ebberts' expression is a good place to start. It goes on Position.
minX = 0;//Minimum x depth value
maxX = 500;//Maximum x depth value
minZ = 0;//Minimum z depth value
maxZ = 1000;//Maximum z depth value
op = thisComp.layer("opLeader").opacity;
seedRandom(index, true);
x = Math.round(random(opX));
z = Math.round(random(opZ));
[x, position[1], z]
Change the min/max X and Z as needed. All the Y's are the same, I'm assuming you have a Floor if you want to cast shadows, so you Y needs to be at (or near) the Floor.
Re: Random layer position constrained by another layer's alpha by Chris Coleman on Jan 6, 2008 at 7:29:42 am
close, but I think the opacity is one value for the entire layer. Is there an attribute than can look at the alpha channel at any given point? It is an illustrator file layer serving as the island map, and i want to make sure the trees randomly place themselves on the land. ( I did try your suggestion but to no avail. Thank you for puzzling thru this with me.
I think if you combine this position expression from Colin:
minX = 0;//Minimum x depth value
maxX = 1000;//Maximum x depth value
minZ = 0;//Minimum z depth value
maxZ = 2000;//Maximum z depth value
seedRandom(index, true);
x = random(minX,maxX);
z = random(minZ, maxZ);
[Math.round( x), position[1], Math.round( z )]
With an Opacity expression that is 100 when there is a Collision Detection, and 0 when not, from Dan's page:
But I don't have AE CS3 or the expression finesse to do it.
Alternatively, you could just use Colin's Position expression above, with the min/max set to hit the island, and then turn off the eyeballs of all trees landing off-island, and shy them so they don't clutter up the stack. That way no collision detection necessary... er, actually you would be performing the collision detection, manually.
Re: Random layer position constrained by another layer's alpha by Chris Coleman on Jan 6, 2008 at 8:44:42 am
Hmm. You have provided some good clues. I see where the two for loops in the collision test could look for the alpha. I am curious tho that if I turn off the opacity of the off island trees manually or with this script, will it still tie up processor time? I am looking to add 1000-2000 of these trees add if I am paying for the invisable ones, it would suck render time. Can an expression turn off the visibility switch or should I try to force a new seed for any tree that lands in the water?
(I never feel like I am accomplishing anything unless I am pushing AE to its limits, hehehe)
Re: Random layer position constrained by another layer's alpha by Darby Edelen on Jan 7, 2008 at 6:07:19 am
The way I would approach this is by looping through random points on the layer, sampling its alpha and stopping the loop when the sample point is over a threshold of alpha value.
I should note that I haven't error checked this code at all, I don't have AE on this computer so I'm writing this from memory (and the online documentation) =)
l = thisComp.layer("Island.psd"); //The 'island' layer
w = l.width; //The island layer's width
h = l.height; //The island layer's height
thresh = 0.9; //Threshold for alpha value on the island layer
seedRandom(index, true); //Seed our random numbers and don't update them based on time (timeless)
p = random([0,0], [w,h]); //'p' is a random point in the layer space of the island layer
alpha = l.sampleImage(p)[4]; //The alpha value at the point 'p' on the island layer (values range from 0-1)
//While the alpha value is below our threshold...
while(alpha < thresh){
p = random([0,0], [w,h]); //Pick a new random point on the island layer
alpha = l.sampleImage(p)[4]; //Update the alpha value at the point
}
l.toWorld(p); //Transforms the point 'p' from layer space to world space
This will return a point in 3D space that should correspond to a random point on the island layer that has an alpha value greater than or equal to 0.9 (0 is fully transparent, 1 is fully opaque), so make sure you have your anchor point on your tree layer set to the base of the trunk (where it will meet the island) and apply this expression to each tree's position property.
Let me know if there are problems with this code, I can check it tomorrow for errors.
Darby Edelen Designer Left Coast Digital Santa Cruz, CA
Re: Random layer position constrained by another layer's alpha by Darby Edelen on Jan 7, 2008 at 6:18:41 am
Also, I thought I would note that this code will take additional processing as the random points 'miss' the island, so you should do your best to extend most of the island right out to the boundaries of the layer. If the alpha of the island is only opaque over 50% of the layer then on average (with large numbers of trees) it will require twice as much processing per frame as if the layer were entirely opaque.
Darby Edelen Designer Left Coast Digital Santa Cruz, CA
Re: Random layer position constrained by another layer's alpha by Chris Coleman on Jan 7, 2008 at 6:48:16 am
I am getting tolerable render times, with about 5 seconds per HD frame for 600 trees so far....thanks for the extra tips. The times are not too different from what I was getting with particular, so I cant complain.
Re: Random layer position constrained by another layer's alpha by Chris Coleman on Jan 7, 2008 at 6:30:54 am
Perfect!
That fixed all of my issues! Only mistake you made from memory was that the alpha is #4 in the array and so you have to use [3].
It only took a day and night of beating my head against the wall and some generous help. I have learned more about expressions doing this damned problem....
Thanks again!
Re: Random layer position constrained by another layer's alpha by Darby Edelen on Jan 14, 2008 at 5:10:48 am
I thought I'd take some time out to let you know that I used a variation of this expression on a recent project. I decided that the toWorld() function wasn't the best idea, since if you rotate the layer that the trees are supposed to be attached to they will remain upright in world space (they don't rotate with the 'island'). Instead I decided that it's best to leave the point in layer space and parent the 'tree' layers to the 'island' layer.
Here is the updated expression:
if(hasParent){
l = parent; //The parent of this layer (the 'island')
w = l.width; //The island layer's width
h = l.height; //The island layer's height
thresh = 0.9; //Threshold for alpha value on the island layer
seedRandom(index, true); //Seed our random numbers and don't update them based on time (timeless)
p = random([0,0], [w,h]); //'p' is a random point in the layer space of the island layer
alpha = l.sampleImage(p)[3]; //The alpha value at the point 'p' on the island layer (values range from 0-1)
//While the alpha value is below our threshold...
while(alpha < thresh){
p = random([0,0], [w,h]); //Pick a new random point on the island layer
alpha = l.sampleImage(p)[3]; //Update the alpha value at the point
}
[p[0],p[1], 0]; //Returns the point 'p' in the layer space of the parent (island) layer
}
else value
If the layer does not have a parent then it defaults to its keyframed values. Once the layers are parented to a layer you can rotate that layer and the layers will behave as you would expect.
Darby Edelen Designer Left Coast Digital Santa Cruz, CA