Jump to content
Unity Insider Forum

Performance einsparen allgmein


Morenar

Recommended Posts

Hallo liebe Community,

 

wohl oder übel mach ich mir gedanken über die Performance in meinem Spiel mit über 100-250 fps kann ich mich noch glücklich schätzen aber auch irgendwie nicht, da noch viele dinge integriert werden müssen.

 

Wärend ich über dieses heikle Thema nachdenke, sehe ich Spiele wie das interstellar marine oder slender the arrival, die anscheinend keine Probleme mit der Performance haben und doch eine richtig gute Grafik liefern.

 

Mein Spiel ist sehr Script lasstig, trotzdem möchte ich eine gute Grafik, nicht so professionell wie die beiden oben genannten Spiele, da ich denke das ich das vorerst nicht schaffen werde. :)

 

Aber wie bekommt man so eine gute Performance im Spiel hin wird das Spiel nicht durch tausende objekte rendern + scripte die Spieler + objekte im Spiel steuern langsamer?

 

 

Ich suche nach Tipps tricks wie z.b Scripts verbessern, ich habe ein paar Update funktionen sind die schlimm?

Soll man beim LevelDesign mehrere Objekte verwenden (Wandbausteine) oder das ganze Level aus einem Block schnitzen?

Nehmen lichter viel Speicher/Performance ein....?

 

 

Wie ist eure Erfahrung um das Maximale aus eurem Spiel rauszuhollen?

Jeden Faktor der auf die Performance schlimm sein könnte, könnt ihr schreiben, sodass ich alle Felder mal abchecken kann.

 

 

 

Danke im Vorraus

 

 

TheMorenar

Link zu diesem Kommentar
Auf anderen Seiten teilen

Lichter

In Unity gibt es drei Arten zum darstellen von Lichtern, alles hat seine Vor- und Nachteile:

  • Lightmaps: Erlaubt nur statische Lichtquellen, liefert aber die maximale Performance. Eine hohe Qualität der Schatten ist dadurch sehr leicht möglich. In der Pro Version lässt sich damit sogar Global Illumination realisieren (indirekte Beleuchtung).
  • Forward Rendering: Der klassische Modus um Lichter zu rendern. Hier wird die Szene evtl. mehrmals gerendert, falls zu viele Lichtquellen vorhanden sind. Dies wirkt sich sehr negativ auf die Performance aus. Ideal bei ca. 1-8 gleichzeitig sichtbaren Lichtquellen.
  • Deferred Rendering: Dies ist nur in der Pro Version verfügbar. Hier werden Lichter quasi als Postprocessing Effect am Ende gezeichnet. Jedoch ist der eigentliche Rendering Vorgang dadurch aufwendiger, da ein sogenannter G-Buffer beim Rendering verwendet werden muss, d.h. es müssen nicht nur wie beim klassischen Forward Rendering die Farben in ein Rendertarget geschrieben werden, sondern auch weitere Daten, wie Normalen und Specular Informationen. Wenn Deferred Rendering verwendet wird zieht das zunächst die allgemeine Performance etwas runter (und skaliert heftig mit Bildschirmauflösung), aber dafür ist das Rendern von Lichtern und anwenden von weiteren Postprocessing Effekten sehr günstig. D.h. 20, 50 oder hunderte dynamische Lichtquellen sind ohne Probleme damit realisierbar.

Generell gilt aber, je mehr Sachen durch Lightmaps vorberechnet sind, desto höher ist im Normalfall die Performance.

 

Schatten

Dynamische Schatten sind eine enorm teuere Angelegenheit, d.h. wenn möglich Qualität eher gering halten oder statische Schatten verwenden.

 

Polygone und 3D Modelle

Ob man nun mehrere kleine 3D Modelle verwendet oder ein großes ist so eine Sache... auf der einen Seite bedeuten weniger Objekte weniger Drawcalls, aber auf der einen Seite nimmt man der Engine bei wenigen Objekten die Möglichkeit weg durch Culling zu optimieren.

Occlusion Culling ist nur in der Pro Version verfügbar (Culling von Objekten die hinter anderen versteckt sind), aber Frustum Culling dürfte in beiden Versionen verfügbar sein und kann sehr nützlich sein um die Performance zu optimieren.

D.h. hier muss ein gesundes Mittelmaß verwendet werden.

 

Bei der Polygonanzahl ist man heutzutage recht frei, natürlich sollten es nicht zuviele sein, aber wenn man für moderen PCs entwickelt sind mehrere Millionen Polygone pro Szene schon drin (sofern sie nicht in ebenso viele Drawcalls gesplitted sind^^). Das bedeutet jetzt natürlich nicht dass man mit Polygonen verschwenderisch umgehen soll. Nach wie vor nur dort mehr Polygone verwenden, wo man sie auch braucht.

 

Texturen

Ich weiß jetzt nicht wie genau Unity das intern hier macht, aber rein theoretisch hat eine Game Engine mehr Möglichkeiten zu optimieren, wenn weniger Texturen verwendet werden. Da hier eben weniger Daten an die Grafikkarte geschickt werden müssen. Dies dürfte sich aber genauso wie die Auflösung der Texturen normalerweise eher gering auf die Performance auswirken.

 

Skripte

Wenn man nicht gerade irgendwelche rechenaufwenigen Algorithmen verwendet, dann wirken sich selbst geschriebene Skripte nicht sonderlich negativ auf die Performance auf, außer man beim Programmieren etwas falsch gemacht (z.B. Frameweise Objekte spawnen oder so einen Quatsch :D). Hier hilft im Zweifelsfall ein Profiler.

 

Speziell in Unity ist es auch performanter wenn man mehrere kleine Szenen verwendet als zu versuchen eine große Open World zu erstellen, da Unity nicht auf Streaming optimiert ist. Abgesehen davon ist es wichtig immer wieder Sachen auszuprobieren, wenn man ein neues Level designed hat, das ganze einfach mal testen (auch gerne auf unterschiedlichen Geräten). Außerdem sollte man immer mal wieder mit unterschiedlichen Einstellungen herumspielen (z.B. Sichtweite, Billboardstartentfernung, etc.).

 

Das waren die Sachen, die mir so spontan eingefallen sind... ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Jopp, das Meiste ist schon gesagt.

 

Soll man beim LevelDesign mehrere Objekte verwenden (Wandbausteine) oder das ganze Level aus einem Block schnitzen?

 

Je mehr einzelne Objekte du hast um so mehr Drawcalls hast du. Also möglichst wenig Objekte verwenden um die Drawcalls niedrig zu halten. Drawcall= die komplette Szene wird neu gezeichnet. Wie von Kevin schon angemerkt kann dadurch aber das Culling leiden. Ausprobieren.

 

Obacht. Ein einzelnes Material bedeutet auch einen einzelnen Drawcall. Das bedeutet dass ein einzelnes Mesh mit zehn Materialien drauf auch 10 Drawcalls hat, und nicht einen.

 

While at it, Blobshadows / Projectorshadows ergeben einen Drawcall bei jedem Kontakt mit einer Boundingbox eines Objektes auf das sie einen Schatten werfen können. Da kann es günstiger sein das Levelmesh doch wieder in kleinere Stücke zu schneiden. Es gibt aber auch die Möglichkeit Objekte in einen ignore Blobshadows Layer zu packen damit die Blobshadows gar nicht damit reagieren.

 

Was auch noch zu ergänzen wäre ist einfach dass jedes Spiel anders ist. Wo deine persönlichen Bremsen liegen kann dir nur dein Prototyp sagen. Anschauen welches Objekt dir die meisten Scherereien macht, die grösste Performance kostet, und da dann nachschauen was da zu optimieren geht. Aber es muss auch nicht wirklich jeder Hasenfurz optimiert werden. Just optimize when you have to :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Kevin

Danke vieles zum Nachdenken und nachschauen, werd mich aufjedenfall mal in den Bereichen des Cullings Informieren.

Das mit den Lichtern war mir auch noch nicht ganz klar und werde es mal genauer unter die Lupe nehmen, am besten evtl sogar mal das AngryBots zur Hand nehmen und das Shadow Beispiel von Unity selbst.

 

@Tiles

Dir auch danke für die schnelle Antwort. Ich hätte mal ne Frage zu den DrawCalls.

Drawcalls werden nur abgerufen, wenn die Kamera sie erfasst oder werden diese immer im Hintergrund schon geladen?

Mir ist bekannt das DrawCalls zusammengefügt werden können, wenn objekte die selbe Textur+Mesh verwenden, jedoch nicht ganz was diese eig performance mäßig fressen bzw. fressen können.

 

Danke euch beiden

Link zu diesem Kommentar
Auf anderen Seiten teilen

Drawcalls werden nur abgerufen, wenn die Kamera sie erfasst oder werden diese immer im Hintergrund schon geladen?

Mir ist bekannt das DrawCalls zusammengefügt werden können, wenn objekte die selbe Textur+Mesh verwenden, jedoch nicht ganz was diese eig performance mäßig fressen bzw. fressen können.

 

Erstmal müssen die Meshs nicht nur die selbe Textur haben, sondern auch das selbe Material :) Zu deiner anderen Frage:

Im Prinzip sind Drawcalls ja Anfragen an die Grafikkarte, etwas darzustellen. Diese Anfragen sind an sich relativ schnell erledigt (im Millisekundenbereich, ist aber auch wieder je nach Objekt und Situation unterschiedlich). Wenn du nun aber ganz viele dieser Aufrufe pro Frame hast, kann sich das summieren.

 

Ein Beispiel: Du kannst locker 2000 einfache, einfarbige Würfel ohne Batching anzeigen lassen und trotzdem noch sehr hohe FPS haben. Wenn du jetzt jedoch 2000 Highpoly-Modelle + hochauflösende Texturen verwendest, kann es ziemlich eng werden.

 

Grundsätzlich aber musste dir nicht wirklich Gedanken drüber machen, wenn du zwar 1500 Drawcalls hast, es aber ansonsten alles flüssig läuft.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zu den Drawcalls möchte ich etwas ergänzen:

Drawcalls werden dummerweise immer dann erzeugt, wenn die Objekte von der Kamera erfasst werden "könnten", sie also in Richtung der Objekte schaut.

Dabei ist es egal, ob ein Objekt dazwischen liegt und das dahinter liegende Objekt eigentlich garnicht zu sehen ist.

Drawcalls stehen im Zusammenhang mit den Materialien und der Beleuchtung.

Transparente Dinge brauchen, beleuchtete auch!

Hast du viele Objekte mit dem gleichen Material, sparst du Drawcalls. Werden diese Objekte aber von unterschiedlichen Lichtquellen bestrahlt, erhöht sich das Ganze wieder.

Batching funktioniert somit nur da, wo die gleichen Materialien nicht unterschiedlich beleuchtet werden.

 

Auf einem Rechner mit handelsüblicher Grafikkarte machen die Drawcalls echt nicht soo viel aus. Auf einem iPad, wo die Grafik ganz anders dargestellt wird, aber schon!

Grob über den Daumen ergeben (bei einem iPad1) 5 Drawcalls einen Verlust von einem Frame/sec.

Hast du also 100 Drawcalls, verlierst du dadurch ~ 20 Fps !

 

Die GUI von Unity erzeugt auch mächtig Drawcalls! So hast du bei einem Button schon 1- 2 Drawcalls. öffnest du also ein Inventory mit 30 Ablageplätzen sind schwupps 30-60 Drawcalls dazu gekommen.

Aus diesem Grund nutze ich die GUI von unity nicht mehr und bin auf EZ-GUI umgestiegen.

 

Das alles ist nur bei schwächeren Geräten wichtig. Aber da man ja gerne für solche Geräte programmiert, wollte ich es wenigstens erwähnen. ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Drawcalls werden dummerweise immer dann erzeugt, wenn die Objekte von der Kamera erfasst werden "könnten", sie also in Richtung der Objekte schaut.

Dabei ist es egal, ob ein Objekt dazwischen liegt und das dahinter liegende Objekt eigentlich garnicht zu sehen ist.

Das ist eben der entscheidende Unterschied zwischen reinem Frustum Culling und Frustum Culling mit Occlusion Culling. Frustum Culling filtert nur Objekte weg, die nicht im Kamerasichtfeld sind (ungeachtet von Objekten die hinter anderen versteckt sind). Beim Occlusion Culling geht es darum Objekte zu erkennen, die zwar im Kamerasichtfeld sind, aber hinter anderen Objekten komplett verborgen sind und somit eigentlich überhaupt nicht gerendert werden müssen.

 

Ich kenne mich mit dem Occlusion Culling in Unity nicht so gut aus, aber soweit ich weiß funktioniert das bereits implementierte Occlusion Culling nur in Unity Pro, und auch hier muss man Occluder (also Objekte die andere verbergen können) explizit markieren.

Weitere Infos in der Dokumentation.

 

Manche Szenen sind ohne Occlusion Culling gar nicht performant realisierbar, daher kann Occlusion Culling enorm wichtig sein! Und u.U. lohnt es sich auch ein eigenes Occlusion Culling System zu implementieren, falls man keinen Zugang zu Unity Pro hat oder das dort implementierte System nicht ausreichend ist.

 

Als sehr gutes Anwendungsbeispiel für Occlusion Culling möchte ich die beiden Bilder aus der Unity Dokumentationsseite hier posten:

 

Ohne Occlusion Culling:

OcclusionCulling-0.jpg

 

Mit Occlusion Culling:

OcclusionCulling-1.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für die weiteren Erklärungen.

 

@malzbie

EZ-GUI sieht nicht schlecht aus, jedoch 199 USDollar dafür zu bezahlen scheint mir vorerst etwas zu teuer, aber da mein Spiel Inventar und ein leichtes Benutzerinterface hat werde ich mir das Tool im Hinterkopf mal abspeichern.

Ich denke aber nicht, dass es notwendig ist, wie die meisten ja schon gesagt oder angedeutet haben, ich muss es einfach testen und dort performance sparen, wo die mankos sind.

Ich möchte zwar mein Spiel für jeden verfügbar machen, aber ich denke, dass ich das auf die Dauer nicht halten kann.

 

 

 

Also Lichter, Drawcalls, Anzahl der Objekte/Polygonanzahl daran sollte ich mich halten. (Scripte verbessern und optimieren, da ich recht viele in einer einzelnen scene habe)

 

 

Danke an alle, wenn euch bestimmte Techniken/Methoden/Tipps noch einfallen sollten einfach posten, jeder Hinweis ist ein Hinweis der vllt helfen kann. ^^

 

 

MfG

 

TheMorenar

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dazu hätte ich dann auch mal ne Frage: Weiter oben wurde gesagt das es sinnvoll sein kein mehrere Objekte zu einem zusammen zusammen.

In dem Unity Probelevel Bootcamp Wurde ein ganzen Terrain an einem Stück zusammengefasst (Terrain,Bäume usw)

 

Wurde das genau aus diesem Grund gemacht ?

 

Wie wurde das Terrain erstellt direkt mit Unity und wie wurden die Bäume mit dem Terrain verbunden und wann macht dies Sinn?

 

Ebenso wurde das Terrain bemalt es wurde sogar mit dunkler Farbe die stellen bemalt wo später mal ein Gebäude oder ein grösser Sein liegt bemalt Wird dieses als Malkierung gemacht das man später weiß wo die gebäuide, Steine hinkommen oder wird das erst später gemacht wenn die steine liegen um einen besseren Kontrast zwischen sein und Terrain zu gewinnen ?

 

Ausserdem ist mir aufgefallen das der Designer beim Modellieren eines geländern teilweise durch objekte durchmodeliert hat,

zb zwei Horrizontale Querstrebe die Paralell verlaufen duch beide geht eine vertikale strebe ist die im Grunde nur ein Langer Zylinder ist der einfach durch beide Objekte hindurchgeht.

 

Ist das Egal so zu Modellieren oder wäre es besser die Objekte verknüftig zu zu verbinden ohne das die Objekte durchsich selbt verlaufen ich hoffe ihr wisst was ich mein.

 

Danke im Vorraus

Link zu diesem Kommentar
Auf anderen Seiten teilen

Genau, das kommt von der Lightmap. Das Terrain ist so weit ich weiß nur ein importiertes Model. Wie du ein solches erstellst, hängt von dem jeweiligen Programm ab.

 

Und ja, in der Tat wurde das aus Performancegründen gemacht. Da der Spieler eh niemals dort hinkommt, braucht man da auch nicht viele Details und kann sich so ein bisschen Ressourcen einsparen.

 

Wegen dem Geländer: Ich schätze mal, dass das Geländer an mehreren Stellen verwendet wird. In dem Fall ist es sinnvoller, einzelne kleine Module zu haben, anstatt für jeden Ort ein eigenes komplexes Model zu erstellen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hätte auch noch mal eine kleine Frage, wenn ich ein Objekt mit Script disable spare ich damit auch performance/resourcen oder wird das objekt immer in einer art schlafphase weiter geladen?

 

Z.B Ein Character der auf dem Rücken 1-15Waffen hat die bei Aktivierung sichtbar werden und der Rest deaktiviert wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...
Z.B Ein Character der auf dem Rücken 1-15Waffen hat die bei Aktivierung sichtbar werden und der Rest deaktiviert wird.

keine gute Idee^^

Die Waffe einfach instanzieren, parenten, Position und Rotation anspassen, fertig... das sind 2-3 Zeilen mehr als sie zu deaktivieren und x unbrauchbare GOs in der Szene zu haben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...