117 votes

Images par seconde dans un jeu de calcul

Ce qui est un bon algorithme pour calculer les images par seconde dans un jeu ? Je veux montrer comme un numéro dans le coin de l’écran. Si j’ai juste regarder combien de temps il a fallu rendre la dernière image le numéro change trop vite.

Des points bonus si votre réponse met à jour chaque cadre et ne convergent pas différemment lorsque la cadence augmente vs diminue.

104voto

Martin Beckett Points 60406

Vous avez besoin d'une moyenne lissée, le plus simple est de prendre le courant de la réponse (le temps de dessiner la dernière image) et de le combiner avec la réponse précédente.

// eg.
time = time * 0.9 + last_frame * 0.1

En ajustant la 0.9 / 0.1 image vous pouvez modifier la "constante de temps" - c'est la façon dont rapidement le nombre répond à des changements. Une fraction plus importante en faveur de l'ancienne donne une réponse plus lente, plus lisse changement, une fraction importante en faveur de la nouvelle réponse donne une rapide évolution de la valeur. Évidemment, les deux facteurs doivent ajouter à!

59voto

KPexEA Points 6188

C’est ce que j’ai utilisé dans de nombreux jeux.

26voto

Wedge Points 11910

Eh bien, certainement

frames / sec = 1 / (sec / frame)

Mais, comme vous le soulignez, il y a beaucoup de variation dans le temps qu'il faut pour rendre une seule image, et à partir d'un point de vue de l'INTERFACE utilisateur mise à jour de la valeur de fps à la cadence n'est pas utilisable à tous (sauf le nombre est très stable).

Ce que vous voulez, c'est probablement une moyenne mobile ou une sorte de binning / réinitialisation du compteur.

Par exemple, vous pouvez maintenir une file d'attente de la structure de données, qui a tenu le temps de rendu pour chacune des dernières 30, 60, 100, ou quoi, avez-vous des images (vous pouvez même concevoir de telle sorte que la limite était réglable au moment de l'exécution). Pour déterminer un décent fps rapprochement, vous pouvez déterminer la moyenne des fps de tous les temps de rendu dans la file d'attente:

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

Lorsque vous avez fini d'afficher une nouvelle image de vous mettre en file d'attente d'un nouveau délai de rendu et de retirer un vieux de temps de rendu. Alternativement, vous pouvez retirer uniquement lorsque le total du temps de rendu supérieure à un seuil prédéterminé (par exemple, 1 sec). Vous pouvez maintenir le "dernier fps valeur", et une dernière mise à jour le timestamp de sorte que vous pouvez déclencher lors de la mise à jour du fps de figure, si vous le désirez. Mais avec une moyenne mobile si vous avez une mise en forme cohérente, l'impression d'un "instantané de la moyenne" fps sur chaque image serait probablement ok.

Une autre méthode serait d'avoir une réinitialisation de compteur. Maintenir un précis (milliseconde) timestamp, un compteur de trames, et une valeur de fps. Lorsque vous avez fini de rendu d'une image, d'incrémenter le compteur. Lorsque le compteur atteint une limite prédéfinie (par exemple, 100 images) ou lorsque le temps écoulé depuis le timestamp a passé quelques pré-valeur de consigne (par exemple, 1 sec), calculez les fps:

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

Ensuite, remettre le compteur à 0 et régler l'horodatage à l'heure actuelle.

13voto

apandit Points 2149

Incrémenter un compteur chaque fois que vous rendre un écran et effacer ce compteur pour un intervalle de temps sur laquelle vous voulez mesurer la fréquence d’images.

C’est à dire. Toutes les 3 secondes, obtenez compteur/3 et puis effacer le compteur.

11voto

Peter Jankuliak Points 1005

Il y a au moins deux façons de le faire:


Le premier est celui que d'autres ont mentionné ici avant moi. Je pense que c'est le plus simple et le moyen préféré. Vous avez juste à garder une trace de

  • cn: compteur de nombre d'images que vous avez rendus
  • time_start: le temps depuis que vous avez commencé à compter
  • time_now: à l'heure actuelle

Le calcul de l'ips dans ce cas est aussi simple que l'évaluation de cette formule:

  • FPS = cn / (time_now - time_start).

Puis il y a l'uber cool manière que vous aimeriez l'utiliser un jour:

Disons que vous avez " je " les cadres à prendre en compte. Je vais utiliser cette notation: f[0], f[1],..., f[i-1] pour décrire combien de temps il a fallu pour le rendu de l'image 0, l'image 1, ..., cadre (i-1) respectivement.

Example where i = 3

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

Ensuite, la définition mathématique de fps après je les cadres seraient

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

Et la même formule, mais en ne considérant i-1 trames.

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

Maintenant, le truc ici est de modifier la partie droite de la formule (1), de telle sorte qu'il contiendra la partie droite de la formule (2) et de la remplacer pour la gauche.

Comme (vous devriez y voir plus clair si vous l'écrivez sur un papier):

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)

Ainsi, selon cette formule (mes calculs découlant de compétences sont un peu rouillé), pour calculer le nouveau fps vous devez savoir que le fps à partir de l'image précédente, la durée qu'il a fallu pour l'affichage de la dernière image et le nombre d'images que vous avez rendus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X