In AAA-Spielen außerhalb der Grenzen

21

In vielen gängigen AAA-Titeln (insbesondere Source-Engine-Spielen), wenn der Spieler einen Bereich erreicht, für den er nicht gesorgt hat, z. Auf dem Bildschirm tritt ein seltsamer Effekt auf (Puffer reißen?).

Es kann als ähnlich wie bei Windows beschrieben werden, dass Windows XP möglicherweise ein Fenster zurücklässt, das gezogen wird, während ein System hängt.

Ich kann nur postulieren, dass die Entwickler den Farbpuffer beim Aktualisieren des Bildschirms nicht löschen?

Ist das korrekt? Wenn ja warum?

verzögerter Kaviar
quelle
8
Übrigens wird dies oft als "Hall of Mirrors" -Effekt oder HOM bezeichnet.
Nathan Reed

Antworten:

35

Es war einmal, dass das Löschen der Farb- und Tiefenpuffer einige Zeit in Anspruch nahm. Ein Clear zu machen bedeutete, dass die Grafikkarte jedes Pixel des Framebuffers durchlaufen und einen Wert darauf schreiben musste.

Aus diesem Grund stellten die Spieleentwickler fest, dass es effizienter wäre, einfach anzunehmen, dass jedes Pixel erneut gerendert würde. Sie entwickelten dazu viele Techniken.

Der Farbpuffer ist am einfachsten zu ignorieren. Weniger einfach ist der Tiefenpuffer, da er mit alten Daten verschmutzt wäre. Also war das, was sie taten, einfach.

In Frame 0 würden sie mit einem glDepthRange(oder dem D3D-Äquivalent) von (0, 0,5) rendern und ein glDepthFuncvon GL_LESS(oder GL_LEQUAL) verwenden. Dies bedeutet, dass der am weitesten entfernte Tiefenwert, den Sie jemals im Tiefenpuffer erhalten würden, 0,5 beträgt. Der größte Wert im Tiefenpuffer am Ende von Bild 0 ist also 0,5 (vorausgesetzt, Sie haben in jedes Pixel geschrieben).

In Frame 1 würden sie den Tiefenbereich auf (1, 0,5) ändern. Beachten Sie, dass in diesem Fall der Wert für die nahe Tiefe größer als die entfernte Tiefe ist. Sie würden aber auch die Tiefenfunktion in GL_GREATER(oder GL_GEQUAL) ändern , was die Bedeutung des Tiefentests umkehrt. Da der größte Wert im Tiefenpuffer 0,5 ist, hat alles, was Sie schreiben, einen größeren Wert . Da der Tiefentest umgekehrt wurde, bedeutet dies effektiv, dass alles, was auf Bild 0 geschrieben wurde, jetzt weiter entfernt ist als alles, was möglicherweise auf Bild 1 geschrieben werden könnte. Am Ende von Bild 1 beträgt der kleinste Wert im Tiefenpuffer jetzt 0,5.

Und dann wiederholen sie.

Bei Hardware, die seit 2003 hergestellt wurde, handelt es sich nicht mehr um eine Optimierung. In der Tat ist es eine negative Optimierung . Durch das Löschen des Tiefenpuffers wird die Hardware tatsächlich schneller . Nicht wirklich.

Grundsätzlich passiert, dass das Löschen von Puffern eigentlich nichts schreibt. Sie speichern einige Bits in den Caches der GPU, die dem System mitteilen, auf welche Farbe / Tiefe sie gelöscht wurden. Wenn das System versucht, in eine Cache-Zeile des Framebuffers zu schreiben, macht es sich nicht die Mühe zu lesen, was sich dort befindet, da es bereits weiß, dass es sich um ein leeres Feld mit dem Wert für klare Farbe / Tiefe handelt. Wenn Sie versuchen, mit dem zu mischen, was vorhanden ist, oder einen Tiefentest durchführen, müssen Sie nicht lesen: Es weiß, welchen Wert Sie mischen / mit / gegen testen müssen.

Jedes erste Lesen / Ändern / Schreiben, das Sie nach dem Löschen in jeder Cache-Zeile ausführen, ist im Grunde ein Schreiben. Es ist kostenlos .

Darüber hinaus kann ein gezackter Tiefenpuffer gegen Hyper-Z / Hierarchial-Z / alle Z-Culling-Optimierungen in der Hardware wirken. Ja, Ihre Szene wird irgendwann gegen diese funktionieren, wenn Sie Details hinzufügen. Wenn Ihr Tiefenpuffer jedoch von früheren Renderings abweicht, selbst wenn sich diese Hintergrundobjekte im Hintergrund befinden, kann dies die Effizienz der Z-Culling-Techniken beeinträchtigen. Und das wird die Leistung nicht verbessern.

Daher sollten Sie diese Tiefenumkehrtechnik in modernen Spielen niemals anwenden.

Hinweis: Jari macht einen guten Eindruck auf kachelbasierte Rendering-Architekturen (wie sie in den meisten mobilen Plattformen zu finden sind). Wenn Sie die Tiefe nicht ausräumen, kann das auch dort unangenehm werden.

Nicol Bolas
quelle
Bedeutet Ihre letzte Aussage, dass der Tiefenpuffer niemals abwechseln soll, oder? Gute Antwort.
verzögerte
1
@ Daniel Ja. Ich habe meinen Beitrag geklärt.
Nicol Bolas
3
Das Überspringen der Clear-on-Binning-Architekturen (wie die meisten OpenGL ES-Chips) führt zu massiven Leistungsverlusten, da der Grafikchip keine Annahmen über den Farbpufferstatus treffen kann.
Jari Komppa
5

Ja, Sie haben Recht, dass der Backbuffer nicht gelöscht wird.

Der Grund dafür ist (meistens), dass es schneller ist, einen benutzerdefinierten Shader zu verwenden, bei dem die Ping-Pongs-Tiefenwerte in jedem Frame in entgegengesetzte Richtungen verlaufen und sich darauf verlassen, dass Ihr Spiel immer jedes Pixel auf dem Bildschirm wiedergibt.

Für null Kosten sparen Sie also einen Puffer, der pro Frame gelöscht wird.

Patrick Hughes
quelle
1
Ich weiß nichts über Tiefen-Ping-Ponging. Jede Engine, mit der ich vertraut bin, löscht den Tiefen- / Schablonenpuffer für jeden Frame. Aber abgesehen davon, ja, wenn das Spiel alle Pixel rendert (wie es sollte), müssen Sie den Farbpuffer nicht löschen.
Nathan Reed
Könntest du ein Beispiel für den Shader geben, sonst gute Antwort.
verzögert
1
Mir ist klar, dass Sie nach den neuesten Motoren fragen. Lesen Sie @ NathanReeds Kommentar, wie viele Nur-PC-Motoren jetzt funktionieren. Die Z-Puffer-Drehung ist eine ältere Technik, ich werde sehen, ob ich eine Referenz finden kann. Konsolen-Engines löschen meistens auch den gesamten Farbpuffer, selbst ein Pixel, der den von Nathan genannten HOM-Effekt anzeigt, versagt bei einem Titel und zwingt ihn, die Einreichungen erneut zu durchlaufen.
Patrick Hughes