Es gibt eine lange Geschichte, wie wir zu diesem gemeinsamen Kongress gekommen sind, mit vielen faszinierenden Herausforderungen auf dem Weg, also werde ich versuchen, ihn schrittweise zu motivieren:
1. Problem: Geräte laufen unterschiedlich schnell
Versuchen Sie jemals, ein altes DOS-Spiel auf einem modernen PC zu spielen, und es läuft unspielbar schnell - nur eine Unschärfe?
Viele alte Spiele hatten eine sehr naive Update-Schleife - sie sammelten Eingaben, aktualisierten den Spielstatus und renderten so schnell, wie es die Hardware zuließ, ohne zu berücksichtigen, wie viel Zeit vergangen war. Das heißt, sobald sich die Hardware ändert, ändert sich das Gameplay.
Im Allgemeinen möchten wir, dass unsere Spieler auf einer Reihe von Geräten ein konsistentes Spielerlebnis und Spielgefühl haben (sofern sie bestimmte Mindestanforderungen erfüllen), unabhängig davon, ob sie das letztjährige Telefon oder das neueste Modell, einen Top-End-Gaming-Desktop oder ein Tablet verwenden mittelgroßer Laptop.
Insbesondere für Spiele, die wettbewerbsfähig sind (entweder im Mehrspielermodus oder über Bestenlisten), möchten wir nicht, dass Spieler, die auf einem bestimmten Gerät laufen, einen Vorteil gegenüber anderen haben, da sie schneller laufen oder mehr Zeit haben, um zu reagieren.
Die todsichere Lösung besteht darin, die Rate festzulegen, mit der wir Spielstatusaktualisierungen durchführen. Auf diese Weise können wir garantieren, dass die Ergebnisse immer gleich sind.
2. Warum also nicht einfach die Framerate sperren (z. B. mit VSync) und trotzdem die Gameplay-Statusaktualisierungen und das Rendering im Gleichschritt ausführen?
Dies kann funktionieren, ist aber für das Publikum nicht immer angenehm. Es gab eine lange Zeit, als das Laufen mit soliden 30 fps als Goldstandard für Spiele galt. Spieler erwarten jetzt routinemäßig mindestens 60 fps, insbesondere in Multiplayer-Actionspielen, und einige ältere Titel sehen jetzt merklich abgehackt aus, da sich unsere Erwartungen geändert haben. Es gibt auch eine Gesangsgruppe von PC-Spielern, die überhaupt gegen die Framerate-Sperre sind. Sie haben eine Menge für ihre hochmoderne Hardware bezahlt und möchten diesen Computermuskel für die reibungsloseste Wiedergabe mit höchster Wiedergabetreue verwenden können.
Insbesondere in der VR ist die Framerate das A und O, und der Standard schleicht sich immer weiter an. Zu Beginn der jüngsten Wiederbelebung von VR liefen die Spiele häufig mit etwa 60 fps. Jetzt ist 90 mehr Standard, und Hardware wie die PSVR beginnt, 120 zu unterstützen. Dies dürfte noch weiter steigen. Wenn also ein VR-Spiel seine Framerate auf das beschränkt, was heute machbar und akzeptiert ist, wird es wahrscheinlich zurückbleiben, wenn sich Hardware und Erwartungen weiterentwickeln.
(In der Regel ist Vorsicht geboten, wenn gesagt wird, dass "Spieler nichts schneller als XXX wahrnehmen können", da dies normalerweise auf einer bestimmten Art von "Wahrnehmung" beruht, z empfindlich.)
Das letzte Problem hier ist, dass ein Spiel mit einer gesperrten Bildrate auch konservativ sein muss - wenn Sie jemals einen Moment im Spiel erreicht haben, in dem Sie eine ungewöhnlich hohe Anzahl von Objekten aktualisieren und anzeigen, möchten Sie Ihren Frame nicht verpassen Frist und verursachen ein merkliches Ruckeln oder Hacken. Sie müssen also entweder Ihr Inhaltsbudget so niedrig einstellen, dass Sie genügend Spielraum haben, oder Sie müssen in komplexere Funktionen zur dynamischen Qualitätsanpassung investieren, um zu vermeiden, dass das gesamte Spielerlebnis auf die schlechteste Leistung auf Hardware mit Mindestanforderungen beschränkt wird.
Dies kann besonders problematisch sein, wenn die Leistungsprobleme erst spät in der Entwicklung auftreten, wenn alle Ihre vorhandenen Systeme unter der Annahme einer Lockstep-Rendering-Framerate erstellt und optimiert wurden, die Sie jetzt nicht mehr immer erreichen können. Das Entkoppeln von Aktualisierungs- und Rendering-Raten bietet mehr Flexibilität beim Umgang mit Leistungsschwankungen.
3. Treten beim Aktualisieren zu einem festgelegten Zeitpunkt nicht die gleichen Probleme auf wie bei (2)?
Ich denke, dies ist das Kernstück der ursprünglichen Frage: Wenn wir unsere Updates entkoppeln und manchmal zwei Frames ohne dazwischen liegende Spielstatus-Updates rendern, ist dies nicht dasselbe wie das Lockstep-Rendering mit einer niedrigeren Framerate, da es keine sichtbaren Änderungen gibt der Bildschirm?
Tatsächlich gibt es verschiedene Möglichkeiten, wie Spiele die Entkopplung dieser Updates effektiv nutzen können:
a) Die Aktualisierungsrate kann schneller als die gerenderte Bildrate sein
Wie Tyjkenn in einer anderen Antwort festhält, wird insbesondere die Physik häufig mit einer höheren Frequenz als das Rendern ausgeführt, was zur Minimierung von Integrationsfehlern und zu genaueren Kollisionen beiträgt. Anstatt 0 oder 1 Aktualisierungen zwischen gerenderten Bildern zu haben, könnten Sie also 5 oder 10 oder 50 haben.
Jetzt kann der Spieler, der mit 120 fps rendert, 2 Aktualisierungen pro Frame erhalten, während der Spieler mit niedrigerer Hardware-Spezifikation, der mit 30 fps rendert, 8 Aktualisierungen pro Frame erhält und beide Spiele mit der gleichen Geschwindigkeit von Gameplay-Ticks pro Echtzeit-Sekunde laufen. Durch die bessere Hardware sieht es flüssiger aus, ändert aber nichts an der Funktionsweise des Spiels.
Hier besteht die Gefahr, dass bei einer Nichtübereinstimmung der Aktualisierungsrate mit der Bildrate eine "Taktfrequenz" zwischen den beiden Werten erzielt wird . Z.B. In den meisten Frames haben wir genug Zeit für 4 Spielzustandsaktualisierungen und einen kleinen Rest. Dann haben wir von Zeit zu Zeit genug Zeit, um 5 Aktualisierungen in einem Frame durchzuführen, was zu einem kleinen Sprung oder Stottern in der Bewegung führt. Dies kann angegangen werden durch ...
b) Interpolieren (oder Extrapolieren) des Spielzustands zwischen Aktualisierungen
Hier lassen wir den Spielstatus oft einen festen Zeitschritt in der Zukunft leben und speichern genug Informationen aus den letzten beiden Status, damit wir einen beliebigen Punkt zwischen ihnen rendern können. Wenn wir dann bereit sind, ein neues Bild auf dem Bildschirm anzuzeigen, werden wir nur zu Anzeigezwecken auf den entsprechenden Zeitpunkt überblendet (dh wir ändern hier nicht den zugrunde liegenden Gameplay-Status).
Wenn dies richtig gemacht wird, fühlt sich die Bewegung butterweich an und hilft sogar dabei, Schwankungen in der Framerate zu verbergen, solange wir nicht zu tief fallen.
c) Hinzufügen von Glätte zu Änderungen außerhalb des Spielzustands
Auch ohne Interpolation des Gameplay-Status können wir noch einige Smoothness-Gewinne erzielen.
Rein visuelle Änderungen wie Charakteranimationen, Partikelsysteme oder VFX und Benutzeroberflächenelemente wie HUD werden häufig unabhängig vom festgelegten Zeitschritt des Spielzustands aktualisiert. Das bedeutet, wenn wir unseren Gameplay-Status mehrmals pro Frame testen, zahlen wir nicht mit jedem Tick ihre Kosten - nur beim letzten Render-Pass. Stattdessen skalieren wir die Wiedergabegeschwindigkeit dieser Effekte, um sie an die Länge des Frames anzupassen, damit sie so flüssig wiedergegeben werden, wie es die Rendering-Framerate zulässt, ohne die Spielgeschwindigkeit oder die Fairness zu beeinträchtigen, wie in (1) erläutert.
Die Kamerabewegung kann dies auch tun - insbesondere in VR zeigen wir manchmal dasselbe Bild mehr als einmal, projizieren es jedoch neu, um die Kopfbewegung des Spielers dazwischen zu berücksichtigen , sodass wir die wahrgenommene Latenz und den Komfort verbessern können, selbst wenn wir können nicht von Haus aus alles so schnell rendern. Einige Spiele-Streaming-Systeme (bei denen das Spiel auf einem Server ausgeführt wird und der Spieler nur einen Thin Client ausführt) verwenden auch eine Version davon.
4. Warum nicht einfach diesen (c) Stil für alles verwenden? Wenn es für Animation und Benutzeroberfläche funktioniert, können wir dann nicht einfach die Gameplay-Statusaktualisierungen so skalieren, dass sie mit der aktuellen Bildrate übereinstimmen?
Ja * das ist möglich, aber nein, es ist nicht einfach.
Diese Antwort ist schon ein bisschen lang, so dass ich nicht auf alle Details eingehen werde, nur eine kurze Zusammenfassung:
Multiplikation mit deltaTime
Werken zur Anpassung an Aktualisierungen mit variabler Länge für lineare Änderungen (z. B. Bewegung mit konstanter Geschwindigkeit, Countdown eines Timers oder Fortschritt entlang einer Animationszeitleiste)
Leider sind viele Aspekte von Spielen nicht linear . Sogar etwas so Einfaches wie die Schwerkraft erfordert ausgefeiltere Integrationstechniken oder Teilschritte mit höherer Auflösung, um divergierende Ergebnisse bei unterschiedlichen Frameraten zu vermeiden. Die Eingabe und Steuerung durch den Spieler ist selbst eine große Quelle der Nichtlinearität.
Insbesondere hängen die Ergebnisse der Erkennung und Auflösung diskreter Kollisionen von der Aktualisierungsrate ab, was zu Tunnel- und Jitterfehlern führt, wenn die Frames zu lang werden. Eine variable Framerate zwingt uns, komplexere / teurere kontinuierliche Kollisionserkennungsmethoden für einen größeren Teil unseres Inhalts zu verwenden oder Variabilität in unserer Physik zu tolerieren. Sogar die kontinuierliche Kollisionserkennung ist eine Herausforderung, wenn sich Objekte in Bögen bewegen und kürzere Zeitschritte erfordern ...
Im allgemeinen Fall eines Spiels mittlerer Komplexität liegt die Aufrechterhaltung eines konsistenten Verhaltens und einer Fairness durch deltaTime
Skalierung zwischen sehr schwierig und wartungsintensiv bis gar nicht realisierbar.
Durch die Standardisierung einer Aktualisierungsrate können wir ein konsistenteres Verhalten unter verschiedenen Bedingungen gewährleisten , häufig mit einfacherem Code.
Dass die Aktualisierungsrate zu halten von Rendering entkoppelt gibt uns die Flexibilität , die Glätte und die Leistung der Erfahrung zu steuern , ohne Veränderung der Spiellogik .
Selbst dann bekommen wir nie wirklich die "perfekte" Unabhängigkeit von Frameraten, aber wie so viele Ansätze in Spielen gibt es uns eine steuerbare Methode, uns in Richtung "gut genug" für die Bedürfnisse eines bestimmten Spiels einzuwählen. Deshalb wird es allgemein als nützlicher Ausgangspunkt gelehrt.