Quand devrais-je utiliser un pas de temps fixe ou variable?

256

Une boucle de jeu doit-elle être basée sur des pas de temps fixes ou variables? Est-ce qu'on est toujours supérieur ou est-ce que le bon choix varie selon les jeux?

Pas de temps variable

Les mises à jour physiques reçoivent un argument "temps écoulé depuis la dernière mise à jour" et sont donc dépendantes du nombre d'images par seconde. Cela peut vouloir dire faire des calculs comme position += distancePerSecond * timeElapsed.

Avantages : lisse, plus facile à coder
Inconvénients : non déterministe, imprévisible à très petites ou grandes étapes

Exemple de deWiTTERS :

while( game_is_running ) {
    prev_frame_tick = curr_frame_tick;
    curr_frame_tick = GetTickCount();
    update( curr_frame_tick - prev_frame_tick );
    render();
}

Pas de temps fixe

Les mises à jour peuvent même ne pas accepter un "temps écoulé", car elles supposent que chaque mise à jour dure une période donnée. Les calculs peuvent être faits comme position += distancePerUpdate. L'exemple inclut une interpolation pendant le rendu.

Avantages : prévisible, déterministe (plus facile à synchroniser au réseau?), Code de calcul plus clair
Inconvénients : non synchronisé pour surveiller v-sync (provoque des graphiques instables sauf si vous interpolez), cadence maximale limitée (sauf si vous interpolez), difficile à travailler dans des cadres assumer des pas de temps variables (comme Pyglet ou Flixel )

Exemple de deWiTTERS :

while( game_is_running ) {
    while( GetTickCount() > next_game_tick ) {
        update();
        next_game_tick += SKIP_TICKS;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    render( interpolation );
}

Quelques ressources

Nick Sonneveld
la source
6
Utilisez des pas de temps variables pour votre jeu et des étapes fixes pour la physique
Daniel Little
7
Je ne dirais pas que le pas de temps variable est plus facile à coder avec précision, car avec un pas de temps fixe, vous "n'avez pas à confondre tous les calculs avec la variable timeElapsed partout". Pas si difficile, mais je n’ajouterais pas "plus facile à coder" en tant que professionnel.
pek
En vérité, je pense que je faisais allusion à la nécessité de ne pas interpoler par intervalles de temps variables.
Nick Sonneveld
@pek je suis d'accord avec toi. Le pas de temps variable a une boucle de jeu codée plus simple mais vous devez coder davantage dans vos entités qui traitent de cette variabilité afin de "cadrer". Le pas de temps fixe a une boucle de jeu plus complexe à coder (car vous devez compenser avec précision les variances d’approximation temporelle et recalculer le délai supplémentaire à ajouter ou le nombre de mises à jour à ignorer pour le garder fixe), mais un codage plus simple pour les entités toujours avoir à faire face au même intervalle de temps. Dans l'ensemble, aucune des approches n'est clairement plus simple que l'autre.
Shivan Dragon
Vous pouvez vérifier ces visuall de cet outil: s3.amazonaws.com/picobots/assets/unity/jerky-motion/… bien que cela ne vous donne pas une idée de ce à quoi ils ressembleraient quand le taux de trame varie
Buddy

Réponses:

134

Il y a deux problèmes liés à la question.

  • Le taux de pas physique devrait-il être lié au taux de trame?
  • La physique devrait-elle être développée avec des deltas constants?

Dans Glen fielder, fixez votre pas de temps, il dit de "libérer la physique". Cela signifie que votre fréquence d'actualisation physique ne doit pas être liée à votre fréquence d'images.

Par exemple, si le nombre d'images par seconde est 50 images par seconde et que la simulation est conçue pour s'exécuter à 100 images par seconde, nous devons suivre deux étapes de physique chaque mise à jour de l'affichage pour maintenir la physique en synchronisation.

Erin Catto recommande également cela dans Box2D.

Donc, ne liez pas le pas de temps à votre fréquence d'images (à moins que vous ne deviez le faire vraiment).

Le taux de progression de la physique doit-il être lié à votre fréquence d'images? Non.


Les pensées d'Erin sur le pas fixe vs le pas variable:

Box2D utilise un algorithme de calcul appelé intégrateur. Les intégrateurs simulent les équations de la physique à des moments précis. ... Nous n'aimons pas le pas de temps pour changer beaucoup. Un pas de temps variable produit des résultats variables, ce qui rend difficile le débogage.

Les pensées de Glen sur le pas fixe vs variable:

Fixez votre timestep ou exploser

... Si vous avez une série de contraintes de ressort très rigides pour les amortisseurs dans une simulation de voiture, alors de minuscules changements dans dt peuvent réellement faire exploser la simulation. ...

La physique devrait-elle être développée avec des deltas constants? Oui.


La façon de faire progresser la physique avec des deltas constants et de ne pas lier votre fréquence d'actualisation physique à la cadence est d'utiliser un accumulateur de temps. Dans mon jeu, je vais encore plus loin. J'applique une fonction de lissage au temps entrant. De cette façon, les pointes FPS importantes n'entraînent pas un saut physique trop important dans la physique, elles sont simulées plus rapidement pour une image ou deux.

Vous mentionnez qu'avec un taux fixe, la physique ne serait pas synchronisée avec l'affichage. Cela est vrai si le taux de physique cible est proche de la fréquence d'images cible. C'est pire le taux de trame est plus grand que le taux de physique. En général, il est préférable de cibler un taux de mise à jour physique égal au double de votre FPS cible, si vous en avez les moyens.

Si vous ne pouvez pas vous permettre une cadence de mise à jour physique importante, envisagez d'interpoler les positions des graphiques entre les images pour que les graphiques dessinés semblent bouger plus doucement que la physique ne le fait réellement.

deft_code
la source
1
J'ai joué à The Floor is Jelly avant et après la mise à niveau de ma machine et c'était idiot: ce n'était pas la même chose parce que la physique était effectivement invoquée depuis la boucle de jeu (et donc liée au débit d'images) et non depuis une minuterie. Mon ancienne machine était très mauvaise, elle passait constamment du ralenti au trop rapide, ce qui avait un impact considérable sur le gameplay. Maintenant, c'est juste à un mouvement très rapide. Quoi qu’il en soit, ce jeu est un bel exemple de la problématique que peut poser ce problème (toujours un jeu mignon).
MasterMastic
55

Je pense qu'il y a vraiment 3 options, mais vous les listez comme seulement 2:

Option 1

Ne fais rien. Essayez de mettre à jour et de rendre à un certain intervalle, par exemple 60 fois par seconde. Si elle prend du retard, laissez-la et ne vous inquiétez pas. Les jeux ralentiront lentement si le processeur ne parvient pas à suivre votre rythme. Cette option ne fonctionnera pas du tout pour les jeux multi-utilisateurs en temps réel, mais convient pour les jeux à un joueur et a été utilisée avec succès dans de nombreux jeux.

Option 2

Utilisez le temps de décalage entre chaque mise à jour pour modifier le mouvement des objets. En théorie, c'est bien, surtout si rien dans votre jeu n'accélère ou ne ralentit, mais se déplace à une vitesse constante. En pratique, de nombreux développeurs l’implémentent mal, ce qui peut conduire à une détection et à une physique des collisions incohérentes. Il semble que certains développeurs pensent que cette méthode est plus simple qu’elle ne l’est. Si vous souhaitez utiliser cette option, vous devez considérablement améliorer votre jeu et faire ressortir des algorithmes et des calculs compliqués, par exemple en utilisant un intégrateur physique Verlet (plutôt que l'Euler standard utilisé par la plupart des gens) et en utilisant des rayons pour détecter les collisions. plutôt que de simples contrôles à distance Pythagore. Il y a quelque temps, j'ai posé une question à ce sujet sur Stack Overflow et j'ai obtenu d'excellentes réponses:

https://stackoverflow.com/questions/153507/calculate-the-position-of-an-accelerating-body-after-a-certain- time

Option 3

Utilisez l'approche "Fixez votre pas de temps" de Gaffer. Mettez à jour le jeu par étapes fixes comme dans l'option 1, mais faites-le plusieurs fois par image rendue (en fonction du temps écoulé), de sorte que la logique du jeu reste en temps réel tout en conservant des étapes discrètes. De cette façon, la logique de jeu, comme les intégrateurs d'Euler, et la détection de collision simple fonctionnent toujours. Vous avez également la possibilité d'interpoler des animations graphiques en fonction du temps delta, mais cela ne concerne que les effets visuels et rien qui affecte votre logique de jeu principale. Vous pouvez éventuellement avoir des problèmes si vos mises à jour sont très intensives. Si les mises à jour prennent du retard, vous en aurez de plus en plus à suivre, ce qui pourrait rendre votre jeu encore moins réactif.

Personnellement, j'aime bien l'option 1 lorsque je peux m'en tirer et l'option 3 lorsque je dois effectuer une synchronisation en temps réel. Je respecte l’option 2 peut être une bonne option lorsque vous savez ce que vous faites, mais je connais suffisamment mes limites pour en rester à l’écart.

Iain
la source
En ce qui concerne l’option 2: je ne suis pas sûr qu’un raycast puisse être plus rapide que les vérifications de distance pythagoras, sauf si vous êtes très brutal dans votre application de pythagoras, mais un raycast sera également très coûteux si vous n’ajoutez pas de chaîne large.
Kaj
4
Si vous utilisez Verlet avec des pas de temps inégaux, vous jetez le bébé avec l'eau du bain. La raison pour laquelle Verlet est aussi stable qu’elle est, c’est que les erreurs s’annulent aux étapes suivantes. Si les pas de temps ne sont pas égaux, cela ne se produit pas et vous vous retrouvez dans une terre en pleine explosion.
drxzcl
Option 3 - Cela ressemble à la description de l'approche de XNA par Joel Martinez.
topright
1
C'est une très bonne réponse. Les trois options ont leur place et il est important de comprendre quand elles sont appropriées.
Adam Naylor
Tous les MMO sur lesquels j'ai travaillé (EQ, Landmark / EQNext [cry], PS2 [brièvement] et ESO), nous avons toujours utilisé un temps de trame variable. Je n'ai jamais participé à cette décision, je me suis présenté après coup et utilisé ce que d'autres ont décidé.
Mark Storer
25

J'aime beaucoup la manière dont XNA Framework implémente le pas de temps fixe. Si un appel de tirage prend un peu trop longtemps, il appelle la mise à jour à plusieurs reprises jusqu'à ce qu'il "rattrape". Shawn Hargreaves le décrit ici:
http://blogs.msdn.com/b/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx

En 2.0, le comportement Draw a changé:

  • Appelez Update autant de fois que nécessaire pour rattraper l'heure actuelle
  • Appelez Draw une fois
  • Attendez qu'il soit l'heure de la prochaine mise à jour

À mon avis, le plus gros professionnel à ce sujet est celui que vous avez mentionné, qui simplifie considérablement tous les calculs de code de jeu, car vous n'avez pas à inclure cette variable de temps dans tous les sens.

note: xna supporte aussi le timestep variable, c'est juste un paramètre.

Joel Martinez
la source
C'est le moyen le plus courant de faire une boucle de jeu. Toutefois, la vie de la batterie n’est pas excellente lorsque vous travaillez avec des appareils mobiles.
knight666
1
@ Knight666; Êtes-vous en train de suggérer qu'en utilisant un pas de temps plus long, le nombre réduit d'itérations permettra de sauver la vie?
falstro
C'est toujours une mise à jour variable - le delta de mise à jour change en fonction du temps de rendu de l'image par rapport à une valeur fixe (c'est-à-dire, 1 / 30ème de seconde).
Dennis Munsie
1
@Dennis: si j'ai bien compris, la fonction Update est appelée avec un delta fixe ...
RCIX
3
@ Knight666 Euh - comment comptez-vous cela? Si vous avez vsync sur et ne bégayez pas - ces méthodes devraient être identiques! Et si vous avez désactivé vsync, vous mettez à jour plus souvent que nécessaire et vous gaspillez probablement le processeur (et donc la batterie) en ne le laissant pas inactif!
Andrew Russell
12

Il existe une autre option: découpler la mise à jour du jeu et la mise à jour de la physique. Adapter le moteur physique au timestep du jeu pose un problème si vous corrigez votre timestep (le problème de la perte de contrôle du fait que l'intégration a besoin de plus de timesteps qui prennent plus de temps et de plus de temps), ou si vous le modifiez et obtenez une physique sans fioritures.

La solution que je vois souvent est de faire fonctionner la physique sur un pas de temps fixe, dans un thread différent (sur un noyau différent). Le jeu interpole ou extrapole en fonction des deux dernières images valides qu'il peut récupérer. L'interpolation ajoute un certain retard, l'extrapolation ajoute une certaine incertitude, mais votre physique sera stable et ne fera pas perdre le contrôle de votre temps.

Ce n'est pas trivial à mettre en œuvre, mais pourrait se révéler une preuve pour l'avenir.

Kaj
la source
8

Personnellement, j'utilise une variation de pas de temps variable (qui est en quelque sorte un hybride de fixe et de variable, je pense). J'ai testé ce système de chronométrage de plusieurs manières, et je me sers de l'utiliser pour de nombreux projets. Est-ce que je le recommande pour tout? Probablement pas.

Mes boucles de jeu calculent la quantité d'images à mettre à jour (appelons-le F), puis effectuent F mises à jour de la logique discrète. Chaque mise à jour logique suppose une unité de temps constante (qui correspond souvent à 1 / 100ème de seconde dans mes jeux). Chaque mise à jour est effectuée en séquence jusqu'à ce que toutes les mises à jour de la logique discrète F soient effectuées.

Pourquoi des mises à jour discrètes en étapes logiques? Eh bien, si vous essayez d’utiliser des étapes continues et que vous rencontrez un problème physique, les vitesses et les distances à parcourir calculées sont multipliées par une valeur énorme de F.

Une mauvaise mise en œuvre de ceci ne ferait que F = heure actuelle - dernières mises à jour de l'heure du cadre. Mais si les calculs prennent trop de retard (parfois en raison de circonstances indépendantes de votre volonté comme un autre processus volant du temps CPU), vous verrez rapidement de terribles sauts. Rapidement, le FPS stable que vous avez essayé de maintenir devient SPF.

Dans mon jeu, j'autorise un ralentissement «en douceur» (en quelque sorte) pour limiter la quantité de rattrapage logique qui devrait être possible entre deux matchs nuls. Je le fais en fixant: F = min (F, MAX_FRAME_DELTA) qui a généralement MAX_FRAME_DELTA = 2/100 * s ou 3/100 * s. Ainsi, au lieu de sauter les images trop loin derrière la logique du jeu, supprimez toute perte d’image importante (ce qui ralentit le processus), récupérez quelques images, dessinez, puis réessayez.

En faisant cela, je m'assure également que les commandes du lecteur restent synchronisées avec ce qui est réellement affiché à l'écran.

Le pseudocode du produit final ressemble à ceci (le delta est F mentionné plus haut):

// Assume timers have 1/100 s resolution
const MAX_FRAME_DELTA = 2
// Calculate frame gap.
var delta = current time - last frame time
// Clamp.
delta = min(delta, MAX_FRAME_RATE)
// Update in discrete steps
for(i = 0; i < delta; i++)
{
    update single step()
}
// Caught up again, draw.
render()

Ce type de mise à jour ne convient pas à tout, mais pour les jeux d'arcade, je préférerais que le jeu ralentisse, car il y a beaucoup de choses qui se passent plutôt que de manquer d'images et de perdre le contrôle du joueur. Je préfère également cela à d’autres approches à pas de temps variable qui finissent par avoir des problèmes irréversibles causés par une perte de trame.

Exagération
la source
Fortement d'accord avec ce dernier point; Dans à peu près tous les jeux, les entrées devraient «ralentir» lorsque le nombre d'images par seconde diminue. Même si cela n’est pas possible dans certains jeux (multijoueurs), ce serait encore mieux si cela était possible. : P On se sent tout simplement mieux que d’avoir un long frame puis de laisser le monde du jeu «sauter» à l’état «correct».
Ipsquiggle
Sans matériel fixe comme une machine d'arcade, le fait de ralentir la simulation lorsque les jeux d'arcade ralentissent la simulation rend la lecture plus lente sur une machine plus lente.
Joe, ça ne compte que si nous nous soucions de "tricher". La plupart des jeux modernes ne sont pas vraiment une compétition entre joueurs, mais une expérience amusante.
Iain
1
Iain, nous parlons spécifiquement de jeux de style arcade ici, qui sont traditionnellement axés sur le classement par liste de scores. Je joue une tonne de shmups, et je sais que si je trouvais quelqu'un qui affichait des scores avec un ralentissement artificiel au classement, je voudrais que ses scores soient effacés.
Ne tentez pas de diminuer votre réponse, mais j’interpréterais cela comme une étape fixe dans laquelle le rendu n’est pas directement lié au taux de mise à jour de la physique, sauf que le rattrapage sur la physique a la priorité sur le rendu. Il a certainement de bonnes qualités.
AaronLS
6

Cette solution ne s'applique pas à tout, mais il existe un autre niveau de variable timestep - variable timestep pour chaque objet du monde.

Cela semble compliqué, et cela peut être, mais considérez-le comme une modélisation de votre jeu comme une simulation d'événement discret. Chaque mouvement de joueur peut être représenté comme un événement qui commence au début du mouvement et se termine à la fin du mouvement. S'il existe une interaction nécessitant le fractionnement de l'événement (une collision par exemple), l'événement est annulé et un autre événement est ajouté à la file d'attente des événements (qui est probablement une file d'attente prioritaire triée par heure de fin de l'événement).

Le rendu est totalement détaché de la file d'attente des événements. Le moteur d’affichage interpole les points entre les heures de début et de fin de l’événement selon les besoins, et peut être aussi précis ou aussi bâclé que nécessaire dans cette estimation.

Pour voir une implémentation complexe de ce modèle, voir le simulateur d’espace EXOFLIGHT . Il utilise un modèle d'exécution différent de la plupart des simulateurs de vol - un modèle basé sur les événements, plutôt que le modèle traditionnel à tranche de temps fixe. La boucle principale de base de ce type de simulation ressemble à ceci, en pseudo-code:

while (game_is_running)
{
   world.draw_to_screen(); 
   world.get_player_input(); 
   world.consume_events_until(current_time + time_step); 
   current_time += time_step; 
}

La principale raison d’en utiliser un dans un simulateur spatial est la nécessité de fournir une accélération temporelle arbitraire sans perte de précision. Certaines missions dans EXOFLIGHT peuvent prendre des années de jeu et même une option d’accélération 32x serait insuffisante. Vous auriez besoin de plus de 1 000 000 x d’accélération pour un sim utilisable, ce qui est difficile à réaliser dans un modèle en tranche de temps. Avec le modèle basé sur les événements, nous obtenons des taux de temps arbitraires, allant de 1 s = 7 ms à 1 s = 1 an.

Changer le taux de temps ne change pas le comportement de la sim, qui est une caractéristique essentielle. S'il n'y a pas assez de puissance CPU disponible pour exécuter le simulateur à la vitesse souhaitée, les événements s'empileront et nous pourrons limiter l'actualisation de l'interface utilisateur jusqu'à ce que la file d'attente des événements soit effacée. De même, nous pouvons faire avancer la simulation autant que nous le souhaitons et nous assurer que nous ne gaspillons pas le processeur ni ne sacrifions la précision.

En résumé, nous pouvons modéliser un véhicule sur une longue orbite tranquille (en utilisant l’intégration Runge-Kutta) et un autre véhicule rebondissant simultanément sur le sol - les deux véhicules seront simulés avec une précision appropriée, car nous n’avons pas d’horodatage global.

Inconvénients: Complexité et absence de tout moteur physique standard prenant en charge ce modèle :)

Sehugg
la source
5

Le pas de temps fixe est utile pour prendre en compte la précision en virgule flottante et rendre les mises à jour cohérentes.

C'est un simple morceau de code, il serait donc utile de l'essayer et de voir si cela fonctionne pour votre jeu.

now = currentTime
frameTime = now - lastTimeStamp // time since last render()
while (frameTime > updateTime)
    update(timestep)
    frameTime -= updateTime     // update enough times to catch up
                                // possibly leaving a small remainder
                                // of time for the next frame

lastTimeStamp = now - frameTime // set last timestamp to now but
                                // subtract the remaining frame time
                                // to make sure the game will still
                                // catch up on those remaining few millseconds
render()

Le principal problème de l'utilisation d'un pas de temps fixe est que les joueurs dotés d'un ordinateur rapide ne pourront pas utiliser cette vitesse. Rendu à 100 images par seconde lorsque le jeu est mis à jour uniquement à 30 images par seconde est identique à un rendu à 30 images par seconde.

Cela dit, il est possible d’utiliser plus d’un pas de temps fixe. 60fps peuvent être utilisés pour mettre à jour des objets triviaux (tels que des interfaces utilisateur ou des images-objets animées) et 30fps pour mettre à jour des systèmes non triviaux (tels que la physique et) et même des minuteries plus lentes à effectuer en arrière-plan, telles que la suppression d'objets inutilisés, de ressources, etc.

Nick Bedford
la source
2
Si le jeu est créé avec soin, la méthode de rendu peut effectuer une interpolation pour effectuer des mises à jour à 30 ips, ce qui est différent du rendu à 30 ips.
Ricket
3

En plus de ce que vous avez déjà dit, cela peut venir du sentiment que vous voulez que votre jeu ait. À moins que vous ne puissiez garantir que vous aurez toujours une fréquence d'images constante, vous risquez probablement un ralentissement quelque part et des pas de temps fixes et variables seront très différents. Fixé aura l'effet de ralentir votre jeu pendant un certain temps, ce qui peut parfois être l'effet voulu (regardez un jeu de tir à l'ancienne, comme Ikaruga, où des explosions massives provoquent un ralentissement après avoir battu un boss). Des pas de temps variables maintiendront les choses à la vitesse voulue, mais il se peut que des changements soudains de position, etc., empêchent le joueur d'effectuer ses actions avec précision.

Je ne vois pas vraiment qu'un pas de temps fixe faciliterait les choses sur un réseau, ils seraient tous légèrement désynchronisés pour commencer et un ralentissement sur une machine, mais pas une autre ne ferait en sorte que les choses soient plus désynchronisées.

Je me suis toujours penché personnellement pour l'approche variable, mais ces articles ont des choses intéressantes à penser. Cependant, j’ai encore trouvé des étapes fixes assez courantes, en particulier sur les consoles où l’on pense que le framerate est de 60 ips par rapport aux taux très élevés pouvant être atteints sur un PC.

identitécrisisuk
la source
5
Vous devez absolument lire le lien Gaffer on games dans le message original. Je ne pense pas que ce soit une mauvaise réponse en tant que telle, je ne vais donc pas voter contre, mais je ne souscris à aucun de vos arguments .
falstro
Je ne pense pas que ralentir dans un jeu en raison d'un pas de temps fixe puisse jamais être intentionnel, car c'est à cause d'un manque de contrôle. Le manque de contrôle revient par définition à céder au hasard et ne peut donc être intentionnel. C’est peut-être ce que vous aviez à l’esprit, mais c’est tout ce que j’aimerais dire. En ce qui concerne le pas de temps fixe dans la mise en réseau, il y a un avantage certain, car il est pratiquement impossible de synchroniser les moteurs physiques sur deux machines différentes sans le même pas de temps. Étant donné que la seule option à synchroniser serait l'envoi de toutes les transformations d’entités, ce serait beaucoup trop lourd en bande passante.
Kaj
0

Utilisez l'approche "Fixez votre pas de temps" de Gaffer. Mettez à jour le jeu par étapes fixes comme dans l'option 1, mais faites-le plusieurs fois par image rendue (en fonction du temps écoulé), de sorte que la logique du jeu reste en temps réel tout en conservant des étapes discrètes. De cette façon, la logique de jeu, comme les intégrateurs d'Euler, et la détection de collision simple fonctionnent toujours. Vous avez également la possibilité d'interpoler des animations graphiques en fonction du temps delta, mais cela ne concerne que les effets visuels et rien qui affecte votre logique de jeu principale. Vous pouvez éventuellement avoir des problèmes si vos mises à jour sont très intensives. Si les mises à jour prennent du retard, vous en aurez de plus en plus à suivre, ce qui pourrait rendre votre jeu encore moins réactif.

Personnellement, j'aime bien l'option 1 lorsque je peux m'en tirer et l'option 3 lorsque je dois effectuer une synchronisation en temps réel. Je respecte l’option 2 peut être une bonne option lorsque vous savez ce que vous faites, mais je connais suffisamment mes limites pour ne pas en subir les conséquences


la source
Si vous allez voler des réponses, créditez au moins la personne!
PrimRock
0

J'ai trouvé que des pas de temps fixes synchronisés à 60fps donnaient une animation en miroir. Ceci est particulièrement important pour les applications de réalité virtuelle. Toute autre chose est physiquement nauséabonde.

Des pas de temps variables ne conviennent pas à la réalité virtuelle. Jetez un coup d’œil à quelques exemples d’Unity VR qui utilisent des pas de temps variables. C'est désagréable.

La règle est que si votre jeu 3D est fluide en mode VR, il sera excellent en mode non-VR.

Comparez ces deux (applications de carton VR)

(Pas de temps variables)

(Timesteps fixes)

Votre jeu doit être multithread afin d'obtenir un timestep / framerate cohérent. La physique, l'interface utilisateur et le rendu doivent être séparés en threads dédiés. Il est hideux de les synchroniser avec PITA, mais les résultats obtenus vous permettent d'obtenir le rendu lisse que vous souhaitez (en particulier pour VR).

Les jeux mobiles sont en particulier. difficile car les processeurs et les GPU intégrés ont des performances limitées. Utilisez GLSL (argot) avec parcimonie pour décharger le plus de travail possible de la CPU. Attention, le fait de transmettre des paramètres au GPU consomme des ressources de bus.

Gardez toujours votre framerate affiché pendant le développement. Le vrai jeu est de le garder fixe à 60fps. C'est le taux de synchronisation natif pour la plupart des écrans et également pour la plupart des globes oculaires.

La structure que vous utilisez doit pouvoir vous informer d'une demande de synchronisation ou utiliser un minuteur. N'insérez pas de délai sommeil / attente pour y parvenir - même de légères variations sont perceptibles.

Dominic Cerisano
la source
0

Les intervalles de temps variables concernent les procédures qui doivent être exécutées aussi souvent que possible: cycles de rendu, gestion des événements, fonctions réseau, etc.

Les pas de temps fixes sont indiqués lorsque vous avez besoin que quelque chose soit prévisible et stable. Cela inclut, mais ne se limite pas à la physique et à la détection de collision.

Concrètement, la physique et la détection de collision devraient être dissociées de tout le reste, sur son propre pas de temps. La raison pour laquelle de telles procédures sont exécutées sur un petit pas de temps fixe est de les garder précises. La magnitude des impulsions dépend fortement du temps. Si l'intervalle devient trop grand, la simulation devient instable et des trucs fous se produisent comme une balle qui rebondit sur le sol ou qui sortent du monde du jeu, ce qui n'est pas souhaitable.

Tout le reste peut fonctionner à un pas de temps variable (bien que, professionnellement, c'est souvent une bonne idée de permettre le verrouillage du rendu sur un pas de temps fixe). Pour qu'un moteur de jeu soit réactif, des éléments tels que les messages réseau et les entrées utilisateur doivent être traités dès que possible, ce qui signifie que l'intervalle entre les scrutations doit idéalement être aussi court que possible. Cela signifie généralement variable.

Tout le reste peut être traité de manière asynchrone, faisant de la synchronisation un point discutable.

Ian Young
la source