Announcement

Collapse
No announcement yet.

What are the do's and don't's of Lerp?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    What are the do's and don't's of Lerp?

    What are the do's and don't's of Lerp?

    Anyone with some good experience willing to share with us some ideas?

    #2
    Not much to it. Lerp is a linear interpolation between A and B, by the unit scalar Alpha. When Alpha is 0 the result == A, when Alpha is 1 the results == B. Any value between 0 and 1 is a blend between A and B.

    If you use a value < 0 or > 1 for Alpha then you enter the realm of extrapolation where the result is 'projected' beyond the two values.

    The actual internal code for lerp is, approximately:

    Code:
    function float Lerp( float A, float B, float Alpha )
    {
        return A + ( B - A ) * Alpha;
    }

    Comment


      #3
      Thanks Spoof. I know how Lerp works but I just can't find a good to way to determine the end of the interpolation:

      Code:
      var float current;
      var float target; // value is 20
      
      event Tick()
      {
          current = Lerp(current, target, alpha);
      
          `log(current);
      
          // first approach
          if(current ~= target)
             // this doesn't work well
             // when I watch the value of current in log it goes from 0 to 19 pretty quick but takes a little longer to go from 19 to 20.
      
          // second approach
          if(current >= target*0.98)
             // this works fine
      
         // third and my favorite approach
         if(current >= target-1)
            //works fine
      }
      Which one of the is the best approach? Or is there any better way to handle this?

      Comment


        #4
        The problem with using Lerp in such a manner (by feeding the result back into the equation) is that - theoretically - it can never end, at least until single precision error creeps in.

        This kind of feedback loop is more generally used for a system that doesn't need to end, such as animating a camera position to lag behind a player. The effect constantly interpolates with no need to check for completion.

        Also, you should be using FInterpTo instead of Lerp for this, as it will account for DeltaTime and give more stable results irrespective of client frame rate.

        There isn't really a definitive test either. You could perhaps improve your third approach by calculating a threshold as a percentage of the difference between start and target, Something like:

        Code:
        threshold = Target - ( Target - Start ) * 0.01; // 1%
        
        ......
        
        if ( current > threshold )
        {
        }

        A completely alternative method, and one I prefer, is to use time to control Alpha directly, using fixed values of A and B. This requires a little extra setup, but is completely deterministic, and automatically supports both delta time and time dilation effects.

        Code:
        var float StartTime, EndTime, A, B;
        
        
        function Go( float inA, float inB, float Duration )
        {
            A = inA;
            B = inB;
            StartTime = WorldInfo.TimeSeconds;
            EndTime = StartTime + Duration;
        }
        
        
        event Tick()
        {
            float t;
        
            t = ( EndTime - StartTime ) / ( WorldInfo.TimeSeconds - StartTime );
        
            if ( t >= 1 )
            {
                result = B;
                // TODO: stop the interpolation
            }
            else
            {
                result = Lerp( Start, End, t );
            }
        }

        This gives a true linear interpolation which is different to the smooth decelerating effect that you have from a feedback loop. To simulate such effects you can use the alternative interpolator functions FInterpEaseIn, FInterpEaseOut and FInterpEaseInOut, all defined in Object.uc with comments.

        One drawback of this method is that you don't get the same dynamic feedback effect as you do from using FInterpTo. If your 'target' value is changing each tick, such as tracking the player position for a camera, then a feedback loop using FInterpTo is better.

        You can also implement additional blending equations by adapting Robert Penner's equations.

        Comment


          #5
          What exactly are you trying to do?
          What is 'alpha' and how is it modified? Is alpha not a value expected to be clamped [0,1]?

          EDIT: I just read the above after my post. I agree with Spoof that you would usually a time parametric (t) instead of just passing in the alpha (this is where I was going with 'what is alpha and how is it modified'. And I usually use a Clamp() on t for [0,1] and then check if t is 1 to break out.

          Comment


            #6
            Thanks a lot Spoof for the informative post. I'm gonna look into that.

            Comment

            Working...
            X