Calculating frames per second in a game

后端 未结 19 639
天命终不由人
天命终不由人 2020-12-04 05:10

What\'s a good algorithm for calculating frames per second in a game? I want to show it as a number in the corner of the screen. If I just look at how long it took to render

相关标签:
19条回答
  • 2020-12-04 05:34

    A much better system than using a large array of old framerates is to just do something like this:

    new_fps = old_fps * 0.99 + new_fps * 0.01
    

    This method uses far less memory, requires far less code, and places more importance upon recent framerates than old framerates while still smoothing the effects of sudden framerate changes.

    0 讨论(0)
  • 2020-12-04 05:34

    Here's how I do it (in Java):

    private static long ONE_SECOND = 1000000L * 1000L; //1 second is 1000ms which is 1000000ns
    
    LinkedList<Long> frames = new LinkedList<>(); //List of frames within 1 second
    
    public int calcFPS(){
        long time = System.nanoTime(); //Current time in nano seconds
        frames.add(time); //Add this frame to the list
        while(true){
            long f = frames.getFirst(); //Look at the first element in frames
            if(time - f > ONE_SECOND){ //If it was more than 1 second ago
                frames.remove(); //Remove it from the list of frames
            } else break;
            /*If it was within 1 second we know that all other frames in the list
             * are also within 1 second
            */
        }
        return frames.size(); //Return the size of the list
    }
    
    0 讨论(0)
  • 2020-12-04 05:37

    You need a smoothed average, the easiest way is to take the current answer (the time to draw the last frame) and combine it with the previous answer.

    // eg.
    float smoothing = 0.9; // larger=more smoothing
    measurement = (measurement * smoothing) + (current * (1.0-smoothing))
    

    By adjusting the 0.9 / 0.1 ratio you can change the 'time constant' - that is how quickly the number responds to changes. A larger fraction in favour of the old answer gives a slower smoother change, a large fraction in favour of the new answer gives a quicker changing value. Obviously the two factors must add to one!

    0 讨论(0)
  • 2020-12-04 05:38

    You could keep a counter, increment it after each frame is rendered, then reset the counter when you are on a new second (storing the previous value as the last second's # of frames rendered)

    0 讨论(0)
  • 2020-12-04 05:40

    store a start time and increment your framecounter once per loop? every few seconds you could just print framecount/(Now - starttime) and then reinitialize them.

    edit: oops. double-ninja'ed

    0 讨论(0)
  • 2020-12-04 05:42

    Good answers here. Just how you implement it is dependent on what you need it for. I prefer the running average one myself "time = time * 0.9 + last_frame * 0.1" by the guy above.

    however I personally like to weight my average more heavily towards newer data because in a game it is SPIKES that are the hardest to squash and thus of most interest to me. So I would use something more like a .7 \ .3 split will make a spike show up much faster (though it's effect will drop off-screen faster as well.. see below)

    If your focus is on RENDERING time, then the .9.1 split works pretty nicely b/c it tend to be more smooth. THough for gameplay/AI/physics spikes are much more of a concern as THAT will usually what makes your game look choppy (which is often worse than a low frame rate assuming we're not dipping below 20 fps)

    So, what I would do is also add something like this:

    #define ONE_OVER_FPS (1.0f/60.0f)
    static float g_SpikeGuardBreakpoint = 3.0f * ONE_OVER_FPS;
    if(time > g_SpikeGuardBreakpoint)
        DoInternalBreakpoint()
    

    (fill in 3.0f with whatever magnitude you find to be an unacceptable spike) This will let you find and thus solve FPS issues the end of the frame they happen.

    0 讨论(0)
提交回复
热议问题