1. 程式人生 > >計算FPS的六種方式

計算FPS的六種方式

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u012494876/article/details/53368164

幀率(FPS)計算是遊戲程式設計中常見的一個話題。大體來說,總共有如下六種方法:

一、固定時間幀數法

幀率計算的公式為:

fps = frameNum / elapsedTime;
  • 1

如果記錄固定時間內的幀數,就可以計算出同步率。此種方法用得較多。

int fps()
{
    static int fps = 0;
    static int lastTime = getTime(); // ms
    static int frameCount = 0;

    ++frameCount;

    int curTime = getTime();
    if (curTime - lastTime > 1000) // 取固定時間間隔為1秒
    {
        fps = frameCount;
        frameCount = 0;
        lastTime = curTime;
    }
    return fps;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

還有另一種寫法:

int fps(int deltaTime)
{
    static int fps = 0;
    static int timeLeft = 1000; // 取固定時間間隔為1秒
    static int frameCount = 0;

    ++frameCount;
    timeLeft -= deltaTime;
    if (timeLeft < 0)
    {
        fps = frameCount;
        frameCount = 0;
        timeLeft = 1000;
    }
    return fps;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

二、固定幀數時間法

幀率計算的公式為:

fps = frameNum / elapsedTime;
  • 1

如果每隔固定的幀數,計算幀數使用的時間,也可求出幀率。此種方法使用得較少。

int fps()
{
    static int fps = 0;
    static int frameCount = 0;
    static int lastTime = getTime(); // ms

    ++frameCount;

    if (frameCount >= 100) // 取固定幀數為100幀
    {
        int curTime = getTime();
        fps = frameCount / (curTime - lastTime) * 1000;
        lastTime = curTime;
        frameCount = 0;
    }
    return fps;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

三、實時計演算法

實時計演算法直接使用上一幀的時間間隔進行計算,結果具有實時性,但平滑性不好。

int fps(int deltaTime) // ms
{
    int fps = static_cast<int>(1.f / deltaTime * 1000); // 別忘了先轉換為浮點數,否則會有精度丟失
    return fps;
}
  • 1
  • 2
  • 3
  • 4
  • 5

四、總平均法

總平均法使用全域性幀數除以全域性時間,以求出幀率。

int beginTime = getTime();

int fps()
{
    static int frameCount = 0;

    ++frameCount;

    int deltaTime = getTime() - beginTime();
    return static_cast<int>(frameCount * 1.f / deltaTime * 1000); // 別忘了先轉換為浮點數,否則會有精度丟失
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

五、精確取樣法

精確取樣法取樣前N個幀,然後計算平均值。此種方法需要額外的記憶體空間,所以不常用。

int fps(int deltaTime) // ms
{
    static std::queue<int> q;
    static int sumDuration = 0; // ms

    int fps = 0;
    if (q.size() < 100) // 樣本數設為100
    {
        sumDuration += deltaTime;
        q.push(deltaTime);
        fps = static_cast<int>(q.size() * 1.f / sumDuration * 1000.f); // 別忘了轉換為浮點數,否則會有精度丟失
    }
    else
    {
        sumDuration -= q.front();
        sumDuration += deltaTime;
        sumDuration.pop();
        sumDuration.push(deltaTime);
        fps = static_cast<int>(100.f / sumDuration * 1000.f); // 別忘了轉換為浮點數,否則會有精度丟失
    }
    return fps;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

六、平均取樣法

平均取樣法利用上次的統計結果,克服了精確取樣法需要使用額外空間的缺點。此種方法較常用。

int fps(int deltaTime) // ms
{
    static float avgDuration = 0.f;
    static alpha = 1.f / 100.f; // 取樣數設定為100
    static int frameCount = 0;

    ++frameCount;

    int fps = 0;
    if (1 == frameCount)
    {
        avgDuration = static_cast<float>(deltaTime);
    }
    else
    {
        avgDuration = avgDuration * (1 - alpha) + deltaTime * alpha; 
    }

    fps = static_cast<int>(1.f / avgDuration * 1000);
    return fps;
}

--------------------- 本文來自 天律界中子 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/u012494876/article/details/53368164?utm_source=copy