Apa algoritme yang bagus untuk menghitung frame per detik dalam sebuah game? Saya ingin menunjukkannya sebagai angka di sudut layar. Jika saya hanya melihat berapa lama waktu yang dibutuhkan untuk membuat bingkai terakhir, angkanya berubah terlalu cepat.
Poin bonus jika jawaban Anda memperbarui setiap bingkai dan tidak menyatu secara berbeda saat frekuensi gambar meningkat vs menurun.
sumber
last_frame
tidak berarti (atau setidaknya tidak berarti) durasi frame sebelumnya; itu harus berarti nilaitime
yang Anda hitung untuk bingkai terakhir. Dengan cara ini, semua bingkai sebelumnya akan disertakan, dengan bingkai terbaru diberi bobot paling banyak.Inilah yang saya gunakan di banyak game.
sumber
tickindex = (tickindex + 1) % MAXSAMPLES;
Ya, tentu
Namun, seperti yang Anda tunjukkan, ada banyak variasi dalam waktu yang diperlukan untuk merender satu frame, dan dari perspektif UI, memperbarui nilai fps pada frekuensi gambar tidak dapat digunakan sama sekali (kecuali jumlahnya sangat stabil).
Apa yang Anda inginkan mungkin adalah rata-rata bergerak atau semacam penghitung binning / reset.
Misalnya, Anda dapat mempertahankan struktur data antrian yang menahan waktu rendering untuk masing-masing frame 30, 60, 100, atau what-have-you terakhir (Anda bahkan dapat mendesainnya sehingga batasnya dapat disesuaikan pada waktu proses). Untuk menentukan perkiraan fps yang layak, Anda dapat menentukan fps rata-rata dari semua waktu rendering dalam antrian:
Saat Anda selesai merender bingkai baru, Anda mengantrekan waktu rendering baru dan menghapus waktu rendering lama. Sebagai alternatif, Anda dapat melakukan dequeue hanya jika total waktu rendering melebihi beberapa nilai preset (mis. 1 detik). Anda dapat mempertahankan "nilai fps terakhir" dan stempel waktu terakhir diperbarui sehingga Anda dapat memicu kapan harus memperbarui angka fps, jika Anda menginginkannya. Meskipun dengan rata-rata bergerak jika Anda memiliki pemformatan yang konsisten, mencetak fps "rata-rata sesaat" pada setiap bingkai mungkin tidak masalah.
Metode lain adalah memiliki penghitung pengaturan ulang. Pertahankan stempel waktu yang tepat (milidetik), penghitung bingkai, dan nilai fps. Saat Anda selesai merender bingkai, tingkatkan penghitung. Ketika penghitung mencapai batas yang telah ditentukan sebelumnya (misalnya 100 bingkai) atau ketika waktu sejak cap waktu telah melewati beberapa nilai yang telah ditetapkan sebelumnya (misalnya 1 detik), hitung fps:
Kemudian setel ulang penghitung ke 0 dan setel stempel waktu ke waktu saat ini.
sumber
Tingkatkan penghitung setiap kali Anda merender layar dan menghapus penghitung itu untuk beberapa interval waktu yang Anda inginkan untuk mengukur laju bingkai.
Yaitu. Setiap 3 detik, dapatkan penghitung / 3 lalu bersihkan penghitung.
sumber
Setidaknya ada dua cara untuk melakukannya:
Yang pertama adalah yang disebutkan orang lain di sini sebelum saya. Saya pikir itu cara yang paling sederhana dan disukai. Anda hanya untuk melacak
Menghitung fps dalam kasus ini semudah mengevaluasi rumus ini:
Lalu ada cara paling keren yang mungkin ingin Anda gunakan suatu hari:
Katakanlah Anda memiliki bingkai 'i' untuk dipertimbangkan. Saya akan menggunakan notasi ini: f [0], f [1], ..., f [i-1] untuk menjelaskan berapa lama waktu yang dibutuhkan untuk merender frame 0, frame 1, ..., frame (i-1 ) masing-masing.
Kemudian, definisi matematis dari fps setelah i frame akan menjadi
Dan rumusnya sama tetapi hanya mempertimbangkan frame i-1.
Sekarang triknya di sini adalah memodifikasi sisi kanan rumus (1) sedemikian rupa sehingga akan berisi sisi kanan rumus (2) dan menggantinya dengan sisi kirinya.
Suka begitu (Anda akan melihatnya lebih jelas jika Anda menulisnya di atas kertas):
Jadi menurut rumus ini (keterampilan matematika saya agak berkarat), untuk menghitung fps baru Anda perlu mengetahui fps dari frame sebelumnya, durasi yang dibutuhkan untuk membuat frame terakhir dan jumlah frame yang Anda miliki. diberikan.
sumber
Ini mungkin berlebihan bagi kebanyakan orang, itulah mengapa saya tidak mempostingnya saat saya menerapkannya. Tapi itu sangat kuat dan fleksibel.
Ini menyimpan Antrean dengan waktu bingkai terakhir, sehingga secara akurat dapat menghitung nilai FPS rata-rata jauh lebih baik daripada hanya mempertimbangkan bingkai terakhir.
Ini juga memungkinkan Anda untuk mengabaikan satu frame, jika Anda melakukan sesuatu yang Anda tahu akan mengacaukan waktu frame itu secara artifisial.
Ini juga memungkinkan Anda untuk mengubah jumlah bingkai yang akan disimpan dalam Antrean saat dijalankan, sehingga Anda dapat mengujinya dengan cepat apa nilai terbaik untuk Anda.
sumber
Jawaban bagus di sini. Hanya bagaimana Anda menerapkannya tergantung pada apa yang Anda butuhkan. Saya lebih suka running average sendiri "time = time * 0.9 + last_frame * 0.1" oleh orang di atas.
namun saya pribadi lebih suka membobotkan rata-rata saya lebih banyak ke data yang lebih baru karena dalam permainan itu SPIKES yang paling sulit untuk dihancurkan dan karenanya paling menarik bagi saya. Jadi saya akan menggunakan sesuatu yang lebih seperti pemisahan .7 \ .3 akan membuat lonjakan muncul lebih cepat (meskipun efeknya akan turun layar lebih cepat juga .. lihat di bawah)
Jika fokus Anda adalah pada waktu RENDERING, maka pemisahan .9.1 berfungsi cukup baik karena cenderung lebih mulus. Meskipun untuk gameplay / AI / physics spikes lebih menjadi perhatian karena ITU biasanya akan membuat game Anda terlihat berombak (yang seringkali lebih buruk daripada frame rate rendah dengan asumsi kami tidak turun di bawah 20 fps)
Jadi, yang akan saya lakukan adalah menambahkan sesuatu seperti ini:
(isi 3.0f dengan besaran apa pun yang Anda anggap sebagai lonjakan yang tidak dapat diterima) Ini akan memungkinkan Anda menemukan dan dengan demikian menyelesaikan masalah FPS pada akhir frame yang terjadi.
sumber
time = time * 0.9 + last_frame * 0.1
kalkulasi rata - rata yang membuat tampilan berubah dengan mulus.Sistem yang jauh lebih baik daripada menggunakan sejumlah besar framerate lama adalah dengan melakukan sesuatu seperti ini:
Metode ini menggunakan memori yang jauh lebih sedikit, memerlukan kode yang jauh lebih sedikit, dan lebih mementingkan frekuensi gambar terbaru daripada frekuensi gambar lama sambil tetap menghaluskan efek perubahan frekuensi gambar yang tiba-tiba.
sumber
Anda dapat menyimpan penghitung, menaikkannya setelah setiap bingkai dirender, lalu mengatur ulang penghitung saat Anda berada di detik baru (menyimpan nilai sebelumnya sebagai # bingkai detik terakhir yang dirender)
sumber
JavaScript:
sumber
Berikut contoh lengkapnya, menggunakan Python (tetapi mudah disesuaikan dengan bahasa apa pun). Ini menggunakan persamaan pemulusan dalam jawaban Martin, jadi hampir tidak ada overhead memori, dan saya memilih nilai yang berhasil untuk saya (jangan ragu untuk bermain-main dengan konstanta untuk beradaptasi dengan kasus penggunaan Anda).
sumber
Setel penghitung ke nol. Setiap kali Anda menggambar bingkai, tambahkan penghitung. Setelah setiap detik mencetak penghitung. busa, bilas, ulangi. Jika Anda menginginkan kredit ekstra, pertahankan penghitung lari dan bagi dengan jumlah total detik untuk rata-rata lari.
sumber
Dalam pseudocode (c ++ like), keduanya adalah yang saya gunakan dalam aplikasi pemrosesan gambar industri yang harus memproses gambar dari satu set kamera yang dipicu secara eksternal. Variasi dalam "kecepatan bingkai" memiliki sumber yang berbeda (produksi lebih lambat atau lebih cepat pada sabuk) tetapi masalahnya sama. (Saya berasumsi bahwa Anda memiliki panggilan timer.peek () sederhana yang memberi Anda sesuatu seperti nr msec (nsec?) Sejak aplikasi dimulai atau panggilan terakhir)
Solusi 1: Cepat tetapi tidak diperbarui setiap frame
Solusi 2: Memperbarui setiap frame, membutuhkan lebih banyak memori dan CPU
sumber
sumber
Bagaimana saya melakukannya!
Dengan kata lain, detak jam melacak detak. Jika ini pertama kalinya, ini mengambil waktu saat ini dan meletakkannya di 'tickstart'. Setelah tick pertama, variabel 'fps' sama dengan jumlah tick pada tick clock dibagi waktu dikurangi waktu dari tick pertama.
Fps adalah integer, oleh karena itu "(int)".
sumber
Begini cara saya melakukannya (di Java):
sumber
Di Ketik, saya menggunakan algoritma ini untuk menghitung rata-rata framerate dan frametime:
pemakaian:
Tip: Jika sampel adalah 1, hasilnya adalah framerate dan frametime waktu nyata.
sumber
Ini didasarkan pada jawaban KPexEA dan memberikan Rata-Rata Bergerak Sederhana. Dirapikan dan diubah menjadi TypeScript agar mudah disalin dan ditempel:
Deklarasi variabel:
Fungsi:
Penggunaan (mungkin berbeda di aplikasi Anda):
sumber
menyimpan waktu mulai dan menaikkan framecounter Anda sekali per loop? setiap beberapa detik Anda cukup mencetak framecount / (Now - starttime) dan kemudian menginisialisasi ulang.
edit: oops. ninja ganda
sumber