天天看點

幀率(FPS)計算的六種方法總結一、固定時間幀數法二、固定幀數時間法三、實時計算法四、總平均法五、精确采樣法六、平均采樣法

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

一、固定時間幀數法

幀率計算的公式為:

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

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

    ++frameCount;

    int curTime = getTime();
    if (curTime - lastTime > ) // 取固定時間間隔為1秒
    {
        fps = frameCount;
        frameCount = ;
        lastTime = curTime;
    }
    return fps;
}
           

還有另一種寫法:

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

    ++frameCount;
    timeLeft -= deltaTime;
    if (timeLeft < )
    {
        fps = frameCount;
        frameCount = ;
        timeLeft = ;
    }
    return fps;
}
           

二、固定幀數時間法

幀率計算的公式為:

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

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

    ++frameCount;

    if (frameCount >= ) // 取固定幀數為100幀
    {
        int curTime = getTime();
        fps = frameCount / (curTime - lastTime) * ;
        lastTime = curTime;
        frameCount = ;
    }
    return fps;
}
           

三、實時計算法

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

int fps(int deltaTime) // ms
{
    int fps = static_cast<int>( / deltaTime * ); // 别忘了先轉換為浮點數,否則會有精度丢失
    return fps;
}
           

四、總平均法

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

int beginTime = getTime();

int fps()
{
    static int frameCount = ;

    ++frameCount;

    int deltaTime = getTime() - beginTime();
    return static_cast<int>(frameCount *  / deltaTime * ); // 别忘了先轉換為浮點數,否則會有精度丢失
}
           

五、精确采樣法

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

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

    int fps = ;
    if (q.size() < ) // 樣本數設為100
    {
        sumDuration += deltaTime;
        q.push(deltaTime);
        fps = static_cast<int>(q.size() *  / sumDuration * ); // 别忘了轉換為浮點數,否則會有精度丢失
    }
    else
    {
        sumDuration -= q.front();
        sumDuration += deltaTime;
        sumDuration.pop();
        sumDuration.push(deltaTime);
        fps = static_cast<int>( / sumDuration * ); // 别忘了轉換為浮點數,否則會有精度丢失
    }
    return fps;
}
           

六、平均采樣法

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

int fps(int deltaTime) // ms
{
    static float avgDuration = ;
    static alpha =  / ; // 采樣數設定為100
    static int frameCount = ;

    ++frameCount;

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

    fps = static_cast<int>( / avgDuration * );
    return fps;
}
           

繼續閱讀