Framerate
Bilder des weißen Balls auf dunklem Hintergrund fehlen (Abschnitt "Unschärfe bei Bewegung"): - Ball links - Ball in der Mitte - Ball rechts - Ball unscharf Ein st-Diagramm passend zu Mikrorucklern wäre toll (Abschnitt "Variation der Framerate"). |
Das englische Wort "frame" lässt sich in etwa mit "Rahmen" übersetzen. Das "Frame" in Framerate hat aber nichts mit einem Bilderrahmen o.ä. zu tun, sondern gemeint ist der zeitliche Rahmen, in dem ein bestimmter Rechenvorgang stattfindet. Wenn man von der Framerate von Spielen spricht, ist ein Frame also genau die Zeit, die der Computer benötigt, um ein neues Bild auf den Bildschirm zu rendern. Die Framerate (auch Bildwiederholrate) gibt an, wie viele dieser Frames pro Sekunde (fps) vergehen.
Inhaltsverzeichnis
24 fps Mythos
Damit die grafische Ausgabe nicht wie eine Abfolge von Einzelbildern, sondern wie eine flüssige Bewegung aussieht, muss das angezeigte Bild schnell genug aktualisiert werden - mit anderen Worten: Die Framerate muss hoch genug sein. Experimente haben ergeben, dass das menschliche Auge eine Animation ab etwa 24 Bildern pro Sekunde nicht mehr als Bildfolge, sondern als Bewegung wahrnimmt. Daher stammt auch die weit verbreitete Meinung, ein Spieler könne keinen Unterschied zwischen 24 fps und beispielsweise 60 fps erkennen. Diese Annahme ist jedoch aus verschiedenen Gründen falsch! Siehe folgender Text.
Unschärfe bei Bewegung
Überlegen wir einmal, was passiert, wenn ein weißer Ball schnell von links nach rechts durchs Bild fliegt. Das erste Bild, das der Computer rendert, zeigt den Ball auf der linken Seite des Bildes.
(Bild)
Sofort nachdem das Bild fertig ist, misst das Programm natürlich die Zeit, die es für das eine Bild gebraucht hat (bei 24 fps knapp 42 ms). Anhand der gemessenen Zeit kann er bestimmen, welche Strecke der Ball in dieser Zeit zurückgelegt hat (s = v*t, Timebased Movement). Nun verschiebt es den Ball um die entsprechende Strecke und beginnt sofort, das nächste Bild zu rendern. Nun ist der Ball schon in der Mitte des Bildschirms angelangt.
(Bild)
Wieder misst das Programm die vergangene Zeit, verschiebt den Ball um die entsprechende Strecke und rendert das nächste Bild. Nun ist der Ball rechts.
(Bild)
Im nächsten Bild wird er gar nicht mehr zu sehen sein. Der Betrachter bekommt also hintereinander drei gestochen scharfe Bilder zu sehen, die er als Bewegung interpretieren soll. Das Problem dabei ist das "gestochen scharf".
Betrachten wir zum Vergleich einmal, was passieren würde, wenn sich diese Szene in der Natur abspielt. Der Ball wird von einer oder mehrerer Lichtquellen beleuchtet und reflektiert einen Teil des Lichts zum Auge des Betrachters. (Der Einfachheit halber nehmen wir an, dass der arme Betrachter nur ein Auge hat.) Währenddessen bewegt sich der Ball, und da der Betrachter seine Blickrichtung in dieser Zeit nicht ändert, wird das Licht während des Frames von 42 ms an verschiedene Stellen der Netzhaut reflektiert - allerdings wird kein Teil der Netzhaut 42 ms lang belichtet. Über den Sehnerv wird für jeden "Pixel" auf der Netzhaut der mittlere Helligkeitswert ans Gehirn übermittelt. Das Resultat ist ein grauer (nicht weißer) Streifen quer durchs Bild. Der Ball "verwischt" sozusagen, wie man es auch von Fotos mit zu langer Belichtungszeit kennt.
(Bild)
Genau diese Unschärfe erwartet auch der Spieler eines Computerspiels. Fehlt dieser Effekt, wirkt die Bewegung ruckelig. Eine Möglichkeit, diesen Effekt zu erzielen, wäre alle Bewegungen unscharf zu zeichnen. Das hat aber einen gewaltigen Nachteil, wie du im nächsten Abschnitt sehen wirst. Die andere Möglichkeit ist, einfach deutlich mehr Bilder pro Sekunde zu rendern, als nur 24.
Schärfe bei Bewegung
Warum ist das Unscharf-Zeichnen keine Lösung des Problems? Ganz einfach: Man stelle sich die selbe Szene noch einmal vor - mit dem einzigen Unterschied, dass der Betrachter dieses Mal nicht auf eine Stelle starrt, sondern den Ball mit seinem Blick verfolgt. Er sieht also erst auf die linke Seite des Bildschirms und bewegt seinen Blick mit konstanter Geschwindigkeit nacht rechts. Was würde er erwarten zu sehen? Denk' mal kurz darüber nach.
Der Spieler erwartet natürlich die selben Effekte, die er (unbewusst) zuvor in der Natur beobachtet hat. Nämlich dass der fliegende Ball gestochen scharf zu sehen ist, während der Hintergrund in Unschärfe verwischt. Denn dadurch, dass der Beobachter sein Auge immer nach dem Ball ausrichtet, trifft das von ihm reflektierte Licht immer die gleichen Stellen der Netzhaut.
Dem Ball auf dem Bildschirm zu folgen, nachdem dieser unscharf gezeichnet wurde, geht aber nicht - man sieht ja nur einen grauen Streifen, überall dort, wo der Ball im Laufe des Frames einmal war. Das Problem ist, dass der Programmierer nicht wissen kann, wie der oder die Betrachter des Bildschirms ihre Augen bewegen.
Würde man die gesamte Szene mit 24000 fps rendern (was natürlich kein PC oder Bildschirm schaffen würde), dann würde sich der Ball in jedem Frame um einen oder zwei Pixel verschieben und wäre zu jeder Zeit gestochen scharf, wenn man ihm folgt. Gleichzeitig würde er (für das Auge) verwischen, wenn man ihm nicht folgt.
Variation der Framerate
Auch wenn die Framerate deutlich über 24 fps liegt, können selbst langsamere Bewegungen noch ruckelig wirken. Grund dafür ist dann, dass die Framelänge stark variiert. Als Beispiel muss mal wieder der Ball herhalten, der diesmal aber nicht in einer achtel Sekunde durchs gesamte Bild fliegt, sondern gemächlich mit konstanter Geschwindigkeit ins Bild rollt. Die Szene wird mit (normalerweise sehr flüssigen) 60 fps gerendert. Ein Frame hat also eine Dauer von 16,67 ms. Leider kommt es nun durch ungünstige Umstände dazu, dass ein einziges Frame plötzlich doppelt so lange dauert wie die anderen zuvor. Welche Auswirkungen hat also folgende Frame-Abfolge?
Frame | Länge |
---|---|
Frame0 | 16,67 |
Frame1 | 16,67 |
Frame2 | 33,33 |
Frame3 | 16,67 |
Frame4 | 16,67 |
Die Hälfte von 60 fps sind 30 fps. Man sollte meinen, dass dies immer noch als ruckelfrei empfunden wird. Das Problem ist auch nicht die Framelänge als solches, sondern die Länge von Frame3 im Vergleich zu den anderen Frames. Der Betrachter erwartet, dass der Ball mit konstanter Geschwindigkeit weiterrollt. Während das Bild gezeichnet wird, kann das Programm noch nicht wissen, wie viel Zeit vergangen sein wird, wenn das Bild fertig ist. Deshalb wird der Ball ja immer um die Strecke verschoben, die der letzten Framelänge entspricht. In Frame2 wird also der Ball verschoben, als wenn der Zeichenvorgang nur 16,67 ms dauern würde. In Wirklichkeit vergeht aber doppelt so viel Zeit, so dass es dem Spieler vorkommt, als hätte der Ball seine Geschwindigkeit plötzlich halbiert. Aber es kommt noch schlimmer: Da Frame3 wieder nur 16,67 ms dauert, der Ball aber so weit fortbewegt wird, als würde der Frame 33,33 ms dauern, vervierfacht sich die Geschwindigkeit nun! Erst in Frame4 bekommt der Ball durch eine erneute Tempohalbierung wieder seine wirkliche Geschwindigkeit. Diese Geschwindigkeitssprünge werden auch bei hoher Framerate noch als Ruckeln wahrgenommen. Man nennt diese Ruckler auch Mikroruckler.
Bildschirmfrequenz und V-Sync
Kein Bildschirm kann beliebig viele Bilder pro Sekunde darstellen. Eine übliche Refreshrate bei Flachbildschirmen ist 60 Hz (das heißt, das Bild wird 60 mal pro Sekunde erneuert). Es gibt aber auch welche mit 120 Hz (für Stereoskopie) oder 200 Hz. Da 60 Hz auf Röhrenbildschirmen stark flimmern, können diese alten Kisten oft auch 75, 85, oder 100 Hz. Egal, wie oft ein Monitor pro Sekunde sein Bild erneuern kann - es gibt (von Ausnahmefällen wie Benchmarking abgesehen) keinen Grund, die Grafikkarte mehr Bilder berechnen zu lassen, zumal dies zu unerwünschten Artefakten führt (Tearing).
Deshalb gibt es eine Technik, die sich V-Sync nennt. Dabei wartet die Grafikkarte, bis das neue Bild an den Bildschirm übertragen wurde, bis sie das nächste beginnt. Es ist unbedingt zu empfehlen V-Sync einzuschalten, wenn der Computer sowieso mehr Bilder pro Sekunde rendern kann als der Bildschirm darzustellen vermag. Doch was passiert, wenn V-Sync eingeschaltet ist und der Rechner nicht die native Framerate des Bildschirms erreicht?
Nehmen wir an, der Bildschirm wird 60 mal pro Sekunde aktualisiert, die GPU schafft aber nur 50 Bilder pro Sekunde. Sobald die Grafikkarte das Synchronisationssignal empfängt, kopiert sie den Backbufferinhalt in den Frontbuffer und rendert das nächste Bild in den Backbuffer. 16,67 ms später kommt das nächste Synchronisationssignal, aber die Grafikkarte ist noch nicht fertig. Also wird nichts in den Frontbuffer kopiert. Stattdessen zeigt der Bildschirm zweimal hintereinander das gleiche Bild an. Erst weitere 3,33 ms später stellt der Grafikchip das Bild fertig und muss nun 13,34 ms (!) auf das nächste Sync-Signal warten. Bis dieses kommt, sind insgesamt 33,33 ms vergangen - mit anderen Worten wir haben eine Framerate von nur 30 fps, obwohl der Computer 50 fps schaffen würde!
Triple-Buffering
Das Problem dabei ist, dass die Grafikkarte während des Wartens auf das Sync-Signal nichts tut. Doch dafür gibt es eine Lösung: Da wir in den Backbuffer noch nicht schreiben dürfen, schreiben wir halt in einen anderen Backbuffer! Während wir in den zweiten Backbuffer schreiben, wird der erste in den Frontbuffer kopiert, sobald das Sync-Signal wieder kommt. Im nächsten Frame schreiben wir natürlich wieder in den ersten Backbuffer, während der zweite aufs Kopieren wartet. Somit erreichen wir die selbe Performance wie ohne V-Sync, sind aber gleichzeitig das Tearing losgeworden.
Ein Nachteil des Verfahrens ist, dass wir etwas mehr Videospeicher benötigen. Der Mehrverbrauch hält sich aber in Grenzen, denn es wird lediglich ein weiterer Farbpuffer benötigt - den Z- und Stencilbuffer dagegen brauchen wir nicht noch einmal. Zudem handelt man sich natürlich weitere Mikroruckler ein - aber mal ehrlich: 50 fps mit Mikrorucklern sind immer noch besser als 30 fps ohne.