Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Camera Force Field?

  • Camera Force Field?

    Posted by Phil Aupperle on January 29, 2015 at 8:23 pm

    I have a project where the 3D camera is flying through a ton of layers in Z that are distributed randomly. I’d love to come up with an expression that would push them away from the camera axis as the camera approached so it wouldn’t go through any of them, like a forcefield. The thing I have no idea how to tackle is getting the layers move away from the camera axis radially, so if a layer is offset from the camera axis to the upper right, it would move farther up and to the right by an adjustable factor as the camera approached. Does that make sense? Like snow in the headlights at night…

    I have an expression (below) that I’m using to control layer Z position, so the layers can “explode” toward the camera or suck back into the distance, so I’d love to be able to combine it with the forcefield effect above to prevent layers from hitting the camera as they go by.

    Thanks for the help!

    seedRandom(thisComp.layer("Cloud Control Keys").effect("Cloud Random Seed")("Slider"), true);

    var zDepth = thisComp.layer("Cloud Control Keys").effect("zDepth")("Slider"); // keyframe this value on Cloud Control Keys layer

    var z_offsetFactor = thisComp.layer("Cloud Control Keys").effect("Spacial Offset Factor")("Slider");

    var t_offsetRange = thisComp.layer("Cloud Control Keys").effect("Time Offset Range")("Slider")+1;

    var t_offsetShift = thisComp.layer("Cloud Control Keys").effect("Time Offset Shift")("Slider");

    var t_offsetRand = time + (random() * t_offsetRange) + t_offsetShift; //randomize time offset within range and add shift

    var z_TimeShifted = zDepth.valueAtTime(t_offsetRand);

    var zPos; //final z position result

    zPos = z_TimeShifted - (random() * z_offsetFactor); // all factors combined

    [position[0],position[1],zPos];

    //+ zDepth / (random value * offset range)

    //+ (time offset within random range)

    = zpos

    (position[0],position[1],zPos);

    Kevin Camp replied 11 years, 6 months ago 2 Members · 3 Replies
  • 3 Replies
  • Kevin Camp

    January 29, 2015 at 11:24 pm

    I think the OP in this thread was going for a similar effect:

    https://forums.creativecow.net/thread/227/28555

    Kevin Camp
    Art Director
    KCPQ, KZJO & KRCW

  • Phil Aupperle

    January 30, 2015 at 9:28 am

    Ah, yes. Thanks for the link!

    Right out of the box that expression does almost exactly what I was looking for, except I need to restrict layer motion to XY so the layers don’t get pushed through each other in Z as the camera approaches.

    I fiddled around with it and have it almost doing exactly what I want, but the problem with my solution is that the layer now only moves a tiny bit before the camera gets to it. Experimenting with the controller variables makes me think I’ve messed up the easing somehow by taking out the Z motion.

    Thanks again for any input…I’m sure there’s a much more graceful way to do this!

    //Here's the original expression from the Colin Braley tutorial:

    avoidPos = thisComp.layer("Avoid Me").position;
    maxDisplacement = 85; //maximum amount to move the layer
    minDistance = 50; //minimum distance to begin displacing at
    //--
    vec = avoidPos - position;
    directionVec = normalize( vec );
    distance = length( vec );
    displaceAmt = ease( distance , 0 , minDistance , 0, maxDisplacement );
    displacementVec = displaceAmt * directionVec;
    position + displacementVec

    //This expression keeps the layer motion in XY, but doesn't work quite right.

    fieldPos = thisComp.layer("Avoid Camera").position;
    maxDisplacement = thisComp.layer("Controls").effect("effect force")("Slider"); //maximum amount to move the layer
    minDistance = thisComp.layer("Controls").effect("effect radius")("Slider"); //minimum distance to begin displacing at
    //--
    vec = position - fieldPos;
    directionVec = normalize( vec );
    distance = length( vec );
    displaceAmt = ease( distance , 0 , minDistance , maxDisplacement , 0 );
    displacementVec = displaceAmt * directionVec;
    [position[0]+displacementVec[0], position[1]+displacementVec[1], position[2]]

  • Kevin Camp

    January 30, 2015 at 7:13 pm

    i fyou don’t want the layers to move back to their original position, you’ll want to use colin’s second expression.

    i modified two lines to limit the moment to the xy plane and it seems to work (at least for my very basic set up)

    avoidPos = thisComp.layer("Avoid Camera").position;
    maxDisplacement = thisComp.layer("Controls").effect("effect force")("Slider");;
    minDistance = thisComp.layer("Controls").effect("effect radius")("Slider");
    //--
    finalPos = position.valueAtTime(0);
    oldDirectionVec = normalize([1,1]);
    for( i = 0 ; i <= time; i+= thisComp.frameDuration ){
       try{
          vec = finalPos - avoidPos.valueAtTime( i );
          directionVec = normalize( vec );
          oldDirectionVec = directionVec;
          distance = length( vec );
          displaceAmt = ease( distance , 0 , minDistance , maxDisplacement , 0 );
          displacementVec = displaceAmt * directionVec;
          finalPos += [ displacementVec[0] , displacementVec[1] , 0 ]
          } catch ( exception ){
             finalPos += [ oldDirectionVec[0] , oldDirectionVec[1] , 0 ] * displaceAmt;
          }
    }
    finalPos

    Kevin Camp
    Art Director
    KCPQ, KZJO & KRCW

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy