Trigger expressions by luminance of another layer?

Moderators: Disciple, zlovatt

Post Reply
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

November 22nd, 2011, 8:06 am

I have two layers, layer1 is a black and white image that animates, and the second layer is a simple solid with a wiggle expression on rotation. The black and white layer should not be visible. Is there a way to trigger the expression of the second layer by the luminance of the first layer? In other words, can I sample the solids position, and if the above layer has white in the same area, trigger the expression, otherwise turn it off. Could you use sampleImage for this?
blindchild
Posts: 14
Joined: February 8th, 2009, 2:19 pm

November 22nd, 2011, 5:25 pm

I'll give it a shot.

As far as I can remember you need to convert the rgba values from sampleImage to hsl (hue, saturation, luminance(or is it lightness?). And then you can read that value. Something like:

Apply this to the solid:

target = thisComp.layer(index -1);
lum = rgbToHsl(thisLayer.transform.position),[2, 2]))[2];

As far as I can tell this will use the solids position and read the pixel value within a 2px 2px sample area of the layer above.

Then add an if statement to turn it on and off.

Hope that helps.
Dan Ebberts
Posts: 319
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

November 22nd, 2011, 8:50 pm

This should work:

Code: Select all

freq = 1;
amp = 25;
sampleSize = [10,10];
L = thisComp.layer("Your Black and White Layer");
P = L.fromComp(toComp(anchorPoint));
lum = rgbToHsl(L.sampleImage(P,sampleSize/2,true,time))[2];
wiggle(freq,amp*lum)

Dan
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

November 23rd, 2011, 12:28 am

Very cool, thanks Dan. I didn't even think this was possible with expressions, I just thought I post it anyway. This is super cool! I will try to decipher your code. One thing though, in the current state the wiggle jumps back to "0" once the white area leaves the sample region. Would it be possible to let it continue it's wiggle? That way the control layer would trigger the animation only.

Also, thanks blindchild, I will take a look at your suggestion as well :).
Dan Ebberts
Posts: 319
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

November 23rd, 2011, 12:57 am

I assume that you would want the wiggle to match the amplitude it had right before it went off the edge. That wouldn't be simple, because I think you'd have to loop back frame-by-frame to find that event. Do-able, but not simple.

Dan
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

November 23rd, 2011, 2:12 am

Well, the wiggle was actually just an example, what I really want to do is:

The solid is a 3D solid that is rotated 90 degrees in Y at start. At the moment the sample expression find white on the control layer, I want the solid to rotate to 0 degrees on Y over 1 second and then stay at 0 throughout the shot. Maybe I should have clarified that from the start, my mistake.

Will that make it easier in any way?

Thanks.
Dan Ebberts
Posts: 319
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

November 23rd, 2011, 7:22 am

It's pretty much the same issue. In this case, you'll have to start at the In Point and move forward, frame-by-frame, to find how long it has been since the first occurance of the luminance event you want to trigger the rotation. sampleImage() has a time parameter you can use for this. It will look something like this (not tested so there may be typos):

Code: Select all

sampleSize = [10,10];
L = thisComp.layer("Your Black and White Layer");
P = L.fromComp(toComp(anchorPoint));
t = inPoint;
while (t < time){
  lum = rgbToHsl(L.sampleImage(P,sampleSize/2,true,t))[2];
  if (lum > .95) break;
  t += thisComp.frameDuration;
}
t2 = Math.max(time-t,0);
linear (t2,0,1,90,0)

Dan
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

November 23rd, 2011, 8:50 am

Thanks for your reply Dan. I did se a pop where it tried to change its rotation value from 90 to 0, but it seems like it's constant at 90 degree. Unfortunately my expression skills aren't at this level at the moment so I can't see what's wrong. Really cool though that this is possible, it could be used for a lot of interesting animations. But I guess it would be pretty slow if you use it on several layers, since it needs to loop through each frame on each layer?
Dan Ebberts
Posts: 319
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

November 23rd, 2011, 6:58 pm

My mistake. The calculation of P needs to include the time element as well:

Code: Select all

sampleSize = [10,10];
L = thisComp.layer("Your Black and White Layer");
t = inPoint;
while (t < time){
  P = L.fromComp(toComp(anchorPoint,t),t);
  lum = rgbToHsl(L.sampleImage(P,sampleSize/2,true,t))[2];
  if (lum > .95) break;
  t += thisComp.frameDuration;
}
t2 = Math.max(time-t,0);
linear (t2,0,1,90,0)
Dan
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

November 24th, 2011, 6:12 am

That works perfectly. Thanks alot Dan, you're a genius!
Post Reply