Confused About Frames Per Second

Started by
28 comments, last by frob 7 years, 11 months ago

>> I made a change so now I'm only counting frames where an update occurred and my FPS is now displaying as 100,

then you are counting updates per second, not renders per second. which do you want?

you are tweening based on accumulator when you render, right? that's part of the "fix your timestep" algo too - not just "consume ET in DT sized chunks".

.

You're right, I did actually modify it so that the render call only happens when it runs an update of the game state, because why render if nothing has changed?

I'm not sure what you mean by tweening though.

Advertisement

You're right, I did actually modify it so that the render call only happens when it runs an update of the game state, because why render if nothing has changed?

I'm not sure what you mean by tweening though.


Something has changed, time. The idea of having a fixed time step is separating the update rate of your simulation from rendering. Time does pass between your simulation steps and whatever you render to the screen should reflect that. As you have noticed, if you dial down the simulation rate, everything seems to jitter and not be as smooth as you'd expect it to be. The solution to this is to interpolate everything between the previous state and the current state (tweening) based on how much time has passed since the previous state.

Put in code, it looks something like this:


accumulator += deltaTime;
while(accumulator >= simulationStepTime)
{
    // store current position as previous position
    // update game state and current position
    accumulator -= simulationStepTime;
}

float interpolation = accumulator / (float)simulationStepTime;
V3 interpolatedPosition = (1 - interpolation) * previousPosition + interpolation * currentPosition;
DrawObjectAt(interpolatedPosition);

Now you can dial your simulation rate to 1Hz and it'll still look smooth as long as your FPS is 25+. The trade-off is that lower rates introduce more latency, in the case of 1Hz it would take up to 1 second before you notice any changes, but with decent rates (20Hz+, less than 50ms latency) you shouldn't notice any difference with any other game out there.

You're right, I did actually modify it so that the render call only happens when it runs an update of the game state, because why render if nothing has changed?

I'm not sure what you mean by tweening though.


Assuming animation is happening, you still need to render when nothing has changed because something HAS changed.

Tweening is an old animation term, drawing the frames in between key frames. It applies here because something HAS changed.

That something is time.

If you reread the "Fix Your Timestep" article, you'll see this near the bottom:



What this means is that we’re displaying the state of the physics simulation at a time value slightly different from the render time. This causes a subtle but visually unpleasant stuttering of the physics simulation



The solution is to draw as though you were pat of the way through.

Imagine you have simulation time steps simulated at simulator time step 2973 and 2986, and your rendering is taking place at simulator time step 2976. That means you don't draw 2973 because that is too far in the past, and you don't draw 2986, that is too far in the future. You draw 23% of the distance between the past and the present. If your next render takes place at simulator time step 2985 you still don't need to update the simulation, but you draw at 92% of the distance between the past and the present.

Decoupling your rendering step from your simulation step is part of the solution. Once it is decoupled so you are no longer simulating every frame, generally you need a somewhat more difficult step of triggering the rendering interpolating between two simulator steps.

You're right, I did actually modify it so that the render call only happens when it runs an update of the game state, because why render if nothing has changed?

I'm not sure what you mean by tweening though.


Assuming animation is happening, you still need to render when nothing has changed because something HAS changed.

Tweening is an old animation term, drawing the frames in between key frames. It applies here because something HAS changed.

That something is time.

If you reread the "Fix Your Timestep" article, you'll see this near the bottom:



What this means is that we’re displaying the state of the physics simulation at a time value slightly different from the render time. This causes a subtle but visually unpleasant stuttering of the physics simulation



The solution is to draw as though you were pat of the way through.

Imagine you have simulation time steps simulated at simulator time step 2973 and 2986, and your rendering is taking place at simulator time step 2976. That means you don't draw 2973 because that is too far in the past, and you don't draw 2986, that is too far in the future. You draw 23% of the distance between the past and the present. If your next render takes place at simulator time step 2985 you still don't need to update the simulation, but you draw at 92% of the distance between the past and the present.

Decoupling your rendering step from your simulation step is part of the solution. Once it is decoupled so you are no longer simulating every frame, generally you need a somewhat more difficult step of triggering the rendering interpolating between two simulator steps.

So I sort of see what you mean, the rendering should be "tricked" into thinking it's matching the simulation time, right? I think I'm still confused though because you are referring to it as the past and the present, but it seems like it would be based on the future.

I tried to make a diagram to help me understand it:

KLymcZW.png

In this example, a red dot is being moved along the x-axis at a rate of 32 units per 0.01 seconds. The simulation time step is also 0.01 seconds. Frame 2 is an in-between frame, where a simulation update hasn't yet occurred, so the position of x would need to be interpolated. When it is time to render frame 2, I don't have the information for frame 3 yet, so I'm not sure how I would calculate the interpolation.

It is often a little confusing to people who haven't worked on modern games.

Many games have simulators that operate in the future as far as the human is concerned.

The simulator advances time occasionally as needed, usually thinking about the near future. The display shows somewhere in the past on the timeline at an approximate location between the previous simulated location and the approximated future simulation. User input generally gets inserted into the game simulation, in many modern games the simulation rewinds time a little, inserts the commands back where the player expects, then replays the future with the new input.

Although it sounds rather complex, in practice it means a few hundred kilobytes or possibly a couple megabytes of data gets kept around between simulation steps, and rendering gets a tad more work.

for a full fixed timestep algo you need two parts:

update:

accumulator += ET

while (accumulator >= DT)

{

// do one update

accumulator -= DT

}

you have to store both current and previous location for objects. IE where they are now, and where they were before the last update.

render:

draw_location = lerp of accumulator from 0 to DT, mapped to the range old through new position.

so whatever % from 0 to DT the accumulator is (say 17% of the way), that's how far you draw the object between the previous and current locations (17% of the distance). so in essence, you're always drawing about half an update (on average) behind where things really are. but given a DT of 100ms or less, this "temporal aliasing" is negligible.

there is another alternative - a framerate limiter. instead of running render as fast as possible and updating every DT seconds, and storing both current and previous locations, and tweening between previous and current location for drawing, you just add this to the end of the main game loop:

while (elapsedtime for this iteration of the main loop < desired_frametime) { // do nothing }.

say you want to run at 60 fps. set your desired frame time to 16.6666 ms.

pros: easier to implement. degrades gracefully under heavy load.

cons: can't run quite as fast as fix your timestep algo. these days the differences in speed are really negligible though. you only need a solid 15 fps to be sufficiently responsive to be playable. once you hit 30 or so, your animation is smooth and your responsiveness is quite snappy. anything more is just smoother animation eye candy. turns out that lower framerates (within reason) aren't bad, variable frames rates are bad.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

you only need a solid 15 fps to be sufficiently responsive to be playable. once you hit 30 or so, your animation is smooth and your responsiveness is quite snappy. anything more is just smoother animation eye candy. turns out that lower framerates (within reason) aren't bad, variable frames rates are bad.

This reads like an absolute truth, but it isn't; it depends wildly on the game. While the games you make might be fully playable at lower framerates (and might also thus be what you're accustomed to), it does not mean that translates to every other game/genre.

For fighting and racing games in particular, higher framerates are easily noticable, far above 30 frames per second.

For a chess game without fancy movements/animations, 2 frames per second would probably still be playable (although possibly somewhat annoying with selection latency).

I can't think of a single instance where a higher frame rate would lead to a worse product, but I can definitely think of the inverse.

For VR games/applications, what is considered to be usable is also much much higher, although not for the same reasons.

That said, I definitely agree with constant frame rates being very important. Companies are also starting to catch on to this, e.g. by offering optional frame rate limiters if the frame rate varies, and even in some cases options for whether graphics quality or frame rate is to be prioritized (both of which, for console games, are a fairly huge change to the status quo).

Hello to all my stalkers.

>> For fighting and racing games in particular, higher framerates are easily noticable, far above 30 frames per second.

noticeable, or necessary?

when you first change framerates its noticeable, but after a while you get used to it.

i can see how something like a fighting game or racing sim might require more than 30 inputs updates and renders per second to reduce temporal lag. at 30 fps you're still only responding to the user once every 33ms, which might be a bit long for a split second game like fighting or driving.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

noticeable, or necessary?

I would say it depends on the specific game. I feel like the more reflex/fast-paced the game is, the more necessary higher frame rates become in order for it to be enjoyable (which I think has a higher threshold than "playable").

I think the most extreme case would probably be fighting games at a competitive/professional level.

Hello to all my stalkers.

Yes, the competition-style games are the most extreme example.

There are many players who intentionally sacrifice visual quality for faster information.

* They'll turn off the optional effects, smoke, flames, flares, object destruction, if there is a switch for it they'll turn it off.

* They'll disable antialiasing for faster display.

* They'll disable vsync and accept visual tearing to get the information as fast as possible, because even partial information is better than no information.

* They'll use low resolutions to get higher frame rates in competition play. If the game goes to 1024x768 or 800x600 full screen with a high refresh rate, they'll run them.

* Some will pay a small fortune for dual-DVI monitors and cards to have 120Hz or 240Hz displays and still have low resolutions.

In serious competitive play, the players do anything they're allowed to gain an edge.

This topic is closed to new replies.

Advertisement