TIGSource Forums

Developer => Technical => Topic started by: iamwhosiam on April 01, 2011, 11:58:55 AM



Title: frame independent friction
Post by: iamwhosiam on April 01, 2011, 11:58:55 AM
hello,

I've been using this simple formula for friction...

----
friction = .7f;
velocity = 10.0f;

velocity *= friction;
----

It works ok for a fixed time step. But I'm hoping to make it frame rate independent. Does anyone know how to incorporate elapsed time into it?

any help much appreciated!


Title: Re: frame independent friction
Post by: Evan Balster on April 01, 2011, 12:07:24 PM
All right, but don't say you weren't warned.


So.  For accurate framerate-independent physics, you need to look at things in terms of continuous change.  If something is continuously changing your velocity, that means you need to make a corresponding calculation for your object's position, which is affected by a changing velocity.

Applying the friction is simple enough; figure out what percentage is lost per second and apply an exponent.  A per-second loss would be equal to a given per-frame loss taken to the power of the framerate, EG .95^30 for typical values.  Say we've called our per-second loss 'drag'.

Code:
velocity *= pow(drag, dt);

But properly calculating the new position is its own matter and requires calculus, incorporating this and any other continuous changes in velocity.  Doing things the naive way means your physics will work differently between high and low framerates, asymptotically approaching one distinct behavior towards 0 FPS and another towards infinite FPS.

So, the change in position is the integral from 0 to dt of (velocity * (drag^(x*dt)))dx.  Integrating by parts, we find it comes out to velocity * (1 / (dt*ln(drag))) * (drag^(dt*dt) - 1).

So we can do our per-frame physics like this, for an object with friction:

Code:
position += velocity * (drag^(dt*dt) - 1) / (dt*ln(drag));
velocity *= pow(drag, dt);


Now at this point I'm going to give you a warning and some advice.  If that integral was child's play for you, and you're very well-versed in calculus, go ahead and implement the framerate-independent physics.  If you don't care about simulation accuracy, or if your game completely loses its feel at low framerates, forgo the calculus and save yourself the headaches.  If, however, you are not a calculus whiz and *do* want a consistent gameplay experience, just go fixed framerate with your physics.

This is a very simple problem, and adding something like joystick-controlled acceleration greatly complicates it, much more than with a fixed-framerate system.  If you can figure out the same integral, but with an acceleration vector and exponential friction that compounds concurrent to the acceleration being linearly applied, the more power to you.  (If someone better at math than me can actually solve that problem and demonstrate how complicated it is, that would be wonderful!)

The simple facts are that stable framerates above 30 or 60 (!) are almost impossible to distinguish, consistent ones feel "faster" than higher, variable ones, and it's much easier to write the code, which has the added bonus of being deterministic so as to support simulation replay systems which are impossible to get right in variable-timestep systems without logging massive "keyframes" of every physical object in the sim.

Even professional tools like Unity do physics in a separate, fixed-framerate timeline to avoid these massive complications.  Incidentally, if you are using Unity, use FixedUpdate to compound friction, as this is what the physics engine is using.


As a last note, despite the prevalence of 60-120 FPS filming equipment, professional films are still shot (or CG-animated) and aired at the NTSC rate of ~25 FPS.  Why?  Because higher framerates (say, 60) in film are widely perceived by audiences as being of lower quality.  It's speculated this is because home camcorders shoot at these higher framerates, creating an association with "cheapness".  It's also speculated as a reason videogame cutscenes tend to come off as "hokey".


Title: Re: frame independent friction
Post by: Zaphos on April 01, 2011, 12:11:39 PM
This might be interesting/relevant to you: http://gafferongames.com/game-physics/fix-your-timestep/


Title: Re: frame independent friction
Post by: Glaiel-Gamer on April 01, 2011, 12:21:59 PM
velocity *= pow(friction, deltatime)


^^^^ the simple answer

IMO I prefer keeping a fixed timestep and just calling "update" a few extra times if its running too slow. Closure runs at 120 Hz, so it usually does 2 updates per frame if it renders at 60. It's easier in general since you don't have to worry about collision skipping if a frame takes too long and whatnot.

If you want to be able to do bullet time effects or whatnot, ya you probably have to use a timestep.


Title: Re: frame independent friction
Post by: iamwhosiam on April 01, 2011, 12:35:10 PM
yeah, i mean thats exactly why i was thinking of turning off the fixed time step cause I had the game locked at 60 and the actual frame rate fluctuates from 45 to 60 causing the game to sputter then speed up totally ruining the whole "fixed time step" thing.

edit: that seems like a good way to go though, thank you!


Title: Re: frame independent friction
Post by: Evan Balster on April 01, 2011, 12:47:02 PM
Yes, frameskip is a better idea.  A much better idea.

<_<


Title: Re: frame independent friction
Post by: Glaiel-Gamer on April 01, 2011, 12:48:23 PM
yeah, i mean thats exactly why i was thinking of turning off the fixed time step cause I had the game locked at 60 and the actual frame rate fluctuates from 45 to 60 causing the game to sputter then speed up totally ruining the whole "fixed time step" thing.

edit: that seems like a good way to go though, thank you!

Oh fixed timestep requires you to keep track of 2 counters. 1 what frame number the game "should be" at ((currenttime-starttime)/16.66) and then a timer that increments every time you update. You update until they match (or are close enough), then you render. This is, of course, assuming your rendering is the bottleneck and not the updating.


Title: Re: frame independent friction
Post by: Evan Balster on April 01, 2011, 12:50:53 PM
You may or may not have noticed the giant treatise on framerate-independent physics and why they are bad I edited in above (http://forums.tigsource.com/index.php?topic=18807.msg538318#msg538318).

>_>


Title: Re: frame independent friction
Post by: Triplefox on April 01, 2011, 12:52:05 PM
Don't go variable timestep if you can - you'll introduce a calculus problem because then your integration appoximations drift in accuracy based on the framerate. You can use better integration approximation(e.g. RK4) but it's not ideal.

Instead, run two timesteps.

If rendering is faster than physics, rendering can interpolate.
If physics is faster than rendering, physics can run an accumulator loop to do as many steps as are necessary to catch up to a "real" time approximation.

When doing this, average your delta-time over a few frames to avoid spikes, and add lower and upper limits so that the game remains playable at the extremes of low/high framerate.

Edit: beaten, and I was less verbose too >.>


Title: Re: frame independent friction
Post by: iamwhosiam on April 01, 2011, 01:09:16 PM
o im so glad i asked this question. I learned sooo much just now lol definitely going back to the fixed time step. And ill implement it correctly now.

thank you all very much!!

note: im using openframeworks not unity :)


Title: Re: frame independent friction
Post by: Draknek on April 02, 2011, 03:58:25 PM
* Redundant vote for keeping it fixed-framerate.

I've never implemented render-interpolation, it's always seemed like a lot of work for not much gain (assuming render time > update time). Has anyone got any thoughts on this based on first-hand experience?


Title: Re: frame independent friction
Post by: Triplefox on April 02, 2011, 04:28:10 PM
I've never implemented render-interpolation, it's always seemed like a lot of work for not much gain (assuming render time > update time). Has anyone got any thoughts on this based on first-hand experience?

I did a test of it once for a possible networked game - I had a bouncing ball test like the Amiga Boing Ball (http://www.youtube.com/watch?v=-ga41edXw3A), running with the physics at 15 FPS and rendering at 60. It was not hard and the results actually looked spectacularly smooth, considering that it was just a simple extrapolation of the velocity vector.

So I'd definitely recommend it, if you want online multiplayer(I never got to the point where it was running over a real network, though - I'm sure it gets much more complex). If your game is single player there's no reason to bother, you might as well run the real physics unless they're hideously expensive for some reason.


Title: Re: frame independent friction
Post by: technogothica on April 02, 2011, 04:48:01 PM
Super Meat Boy on Windows is a good example of how updating the game state in step with rendering updates on a variable time base can have a negative impact on game play. A slight pause causes the physics to go haywire, more often than not causing poor old meat boy to die. Fortunately the nature of that game means it doesn't matter too much.

Where possible, use a fixed timebase for world/physics updates. I do this by checking a high resolution timer to see if a fixed amount of time has elapsed before updating the game state. Rendering happens as fast as the hardware will permit.


Title: Re: frame independent friction
Post by: Evan Balster on April 02, 2011, 05:02:47 PM
For whatever it's worth, my machine has developed an odd habit of making all applications that make system calls hang for about five seconds, once every ten minutes or so.  That's a worst-case scenario for many framerate-independent games.  (I'll be reinstalling my OS soon)


Title: Re: frame independent friction
Post by: Glaiel-Gamer on April 02, 2011, 05:28:16 PM
For whatever it's worth, my machine has developed an odd habit of making all applications that make system calls hang for about five seconds, once every ten minutes or so.  That's a worst-case scenario for many framerate-independent games.  (I'll be reinstalling my OS soon)

as a safety mechanism (whether you use an update loop or a delta-time method), you should always cap the maximum frameskip/deltatime. For me it's 10 frameskips (83ms). If you ever detect this, in addition to capping you need to resync the game immediately. Without this I had an issue where a pause would let the game run "hyperspeed" for a few seconds to catch up to where it "should" be which is far more distracting than a small 1-frame slowdown.


Title: Re: frame independent friction
Post by: technogothica on April 02, 2011, 05:30:01 PM
For whatever it's worth, my machine has developed an odd habit of making all applications that make system calls hang for about five seconds, once every ten minutes or so.

Wow, that's nasty :o

Quote
That's a worst-case scenario for many framerate-independent games.

If you implement it like:

Code:
if ((current_time - last_update_time) >= FIXED_DURATION)
{
   Update(FIXED_DURATION);
   last_update_time = current_time;
}

...then the worst that will happen is the game will simply grind to a halt. The pause will be noticeable, but at least the game state will be consistent when it starts moving again.

Not sure about networked games though...


Title: Re: frame independent friction
Post by: Derakon on April 02, 2011, 08:30:38 PM
My project uses interpolation for rendering, and it really does make a big difference. It's also not too hard to do; I just store the previous position of each sprite, and the render function takes a number between 0 and 1 which is the fraction of time that has passed since the last physics update. Just do a weighted interpolation (prevPos + progress * (curPos - prevPos)) and draw the sprite at that location. I have it capped to always render at least once per physics step, so there's no issue with physics running away from rendering, but as long as the computer can keep up, the animations are significantly smoother than they would otherwise be.

Non-interpolated sprites really don't look all that good unless you either have a very high physics update rate (which, depending on what you're doing, may end up limiting how old of a computer you can run on) or have sprites that don't move very quickly.


Title: Re: frame independent friction
Post by: Draknek on April 03, 2011, 03:01:33 AM
I have to admit, Triplefox's solution of just extrapolating from the velocity vector is more tempting since that wouldn't require hacking the engine to store the past state of every game object.

Anyone implemented it both ways for comparison?