Activity › Forums › Adobe After Effects Expressions › Time Remap controlled by SampleImage
-
Dan Ebberts
July 9, 2012 at 4:41 pmI can generate the error immediately in AE CS5, but not in CS5.5 or CS6. I don’t know what the problem is, but it looks to me like they may have fixed it.
Dan
-
Arne Münch
July 10, 2012 at 12:51 pmHi guys
For those who have older versions, here is what I ended up with and I am quite satisfied:Instead of writing the expression into “timeremap” I used the effect “timewarp” which also has an option for “source frame”. For this I wrote Dans expression, (but without the Math.round for smoother results.)
L = thisComp.layer(“luma”);
p = L.fromComp(toComp(transform.anchorPoint));
s = L.sampleImage(p,[.5,.5],true);
luma = rgbToHsl(s)[2];
maxFrame = 300;
f = maxFrame*luma;
framesToTime(f)The one problematic difference is, the effect time warp doesn´t look in-between frames in the nested comp, like “time remapping” does, so you will not have the same smoothness, but here is a little trick:
Just use “time-remapping” as well without any expression, and give it a lot of space. For example if your nested comp is 30 Frames long, span this 30 Frames with time Remap over a space of 300 Frames, so the “Time Warp” effect has a lot of real in-between Frames, (not calculated ones through FrameMix or PixelMotion).
Give it a try.. -
Jay Ingles
March 17, 2018 at 7:13 pmThanks again for previous input, I’m back with an evolved version of this technique.
Imagine there is a dancer with 6 main poses/dances and based on opacity of a base layer we want to transition to a different dance.
In the end this will be a grid wall of dancers. Up until now the thread above allows switching to a SINGLE frame based on an alpha via SampleImage, but doesn’t allow that new frame to keep playing out (and looping).
How would I modify the code to achieve this? The dances could be all in one main composition and we jump to a specific range of the sequence, OR a separate shorter comp for each dance (which loops).
12262_dancergrid.aep.zip – example setup
Thanks!
L = thisComp.layer("luma");
p = L.fromComp(toComp(transform.anchorPoint));
s = L.sampleImage(p,[.5,.5],true);
luma = rgbToHsl(s)[2];
maxFrame = thisComp.layer("ref").effect("# Frames")("Slider");
f = Math.round(maxFrame*luma);
framesToTime(f) -
Dan Ebberts
March 17, 2018 at 7:56 pmThe problem is, I think, that for this to work, the expression would need to figure out how long the luma has been at its current value. To do that, it would need to work backward in time, frame-by-frame (using the time parameter of sampleImage()) looking for a change in luma. And that would only work well with step changes in luma–fading wouldn’t work well. Not impossible, but tricky to set up and maybe cpu intensive if the loops get long.
Dan
-
Jay Ingles
March 17, 2018 at 9:11 pmHi Dan, thanks for the quick reply.
Assuming all ‘dance scenes’ are the same duration (lets say 100 frames), would it not be able to do the following…
If base luma = 30%, jump to frame 300 & start playing for 100 frames
if hit frame 399 reverse frame playback.
check on each new frame if base luma has changed, if not continue playing next frameSeems like its getting complex, but is it feasible? I was really hoping to achieve this in C4D with effectors but haven’t been able to get that working. It may turn into manually placing/timing each quadrant ☹
Thanks again for any input.
-
Dan Ebberts
March 17, 2018 at 9:15 pmSure, if you can make that assumption so that you can calculate the current elapsed run time based on the luma level, that makes it pretty straightforward.
Dan
-
Jay Ingles
March 23, 2018 at 3:38 pmThanks again for your input. I tried to merge 2 portions of code which uses the sampleImage and based on that result triggers a playback. The code is pseuodo code i suppose.
I know i’m missing something especially with regard to getting the scene to play and increment frames once it understands what scene to playback.
Where am I going wrong?
//previous sample image based on layer position
L = thisComp.layer("luma");
p = L.fromComp(toComp(transform.anchorPoint));
s = L.sampleImage(p,[.5,.5],true);
luma = rgbToHsl(s)[2];
//maxFrame = effect("# Frames")("Slider"); //erase?
//f = Math.round(maxFrame*luma); //erase?//Define "trigger" from our sample results
trigger = luma;//Define how many scenes in the precomp and how long each will play for
SceneCount = 10; //slider ... how many areas to playback
SceneDuration = 100; //length of each scene in framesif (trigger == 10){ //start playback at scene 10 which is frame 100
frame = (trigger*SceneCount) ++; // Start playback at frame 100 if luma = 10%}else if (trigger == 20){
frame = (trigger*SceneCount) ++; // Start playback at frame 200 if luma = 20%
}}else if (trigger == 30){
frame = (trigger*SceneCount) ++; // Start playback at frame 300 if luma = 30%
}t = Math.min(t, tMax);
//t = frame * thisComp.frameDuration;
framesToTime(t); -
Dan Ebberts
March 23, 2018 at 5:26 pmI think the issue is still the same. The expression has to be able to calculate how long ago the current luma value was first reached. I’m thinking again, that you’ll have to do this by looping back in time, frame by frame until you find when the luma was a different value.
Dan
-
Jay Ingles
March 24, 2018 at 11:46 amThat’s too bad, but thanks for explaining it.
Do you have any suggestions on how to achieve something similar visually? IE Initiating layer to play in a more automated way OR working with Markers in a more graphic way? There are lots of scripts to choose from but they mostly just appear to slide layers (or markers) on exponential or linear curves.
My only approach I can think of is using your “trigger by markers” approach on 1 horizontal line, then precomping 1 row, repeating, and offsetting all layers.
Unfortunately this largely restricts actions what type of patterns can be created and is quite laborious.
: / -
Jay Ingles
March 24, 2018 at 1:38 pmFound a massively useful tool! Sharing should others look for this effect:
https://aescripts.com/ae-shader-effector/
Reply to this Discussion! Login or Sign Up