एक खेल में प्रति सेकंड फ्रेम की गणना


110

एक खेल में प्रति सेकंड फ्रेम की गणना के लिए एक अच्छा एल्गोरिथ्म क्या है? मैं इसे स्क्रीन के कोने में एक नंबर के रूप में दिखाना चाहता हूं। अगर मैं अभी देखता हूं कि आखिरी फ्रेम को रेंडर करने में कितना समय लगा तो नंबर बहुत तेजी से बदलता है।

बोनस अंक यदि आपका उत्तर प्रत्येक फ्रेम को अपडेट करता है और फ्रेम दर में वृद्धि बनाम घटते समय अलग-अलग रूपांतरित नहीं करता है।

जवाबों:


100

आपको एक सुचारू औसत की आवश्यकता है, सबसे आसान तरीका वर्तमान उत्तर (अंतिम फ्रेम को खींचने का समय) लेना है और इसे पिछले उत्तर के साथ संयोजित करना है।

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

0.9 / 0.1 अनुपात को समायोजित करके आप 'समय स्थिर' बदल सकते हैं - यह है कि कितनी जल्दी संख्या परिवर्तनों के प्रति प्रतिक्रिया करती है। पुराने उत्तर के पक्ष में एक बड़ा अंश एक धीमी गति से परिवर्तन देता है, नए उत्तर के पक्ष में एक बड़ा अंश एक त्वरित परिवर्तन मूल्य देता है। जाहिर है कि दो कारकों को एक में जोड़ना होगा!


14
फिर मूर्खता और प्रफुल्लता के लिए, आप शायद फ्लोट वेटरेटियो = 0.1 जैसा कुछ चाहते हैं; और समय = समय * (1.0 - भार अनुपात) + last_frame * भारांक
कोरोना

2
सिद्धांत रूप में अच्छा और सरल लगता है, लेकिन वास्तव में इस दृष्टिकोण का चौरसाई मुश्किल से ध्यान देने योग्य है। अच्छा नहीं।
पेट्रुकियो

1
@Petrucio यदि चौरसाई बहुत कम है, तो बस समय स्थिर रखें (भार अनुपात = 0.05, 0.02, 0.01 ...)
जॉन ड्वोरक

8
@Petrucio: का last_frameमतलब यह नहीं है (या कम से कम इसका मतलब नहीं होना चाहिए ) पिछले फ्रेम की अवधि; इसका मतलब यह होना चाहिए timeकि आपने अंतिम फ्रेम के लिए गणना की है। इस तरह, पिछले सभी फ़्रेमों को शामिल किया जाएगा, जिनमें सबसे हाल के फ़्रेमों को सबसे अधिक भारित किया गया है।
j_random_hacker

1
चर नाम "last_frame" भ्रामक है। "current_frame" अधिक वर्णनात्मक होगा। यह जानना भी महत्वपूर्ण है कि उदाहरण में चर "समय" वैश्विक होना चाहिए (अर्थात सभी फ़्रेमों में इसका मूल्य रखें) और आदर्श रूप से एक अस्थायी फ़्लोटिंग संख्या। इसमें औसत / कुल मूल्य शामिल है और प्रत्येक फ्रेम पर अपडेट मिलता है। अनुपात जितना अधिक होगा, "समय" चर को मान की ओर व्यवस्थित करने में अधिक समय लगेगा (या इसे उससे दूर बहाव)।
जोक्स

52

यही मैंने कई खेलों में उपयोग किया है।

#define MAXSAMPLES 100
int tickindex=0;
int ticksum=0;
int ticklist[MAXSAMPLES];

/* need to zero out the ticklist array before starting */
/* average will ramp up until the buffer is full */
/* returns average ticks per frame over the MAXSAMPLES last frames */

double CalcAverageTick(int newtick)
{
    ticksum-=ticklist[tickindex];  /* subtract value falling off */
    ticksum+=newtick;              /* add new value */
    ticklist[tickindex]=newtick;   /* save new value so it can be subtracted later */
    if(++tickindex==MAXSAMPLES)    /* inc buffer index */
        tickindex=0;

    /* return average */
    return((double)ticksum/MAXSAMPLES);
}

मुझे यह दृष्टिकोण बहुत पसंद है। किसी भी विशिष्ट कारण से आप MAXSAMPLES को 100 पर सेट कर सकते हैं?
ज़ोलोमन

1
MAXSAMPLES यहां उन मानों की संख्या है जो एफपीएस के लिए एक मूल्य के साथ आने के लिए औसत हैं।
कोरी ग्रॉस

8
यह साधारण मूविंग एवरेज (SMA)
KindDragon

बहुत बहुत धन्यवाद! मैंने इसे अपने गेम में ट्विक किया ताकि टिक फंक शून्य हो, और एक अन्य फ़ंक्शन एफपीएस लौटाता है, फिर मैं प्रत्येक एक टिक को मुख्य रूप से चला सकता हूं, भले ही रेंडर कोड में एफपीएस न दिखा हो।
TheJosh

2
कृपया मोडुलो का उपयोग करें और यदि नहीं। tickindex = (tickindex + 1) % MAXSAMPLES;
फेलिक्स के।

25

खैर, निश्चित रूप से

frames / sec = 1 / (sec / frame)

लेकिन, जैसा कि आप बताते हैं, किसी एकल फ़्रेम को प्रस्तुत करने में लगने वाले समय में बहुत अधिक भिन्नता है, और एक UI परिप्रेक्ष्य से फ्रेम दर पर एफपीएस मूल्य को अपडेट करना बिल्कुल भी उपयोग करने योग्य नहीं है (जब तक कि संख्या बहुत स्थिर न हो)।

आप जो चाहते हैं, वह संभवतया एक चलती औसत या किसी प्रकार का बिनिंग / रीसेटिंग काउंटर है।

उदाहरण के लिए, आप एक कतार डेटा संरचना को बनाए रख सकते हैं, जिसमें पिछले 30, 60, 100 या क्या-क्या-क्या फ्रेम हैं (आप इसे डिजाइन भी कर सकते हैं, ताकि सीमा रन-टाइम में समायोज्य हो)। एक सभ्य एफपीएस सन्निकटन निर्धारित करने के लिए आप कतार में सभी प्रतिपादन समय से औसत एफपीएस निर्धारित कर सकते हैं:

fps = # of rendering times in queue / total rendering time

जब आप एक नया फ्रेम प्रदान करते हैं तो आप एक नया प्रतिपादन समय देते हैं और एक पुराने प्रतिपादन समय को समाप्त करते हैं। वैकल्पिक रूप से, आप केवल तब ही धोखा दे सकते हैं जब रेंडरिंग के समय में कुछ पूर्व निर्धारित मूल्य (जैसे 1 सेकंड) से अधिक हो। आप "अंतिम एफपीएस वैल्यू" और एक अंतिम अपडेटेड टाइमस्टैम्प को बनाए रख सकते हैं ताकि आप एफपीएस फिगर को अपडेट करने के लिए ट्रिगर कर सकें, यदि आप चाहें तो। एक चलती औसत के साथ यदि आपके पास लगातार प्रारूपण है, तो प्रत्येक फ्रेम पर "तात्कालिक औसत" एफपीएस को प्रिंट करना संभवतः ठीक होगा।

एक अन्य विधि एक रीसेट काउंटर होगा। एक सटीक (मिलीसेकंड) टाइमस्टैम्प, एक फ्रेम काउंटर और एक एफपीएस मूल्य बनाए रखें। जब आप एक फ्रेम प्रदान करते हैं, तो काउंटर बढ़ाएँ। जब काउंटर प्री-सेट सीमा (जैसे 100 फ़्रेम) को हिट करता है या जब टाइमस्टैम्प से कुछ पूर्व-सेट मान (जैसे 1 सेकंड) बीत चुका होता है, तो एफपीएस की गणना करें:

fps = # frames / (current time - start time)

फिर काउंटर को 0 पर रीसेट करें और टाइमस्टैम्प को वर्तमान समय पर सेट करें।


12

हर बार जब आप किसी स्क्रीन को प्रस्तुत करते हैं तो एक काउंटर बढ़ाते हैं और उस समय अंतराल के लिए उस काउंटर को साफ़ करते हैं, जिस पर आप फ्रेम-दर को मापना चाहते हैं।

अर्थात। प्रत्येक 3 सेकंड, काउंटर / 3 प्राप्त करें और फिर काउंटर को खाली करें।


+1 हालांकि यह केवल आपको अंतराल में एक नया मूल्य देगा, यह समझना आसान है और इसके लिए न तो सरणियों और न ही अनुमान लगाने की आवश्यकता है और वैज्ञानिक रूप से सही है।
opatut

10

इसे करने के कम से कम दो तरीके हैं:


पहला वह है जिसका उल्लेख अन्य लोग यहां मेरे समक्ष कर चुके हैं। मुझे लगता है कि यह सबसे सरल और पसंदीदा तरीका है। आप बस नज़र रखने के लिए

  • cn: आपने कितने फ़्रेमों का काउंटर किया है
  • time_start: जब से आपने गिनना शुरू किया है
  • time_now: वर्तमान समय

इस मामले में एफपीएस की गणना करना इस फॉर्मूले का मूल्यांकन करने जितना आसान है:

  • FPS = cn / (time_now - time_start)।

फिर uber कूल तरीका है जिसे आप किसी दिन उपयोग करना पसंद कर सकते हैं:

मान लीजिए कि आपके पास विचार करने के लिए 'i' फ्रेम हैं। मैं इस नोटेशन का उपयोग करूँगा: f [0], f [1], ..., f [i-1] यह वर्णन करने में कि फ्रेम 0, फ्रेम 1, ..., फ्रेम (i-1) को रेंडर करने में कितना समय लगा। ) क्रमशः।

Example where i = 3

|f[0]      |f[1]         |f[2]   |
+----------+-------------+-------+------> time

तब, मैं फ्रेम के बाद एफपीएस की गणितीय परिभाषा होगी

(1) fps[i]   = i     / (f[0] + ... + f[i-1])

और एक ही सूत्र लेकिन केवल i-1 फ्रेम पर विचार करना।

(2) fps[i-1] = (i-1) / (f[0] + ... + f[i-2]) 

अब यहाँ ट्रिक है फॉर्मूला (1) के राइट साइड को इस तरह से मोडिफाई करना कि इसमें फॉर्मूला का राइट साइड (2) होगा और इसे लेफ्ट साइड के लिए सब्स्टीट्यूट किया जाएगा।

जैसे (यदि आप इसे कागज पर लिखते हैं तो आपको इसे और स्पष्ट रूप से देखना चाहिए):

fps[i] = i / (f[0] + ... + f[i-1])
       = i / ((f[0] + ... + f[i-2]) + f[i-1])
       = (i/(i-1)) / ((f[0] + ... + f[i-2])/(i-1) + f[i-1]/(i-1))
       = (i/(i-1)) / (1/fps[i-1] + f[i-1]/(i-1))
       = ...
       = (i*fps[i-1]) / (f[i-1] * fps[i-1] + i - 1)

तो इस सूत्र के अनुसार (मेरा गणित व्युत्पन्न कौशल हालांकि थोड़ा कठोर है), नए एफपीएस की गणना करने के लिए आपको पिछले फ्रेम से एफपीएस जानने की जरूरत है, अंतिम फ्रेम और आपके द्वारा फ़्रेम की संख्या को रेंडर करने के लिए ली गई अवधि प्रदान की गई।


1
दूसरी विधि के लिए +1। मुझे लगता है कि यह uber सटीक गणना के लिए अच्छा होगा: 3
zeboidlund

5

यह ज्यादातर लोगों के लिए ओवरकिल हो सकता है, इसीलिए जब मैंने इसे लागू किया तो मैंने इसे पोस्ट नहीं किया था। लेकिन यह बहुत मजबूत और लचीला है।

यह अंतिम फ्रेम समय के साथ एक क्यू स्टोर करता है, इसलिए यह केवल अंतिम फ्रेम को ध्यान में रखने से बेहतर एफपीएस मूल्य की गणना कर सकता है।

यह आपको एक फ्रेम को अनदेखा करने की भी अनुमति देता है, यदि आप कुछ ऐसा कर रहे हैं जो आप जानते हैं कि उस फ्रेम के समय को कृत्रिम रूप से खराब करना है।

यह आपको क्यू में स्टोर करने के लिए फ़्रेम की संख्या को बदलने की भी अनुमति देता है क्योंकि यह चलता है, इसलिए आप इसे मक्खी पर परीक्षण कर सकते हैं कि आपके लिए सबसे अच्छा मूल्य क्या है।

// Number of past frames to use for FPS smooth calculation - because 
// Unity's smoothedDeltaTime, well - it kinda sucks
private int frameTimesSize = 60;
// A Queue is the perfect data structure for the smoothed FPS task;
// new values in, old values out
private Queue<float> frameTimes;
// Not really needed, but used for faster updating then processing 
// the entire queue every frame
private float __frameTimesSum = 0;
// Flag to ignore the next frame when performing a heavy one-time operation 
// (like changing resolution)
private bool _fpsIgnoreNextFrame = false;

//=============================================================================
// Call this after doing a heavy operation that will screw up with FPS calculation
void FPSIgnoreNextFrame() {
    this._fpsIgnoreNextFrame = true;
}

//=============================================================================
// Smoothed FPS counter updating
void Update()
{
    if (this._fpsIgnoreNextFrame) {
        this._fpsIgnoreNextFrame = false;
        return;
    }

    // While looping here allows the frameTimesSize member to be changed dinamically
    while (this.frameTimes.Count >= this.frameTimesSize) {
        this.__frameTimesSum -= this.frameTimes.Dequeue();
    }
    while (this.frameTimes.Count < this.frameTimesSize) {
        this.__frameTimesSum += Time.deltaTime;
        this.frameTimes.Enqueue(Time.deltaTime);
    }
}

//=============================================================================
// Public function to get smoothed FPS values
public int GetSmoothedFPS() {
    return (int)(this.frameTimesSize / this.__frameTimesSum * Time.timeScale);
}

2

यहाँ अच्छा जवाब। बस आप इसे कैसे लागू करते हैं, इस पर निर्भर है कि आपको इसकी क्या आवश्यकता है। मैं ऊपर वाले आदमी द्वारा खुद को "औसत = समय * 0.9 * पिछले_फ्रेम * 0.1" चलाने की औसत पसंद करता हूं।

हालाँकि, मैं व्यक्तिगत रूप से नए डेटा की ओर अपने औसत को अधिक भारित करना पसंद करता हूं क्योंकि एक खेल में यह SPIKES है जो स्क्वैश के लिए सबसे कठिन है और इस प्रकार मेरे लिए सबसे अधिक रुचि है। तो मैं एक .7 \ .3 विभाजन की तरह कुछ और अधिक उपयोग करेगा, एक स्पाइक को बहुत तेज़ी से दिखाएगा (हालांकि इसका प्रभाव ऑफ-स्क्रीन को तेज़ी से छोड़ देगा .. नीचे देखें)

यदि आपका ध्यान RENDERING के समय पर है, तो .9.1 स्प्लिट बहुत अच्छी तरह से b / c काम करता है, यह अधिक चिकना होता है। गेमप्ले / एआई / फिजिक्स स्पाइक्स के लिए बहुत अधिक चिंता का विषय है क्योंकि आमतौर पर यह आपके खेल को तड़का हुआ बनाता है (जो अक्सर कम फ्रेम दर से भी बदतर होता है, यह मानते हुए कि हम 20 एफपीएस से नीचे नहीं जा रहे हैं)

इसलिए, मैं जो करूंगा वह भी कुछ इस तरह से जोड़ना होगा:

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

(जो कुछ भी परिमाण आपको एक अस्वीकार्य स्पाइक लगता है, उसके साथ 3.0f में भरें) यह आपको ढूंढने देगा और इस प्रकार एफपीएस के मुद्दों को हल करेगा जो कि वे होते हैं।


मुझे time = time * 0.9 + last_frame * 0.1औसत गणना पसंद है जो डिस्प्ले को सुचारू रूप से बदल देती है।
फाबिन क्वात्रावाक्स 13

2

पुराने फ्रैमरेट्स के एक बड़े सरणी का उपयोग करने की तुलना में एक बेहतर प्रणाली सिर्फ इस तरह से कुछ करना है:

new_fps = old_fps * 0.99 + new_fps * 0.01

इस पद्धति में बहुत कम मेमोरी का उपयोग होता है, बहुत कम कोड की आवश्यकता होती है, और पुराने फ्रैमरेट्स की तुलना में हाल के फ्रैमरेट्स पर अधिक महत्व रखता है जबकि अभी भी अचानक फ्रैमरेट परिवर्तनों के प्रभाव को सुचारू करता है।


1

आप एक काउंटर रख सकते हैं, प्रत्येक फ्रेम के प्रस्तुत होने के बाद इसे बढ़ा सकते हैं, फिर काउंटर को रीसेट कर सकते हैं जब आप एक नए सेकंड पर होते हैं (पिछले मूल्य को फ्रेम के अंतिम दूसरे के रूप में संग्रहीत करते हुए)


1

जावास्क्रिप्ट:

// Set the end and start times
var start = (new Date).getTime(), end, FPS;
  /* ...
   * the loop/block your want to watch
   * ...
   */
end = (new Date).getTime();
// since the times are by millisecond, use 1000 (1000ms = 1s)
// then multiply the result by (MaxFPS / 1000)
// FPS = (1000 - (end - start)) * (MaxFPS / 1000)
FPS = Math.round((1000 - (end - start)) * (60 / 1000));

1

यहां एक पूर्ण उदाहरण है, पायथन का उपयोग करके (लेकिन आसानी से किसी भी भाषा के लिए अनुकूलित)। यह मार्टिन के जवाब में स्मूथिंग समीकरण का उपयोग करता है, इसलिए लगभग कोई मेमोरी ओवरहेड नहीं है, और मैंने उन मूल्यों को चुना जो मेरे लिए काम करते थे (अपने उपयोग के मामले में अनुकूल होने के लिए स्थिरांक के साथ खेलने के लिए स्वतंत्र महसूस करें)।

import time

SMOOTHING_FACTOR = 0.99
MAX_FPS = 10000
avg_fps = -1
last_tick = time.time()

while True:
    # <Do your rendering work here...>

    current_tick = time.time()
    # Ensure we don't get crazy large frame rates, by capping to MAX_FPS
    current_fps = 1.0 / max(current_tick - last_tick, 1.0/MAX_FPS)
    last_tick = current_tick
    if avg_fps < 0:
        avg_fps = current_fps
    else:
        avg_fps = (avg_fps * SMOOTHING_FACTOR) + (current_fps * (1-SMOOTHING_FACTOR))
    print(avg_fps)

0

काउंटर को शून्य पर सेट करें। हर बार जब आप काउंटर बढ़ाते हैं तो एक फ्रेम बढ़ाते हैं। प्रत्येक सेकंड के बाद काउंटर प्रिंट करें। बल्कि, कुल्ला, दोहराएं। यदि यो अतिरिक्त क्रेडिट चाहते हैं, तो एक रनिंग काउंटर रखें और एक रनिंग एवरेज के लिए कुल सेकंड में विभाजित करें।


0

(C ++ की तरह) pseudocode ये दोनों वे हैं जो मैंने औद्योगिक छवि प्रसंस्करण अनुप्रयोगों में उपयोग किए हैं जिन्हें बाहरी रूप से ट्रिगर कैमरा के सेट से छवियों को संसाधित करना था। "फ्रेम रेट" में भिन्नता का एक अलग स्रोत था (बेल्ट पर धीमी या तेज उत्पादन) लेकिन समस्या समान है। (मुझे लगता है कि आपके पास एक सरल टाइमर है। पीक () कॉल जो आपको एमएसईसी (एनएससी?) के एनआर की तरह कुछ देता है क्योंकि आवेदन शुरू या आखिरी कॉल)

समाधान 1: तेजी से लेकिन हर फ्रेम को अपडेट नहीं किया गया

do while (1)
{
    ProcessImage(frame)
    if (frame.framenumber%poll_interval==0)
    {
        new_time=timer.peek()
        framerate=poll_interval/(new_time - last_time)
        last_time=new_time
    }
}

समाधान 2: हर फ्रेम को अपडेट किया गया है, अधिक मेमोरी और सीपीयू की आवश्यकता है

do while (1)
{
   ProcessImage(frame)
   new_time=timer.peek()
   delta=new_time - last_time
   last_time = new_time
   total_time += delta
   delta_history.push(delta)
   framerate= delta_history.length() / total_time
   while (delta_history.length() > avg_interval)
   {
      oldest_delta = delta_history.pop()
      total_time -= oldest_delta
   }
} 

0
qx.Class.define('FpsCounter', {
    extend: qx.core.Object

    ,properties: {
    }

    ,events: {
    }

    ,construct: function(){
        this.base(arguments);
        this.restart();
    }

    ,statics: {
    }

    ,members: {        
        restart: function(){
            this.__frames = [];
        }



        ,addFrame: function(){
            this.__frames.push(new Date());
        }



        ,getFps: function(averageFrames){
            debugger;
            if(!averageFrames){
                averageFrames = 2;
            }
            var time = 0;
            var l = this.__frames.length;
            var i = averageFrames;
            while(i > 0){
                if(l - i - 1 >= 0){
                    time += this.__frames[l - i] - this.__frames[l - i - 1];
                }
                i--;
            }
            var fps = averageFrames / time * 1000;
            return fps;
        }
    }

});

0

मैं इसे कैसे करूँ!

boolean run = false;

int ticks = 0;

long tickstart;

int fps;

public void loop()
{
if(this.ticks==0)
{
this.tickstart = System.currentTimeMillis();
}
this.ticks++;
this.fps = (int)this.ticks / (System.currentTimeMillis()-this.tickstart);
}

शब्दों में, एक टिक घड़ी ट्रैक टिक करता है। यदि यह पहली बार है, तो यह वर्तमान समय लेता है और इसे 'टिकस्टार्ट' में रखता है। पहली टिक के बाद, यह चर 'एफपीएस' के बराबर बनाता है कि टिक टिक घड़ी के कितने टिक पहले टाइम टिक के समय को घटाते हैं।

एफपीएस एक पूर्णांक है, इसलिए "(इंट)"।


1
किसी के लिए भी सिफारिश नहीं करेंगे। टिक्स की कुल संख्या को सेकंड की कुल संख्या से विभाजित करने से एफपीएस दृष्टिकोण गणितीय सीमा की तरह हो जाता है, जहां यह मूल रूप से लंबे समय के बाद 2-3 मूल्यों पर बसता है, और गलत परिणाम प्रदर्शित करता है।
कार्तिक चुघ

0

यहाँ मैं यह कैसे (जावा में) कर रहा हूँ:

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

टाइपस्क्रिप्ट में, मैं इस एल्गोरिथ्म का उपयोग फ्रैमरेट और फ्रैमेमेटाइम औसत की गणना करने के लिए करता हूं:

let getTime = () => {
    return new Date().getTime();
} 

let frames: any[] = [];
let previousTime = getTime();
let framerate:number = 0;
let frametime:number = 0;

let updateStats = (samples:number=60) => {
    samples = Math.max(samples, 1) >> 0;

    if (frames.length === samples) {
        let currentTime: number = getTime() - previousTime;

        frametime = currentTime / samples;
        framerate = 1000 * samples / currentTime;

        previousTime = getTime();

        frames = [];
    }

    frames.push(1);
}

उपयोग:

statsUpdate();

// Print
stats.innerHTML = Math.round(framerate) + ' FPS ' + frametime.toFixed(2) + ' ms';

युक्ति: यदि नमूने 1 हैं, तो परिणाम वास्तविक समय के फ्रैमरेट और फ्रैमेटाइम है।


0

यह KPexEA के उत्तर पर आधारित है और सरल मूविंग एवरेज देता है। आसान कॉपी और पेस्ट के लिए टाइपस्क्रिप्ट में टाइप और परिवर्तित:

परिवर्तनीय घोषणा:

fpsObject = {
  maxSamples: 100,
  tickIndex: 0,
  tickSum: 0,
  tickList: []
}

समारोह:

calculateFps(currentFps: number): number {
  this.fpsObject.tickSum -= this.fpsObject.tickList[this.fpsObject.tickIndex] || 0
  this.fpsObject.tickSum += currentFps
  this.fpsObject.tickList[this.fpsObject.tickIndex] = currentFps
  if (++this.fpsObject.tickIndex === this.fpsObject.maxSamples) this.fpsObject.tickIndex = 0
  const smoothedFps = this.fpsObject.tickSum / this.fpsObject.maxSamples
  return Math.floor(smoothedFps)
}

उपयोग (आपके ऐप में भिन्न हो सकता है):

this.fps = this.calculateFps(this.ticker.FPS)

-1

एक शुरुआत समय स्टोर करें और एक बार प्रति लूप में अपने फ्रैमेकेर को बढ़ाएं? हर कुछ सेकंड में आप केवल framecount / (अब - starttime) प्रिंट कर सकते हैं और फिर उन्हें पुन: व्यवस्थित कर सकते हैं।

संपादित करें: उफ़। इस बात की दोबारा ninja'ed

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.