Jump to content
Unity Insider Forum

Stottern bzw. Ruckeln bei vielen Objekten


Duco

Recommended Posts

Hallo, 

 

Ich bin Recht neu in der Unity-Szene und habe noch nicht all zu viel Erfahrung. Ich entwickle eine App für Android. Meine Objekte nutzen fast alle Texturen (albedos und normal maps) und einige haben metallic und Emitter eingestellt. 

Meine Objekte modelliere ich selbst, und sie haben viele faces, sind Recht detailliert. 

Es ist etwas in Richtung Temple Run und es werden 6 Plattformen gleichzeitig gespawnt um den Bildschirm auszufüllen. 

Ein Objekt besitzt äußerst viele faces, und wenn dieses spawnt (besonders mehrfach), fängt alles an zu ruckeln. 

Ich nutze bereits das GPU Instancing und auch das Occlusion Culling. 

Gibt es sonst noch etwas, was mir weiter helfen könnte? Ich hab etwas von streams gelesen, ist das in meinem Fall sinnvoll? 

Ich nutze die neuste Version von Unity, besitze ein OnePlus2 (Android 6) und mein Rechner nutzt Windows 10. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wieviele Faces hat dein Objekt denn? Besonders bei Mobile Games musst du auf Performance achten als bei normalen PC's.

Auch neuere Geräte kommen schnell an ihre Grenzen. 

Probiere mal, deine Objekte in einer Coroutine zu spawnen. Zwsichen jedem Objekt-Spawn machst du dann ein "yield return new WaitForEndOfFrame()"

Schau mal hier: https://docs.unity3d.com/Manual/Coroutines.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Legst du denn Objekte in deiner Szene zur Laufzeit noch jedesmal neu an? Solltest du eigentlich kaum noch, wenn du GPU Instancing korrekt verwendest (und du viele gleichartige Meshes verwendest). Ansonsten können deine Ruckler viele verschiedene Ursachen haben. Du solltest deine Szene einmal über den Unity Profiler laufen lassen und hier im Detail überprüfen, an welcher Stelle die meiste Zeit verbraucht und an welcher Stelle CPU- oder GPU-Peaks entstehen. Solche Peaks (in Verbindung mit hoher Grundlast) sind oft Ursachen für solche Aussetzer und Ruckler.  Dann wäre wichtig zu wissen, ruckelt es nur wenn die Objekte neu im Spiel erscheinen oder ruckelt es auch, wenn die Objekte schon länger in der Szene vorhanden sind. Sollte es ruckeln wenn die Objekte neu erscheinen, würde ich mal raten, du erzeugst immer noch Objekte zur Laufzeit neu in der Szene (was eigentlich über GPU Instancing reduziert oder vermieden werden sollte). Jedes neu erzeugte Objekt in der Szene kann potentiell zu Rucklern führen, umso mehr, je mehr Faces und Texturen dieses Objekt besitzt. Oft ist es hier besser diese Objekte bereits zu Programmstart in die Szene zu laden und während des Gameflows diese Objekte nur noch ein- und auszublenden (und ggf. neu zu Positionieren). Damit müssen die Objekte nicht mehr in die Szene geladen werden und es entfällt das Laden des Assets von der Festplatte in den Arbeitsspeicher.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich danke euch, ich war bis jetzt unterwegs. 

Ich werde mich heute Abend wieder dran setzen und die coroutine Methode probieren. 

Ich lege sie jedes Mal neu an und lösche sie wieder sobald sie hinter mir sind. Offensichtlich habe ich das GPU Instancing dann nicht richtig angewendet, ist aber kein Problem, ändere ich ab auf enable on/Off. Oder meintest du etwas anderes mit ein und ausblenden? 

Sollte ich das Asset Stream auch nutzen? 

Übrigens habe ich es gerade eben auf dem OnePlus 3 von meiner Freundin getestet, da läuft alles flüssig. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Der Idealfall beim GPU Instancing ist, du hast nur 1 Meshmodell und dieses wird in der Szene über die GPU vervielfältigt. Stell dir den Anwendungsfall vor, du hast eine Sphere als Modell und nun möchtest du in der Szene 100 (bewegliche) Bälle in verschiedenen Farben (bzw. Materialien) spawnen. Wenn du mehrere Modelle (Meshes) hast und diese Modelle in deiner Szene jeweils nur 1x vorkommen, solltest du kein GPU Instancing verwenden (bzw. macht es keinen Sinn es zu verwenden).

Zu dem was ich meinte. Hier gibt es mehrere Möglichkeiten, die Performance einspart:
a.) Du hast eine feste Szenerie (Levelaufbau) und alle Objekte (static Meshes) die für die Szene benötigt werden befinden sich bereits in der Szene.
Du blendest nun nur die Meshes ein, die der Spieler sehen soll. Diese Lösung ist allerdings eventuell speicherhungrig, da alle Objekte im Speicher vorgehalten werden.
b.) Hast du eine "Zufallsscene", dann legst du dir am besten einen Pool von Objekten an, die du wiederverwenden kannst.
Wird ein entsprechendes Objekt das 1. Mal gebraucht wird es gespawnt. Wird es nicht mehr gebraucht, dann wird es in den Objektpool geschoben und disabled.
Wird es wieder in der Szene benötigt, wird in den Pool geschaut, ob ein entsprechendes Objekt bereits vorhanden ist und entsprechend platziert und wieder enabled.
(siehe Objektpooling)
c) Mischung aus a und b
d) Man kann versuchen eine Coroutine zu verwenden, ABER einige Operationen in Unity lassen sich nicht parallelisieren... d.h. die Engine wartet evtl. indirekt trotzdem auf den Spawn eines Objektes.

Generell kann man sagen kleinere Objekte lassen sich performanter spawnen als größere Objekte. d.h. vor allem bei größeren Objekten sollte man auf a.) und b.) zurückgreifen.
Ebenso sollte man die Menge an "Spawns je Sekunde" begrenzen. Je mehr Spawns je Sekunde und je größer die Objekte desto mehr Ruckler sind zu erwarten.
 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich habe jetzt die coroutine zum spawnen und zum Löschen eingebracht. Das funktioniert. 

Dann habe ich die Spawn und delete funktionen umgeschrieben, dass diese nur auf Objekte zugreifen die ich zu Beginn spawne. Also ich habe 12 verschiedene Elemente, die spawne ich direkt und danach werden nur die Positionen berechnet und die werden verschoben und dis-/enabled. 

Das funktioniert schon, aber eigentlich funktioniert das Spiel auf 3 Ebenen. Daher habe ich nicht 12 sondern 36 Elemente zu Beginn gespawnt. Sobald ich die 2. Ebene hinzufüge stürzt Unity komplett ab, da gucke ich heute Abend noch mal. 

Für die Elemente habe ich das occlusion culling und das GPU Instancing aktiviert. Das GPU Instancing dürfte nun Sinn ergeben in dieser Weise, oder sehe ich das falsch?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du nur - jeweils sagen wir mal 2-3 - Objekte mit dem gleichen Mesh in deiner Szene hast, dann bringt GPU Instancing vermutlich gar nichts. Hier solltest du dann eher darauf achten, daß möglichst viele Objekte in deiner Szene das gleiche Material verwenden und du "static" am Mesh aktivierst, damit Unity alle Meshes "batched" (siehe static batching) und damit als 1 Mesh an die GPU übergibt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am ‎20‎.‎10‎.‎2017 um 22:40 schrieb Helishcoffe:

Wieviele Faces hat dein Objekt denn? Besonders bei Mobile Games musst du auf Performance achten als bei normalen PC's.

Habe endlich mal nachgeguckt, also ich habe 3 Objekte mit recht vielen Faces/Tris.

Alle 3 kommen sehr häufig vor, daher habe ich gerade neue Modelle erzeugt, die nicht ganz so schön aussehen aber dafür kaum Tris haben.

Das Objekt, das ich als erstes angesprochen habe weshalb immer alles anfängt zu stottern besitzt 544k Tris. Ein anderes 10k Tris, dieses kommt deutlich häufiger vor als das erste. Das dritte hat rund 240k Tris.

Ich hab das größte raus geschmissen, und für die anderen beiden ähnliche Modelle mit jeweils ca. 100 - 200 Tris.

 

Wenn ich nachher zuhause bin probiere ich es mal damit aus. Ich gehe mal davon aus, dass diese Anzahl an Tris zu viel für die meisten Smartphones sind, oder liege ich da falsch? Ich habe es an 4 Handys ausprobiert und das einzige, dass es flüssig geschafft hat, mit dem 544k Objekt (das teilweise 4 mal gleichzeitig im Bild war), war ein OnePlus 5.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, aus Blender. Das ist gut zu wissen, wie gesagt ich habe es abgeändert und jetzt läuft es endlich flüssig. 

Danke an alle, ihr habt mir sehr geholfen, ich habe die Optimierungen die genannt wurden mittlerweile alle umgesetzt. 

Auch das Objectpooling funktioniert jetzt auf allen 3 Ebenen einwandfrei. 

 

Dies ist mein erster Thread hier, daher eine Frage noch: Muss ich das Thema schließen oder wie läuft das in diesem Forum ab?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wir schließen in der Regel keine Themen. (Außer sie laufen aus dem Ruder) ;)

Es kann ja auch immer sein, dass vielleicht doch noch ne Frage zum Thema offen ist.

Was ich dir aber noch auf den Weg geben wollte, da ich ja scheinbar ursprünglich auch aus der 3D Schiene kommen:
Du musst immer daran denken, dass ein Spiel in Echtzeit abläuft. Wenn also in Blender ein Objekt, was mehrere tausend Polys hat und mit mehreren Lichtquellen ausgeleuchtet wird, mehrere Sekunden dauert bis es gerendert ist, dann kann das eine Gameengine auch nicht in Echtzeit schaffen.
Jedes Polygon multipliziert sich mit jeder Leichtquelle und jedem Schattenwurf in der Berechnung! Aus diesem Grund muss man auch in heutiger Zeit noch auf die Anzahl der Polygone achten und gewisse Unebenheiten eben über Normalmaps und ähnlichen Möglichkeiten faken!
Je weniger Polygone ein Objekt hat, umso mehr kannst du in die Szene rein bringen. Je nach Hardware (Grafikkarte bzw. Grafikchip) ist es mal mehr oder mal weniger. Aber es hängt nicht nur von den Polygonen ab, sondern auch von den Lichtern, den Schatten, den Reflektionen und von all den Posteffekten die du noch dazu schaltest.
Versuche also deine Objekte immer so sparsam wie möglich zu gestalten, dann hast du noch Luft für andere Dinge. Low-Poly-Modelling ist nicht leicht, aber man lernt schnell wo man Polys sparen kann, ohne dass es zu Qualitätseinbußen kommt. :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hatte eigentlich gedacht, dass man heutzutage soweit ist mit der Hardware, dass man einfach mit allem um sich werfen kann. Da wurde ich wohl eines besseren belehrt ;) 

Aber ich sehe das positive darin, jetzt habe ich schon einige Optimierungen an meiner App vorgenommen, die sicher irgendwann nützlich sein werden, und wenn nicht bei dieser App, dann wohl bei der nächsten :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...