Ich mache eine Art Low-Poly-Spiel. Ich habe ein Gelände mit etwas Wasser und ich möchte viele, viele Bäume. Ich habe im Moment 10.000 Baummassen platziert. Jeder Baum besteht aus nicht mehr als 200 Dreiecken, daher sind sie nicht zu anstrengend.
Das Hauptproblem ist, dass es Seen gibt und die Seen ziemlich groß sind. Auf der anderen Seite des Sees sieht man eigentlich keine Bäume, und das sieht wirklich schlimm aus, besonders wenn man dorthin läuft und plötzlich Bäume auftauchen.
Um dies zu beheben, muss ich die Baumentfernung erhöhen, damit auf der anderen Seite des Sees eine anständige Anzahl von Bäumen zu sehen ist. Dadurch wird die Leistung jedoch auf 40-50 fps reduziert, und es ist noch kaum etwas anderes im Spiel. Ich benutze eine GTX 1080, wenn das hilft.
Was kann ich tun, um mein Spiel mit mehr Bäumen schneller zu machen?
quelle
Antworten:
Sie können verschiedene Maßnahmen ergreifen, um die Zeichenleistung zu verbessern.
Sie sagten, sie wären ziemlich weit weg. Sie können LOD verwenden , um die Anzahl der Scheitelpunkte dieser Bäume und damit die Zeit zu verringern, die erforderlich ist, um alle gezeichneten Scheitelpunkte zu durchlaufen. Auch wenn dies höchstwahrscheinlich nicht das Problem ist (GTX1080 mit nur 10.000 Bäumen mit jeweils 200 Tris, winzige Zahlen für die GPU), habe ich es dennoch aufgenommen. Billboarding ist ein effektives Werkzeug für die niedrigste LOD-Ebene, da es sich im Wesentlichen um eine flache Ebene handelt, die immer der Kamera zugewandt ist und ein gerendertes Bild des Baums enthält. Es verliert an Tiefe, weshalb es für die niedrigste Stufe gut ist, da der Spieler den Unterschied höchstwahrscheinlich nicht bemerkt.
Haben Sie die Stapelverarbeitung aktiviert ? Dynamisches Batching wird normalerweise automatisch durchgeführt, wenn die Anzahl der Scheitelpunkte der Netze relativ niedrig ist. Statisches Batching kann auch versucht werden, indem die Bäume statisch gemacht werden, indem das Kontrollkästchen im Unity-Editor auf dem übergeordneten Spielobjekt aktiviert wird. Dies funktioniert nicht gut mit animierten Objekten. Sie benötigen für die Objekte freigegebenes Material, damit dies funktioniert.
Mit benutzerdefinierten Stapeln können Sie das Rendern steuern, indem Sie die Blöcke selbst generieren, anstatt Unity damit umgehen zu lassen. Außerdem können Sie auch größere Maschen stapeln. Dies geschieht einfach mit Mesh.CombineMeshes . Dies funktioniert auch nicht gut mit animierten Objekten. Sie benötigen für die Objekte freigegebenes Material, damit dies funktioniert. Wahrscheinlich möchten Sie Ihre Welt in einige Teile aufteilen und daraus Stapel erstellen. Wie diese Blöcke erzeugt werden sollen, hängt davon ab, wie sich Ihre Kamera in der Welt bewegt.
Aktivieren Instancing auf den Shadern. Durch das Instanzieren kann die Engine mehrere Objekte (mit demselben Netz) mit nur einem Zeichnungsaufruf zeichnen. Damit dies funktioniert, müssen die Objekte über ein gemeinsames Netz und einen gemeinsamen Shader verfügen. Das Material kann variieren, aber der Shader muss alle unterschiedlichen variierenden Eigenschaften unterstützen.
Damit die Engine instanziierte Rendering-Batches besser erstellt, möchten Sie wahrscheinlich dieselben Meshes in einer Szene gruppieren. Auch das Spielen mit der Material-Render-Warteschlange liefert gute Ergebnisse, wenn ein Mesh immer dasselbe Material enthält. Während der Entwicklung des Handyspiels, an dem ich gerade arbeite, habe ich das genutzt, um Drawcalls in meiner Testszene um mehr als die Hälfte zu reduzieren. Stellen Sie auch seit Unity 5.6 sicher, dass Sie das
Enable Instancing
Kontrollkästchen im Material aktivieren.Halten Sie Ihre Drawcalls und SetPass-Anrufe im Allgemeinen niedrig. Dies sind die rohen Anforderungen an Ihre GPU, um Inhalte zu zeichnen, und sie haben einen großen Overhead. Das Reduzieren von Drawcalls (was durch Batching und Instancing erreicht wird) erhöht die Gesamtleistung Ihrer CPU, da weniger Wartezeiten erforderlich sind. SetPass-Aufrufe sind Änderungen an Ihren aktuellen Shadern. Wenn Sie also viele verschiedene Materialien haben, werden Sie mehrere SetPass-Aufrufe haben, die auch dazu führen, dass die CPU ein wenig wartet.
Wenn Ihre Szene sehr umfangreich ist und Ihre CPU-Zeit für das Durchlaufen aller Objekte in der Szene aufgewendet wird, versuchen Sie, die Objekte in der Szene zu verkleinern. Gruppieren Sie einige Bäume, anstatt sie einzeln zu platzieren, und stellen Sie sie als einzelnes Objekt zur Verfügung. Stellen Sie außerdem sicher, dass Sie die Bäume oder die übergeordneten Objekte nicht verschieben, da Unity dadurch zwischengespeicherte Transformationen verwerfen und den gesamten Szenenbaum neu berechnen kann.
Wenn Ihre Szene riesig ist und Ihre CPU-Zeit immer noch hauptsächlich für Unity aufgewendet wird, das durch den Szenenbaum geht, um Listen zum Rendern aller Objekte zu erstellen, können Sie Unity das Rendern nicht erlauben. Wenn Sie zeichnbare Objekte besser verfolgen können, können Sie sie mit CommandBuffer.DrawMeshInstanced oder Graphics.DrawMeshInstanced von Hand zeichnen. Ich werde nicht näher darauf eingehen, da es viel fortgeschrittener ist und das Ausmerzen von Obects selbst und so weiter beinhaltet.
Wenn die statische oder dynamische Stapelverarbeitung nicht ordnungsgemäß funktioniert (was Sie anhand des Frame-Debuggers feststellen können), müssen Sie sicherstellen, dass Sie tatsächlich freigegebenes Material verwenden und keine versehentlichen Kopien des Materials mit dem Aufruf anfertigen
meshRenderer.material
. Durch Aufrufen von.material
werden Kopien Ihrer Materialien erstellt und die Stapelverarbeitung unterbrochen. Verwenden Sie.sharedMaterial
stattdessen.Seit Unity 5.6 können Sie mit dem Frame-Debugger feststellen, warum bestimmte Drawcalls nicht mit den vorherigen Drawcalls abgeglichen wurden. Dies ist sehr hilfreich, wenn Sie versuchen, die Drawcalls Ihres Spiels zu reduzieren.
Die Instanziierung bietet gegenüber der statischen / dynamischen / benutzerdefinierten Stapelverarbeitung die folgenden Vorteile:
Auch als Nachteil ist es ein ziemlich neues Feature in Unity und könnte ein bisschen instabil sein. Auch ältere GPUs oder GPUs für mobile Geräte unterstützen nicht unbedingt die Instanziierung.
quelle
Ok, das Problem war einfach, dass ich keinen vorberechneten Echtzeit-GI verwendet habe. Ich überprüfe das vor einiger Zeit, aber es wirkte sich nicht sofort aus, also habe ich es verlassen und vergessen, und die Bearbeitungszeit für die Beleuchtung war auch so lang. Es ist jedoch gerade fertig damit, und mein Wort, meine FPS sind um das Dreifache gestiegen. Also lasse ich es fürs Erste dabei und stelle in Zukunft sicher, dass ich immer Precomputer Realtime GI verwende!
Wenn ich noch etwas tun könnte, um die Leistung weiter zu verbessern, lassen Sie es mich bitte wissen, ich wäre Ihnen sehr dankbar!
quelle