• Advertisement
Sign in to follow this  

Framerate independent friction

This topic is 2176 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I noticed that my game runs a bit differently when running at 60 FPS on my PC and 30 FPS on my phone, and I traced it down to the friction code. I'm applying friction like this:

newVelocity = oldVelocity - oldVelocity * friction * elapsedTime

The results are not consistent between 60 Hz and 30 Hz. But then I thought about how continuous compound interest is calculated, and I came up with this:

newVelocity = oldVelocity * exp(-friction * elapsedTime)

It works perfectly, at least on paper. Has anyone else ever used an approach like this? Or is there a better way to do it?

Edit: I should mention that the game is using a fixed time step. At 30 Hz it's 1/30 seconds and at 60 Hz it's 1/60. Edited by BradDaBug

Share this post


Link to post
Share on other sites
Advertisement
Personally I think fixed timestep physics is good, but some accomodation for varying time delta is nice because schedulers are never 100% precise.

Share this post


Link to post
Share on other sites

Personally I think fixed timestep physics is good, but some accomodation for varying time delta is nice because schedulers are never 100% precise.


what do schedulers have to do with a fixed timestep ?

If you use a fixed timestep you won't use elapsed time in the physics calculations.

instead of:

updatePhysics(elapsedTime);

you do:

while (elapsedTime>timeStepSize) {
updatePhysics(timeStepSize);
elapsedTime-=timeStepSize;
}
where timeStepSize is constant so the physics calculations will be deterministics as you always give it the same delta to work with and instead call the physics update routine multiple times per frame if needed (or not at all if your framerate is higher than the physics update rate) Edited by SimonForsman

Share this post


Link to post
Share on other sites

It works perfectly, at least on paper. Has anyone else ever used an approach like this? Or is there a better way to do it?


It's the correct way of doing it... You are essentially multiplying with (1-friction) every time step so over multiple time steps the "correction" is (1-friction)^n and not [s]n*(1-friction)[/s] (1-n*friction) as you would get with the first version when increasing the timestep n times.

Edit: n*(1-friction) would be totally off Edited by japro

Share this post


Link to post
Share on other sites

what do schedulers have to do with a fixed timestep ?


Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.

Share this post


Link to post
Share on other sites

[quote name='SimonForsman' timestamp='1335678100' post='4935764']
what do schedulers have to do with a fixed timestep ?


Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.
[/quote]

When you use a fixed timestep the delta is constant, you don't pass the actual elapsed time to the physics subsystem. (if you run the physics at 50hz with a fixed timestep you always pass 0.02 as the delta, if the elapsed time is 0.023 you still pass 0.02 as the delta and carry the 0.003 you have left (so the next update triggers after an additional 0.017s have passed), Therefore the scheduler has no impact on the simulation. (You can even run the simulation without measuring the actual elapsed time if the result doesn't have to be displayed in realtime (if you're making a movie for example))

If you need to compensate for a variable delta then you're not using a fixed timestep, you're using a variable timestep. Edited by SimonForsman

Share this post


Link to post
Share on other sites

Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.

Pseudo-code for which the scheduler doesn't matter:

float timestep = 1.0f / 30.0f; // 30 updates per second
Clock clock;
clock.start();

while (runMainLoop)
{
if (clock.time() >= timestep)
{
clock.reset();
updateGame(timestep); // use the *fixed* timestep
}

renderGame();
}

Share this post


Link to post
Share on other sites
@Cornstalks: Very true. I wonder whether it might appear inconsistent or stuttery to a player when physics performed is constant but the real-time that it occurs in is not constant, but I really have no proof either way.

Share this post


Link to post
Share on other sites

@Cornstalks: Very true. I wonder whether it might appear inconsistent or stuttery to a player when physics performed is constant but the real-time that it occurs in is not constant, but I really have no proof either way.

True. In a well done game, the rendering is often interpolated. So you don't just naively call renderGame(), but you give it the system time as well and it interpolates the rendering between the current system time and the game time.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement