Jump to content
Unity Insider Forum
  • Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011
Sign in to follow this  
malzbie

Performance in Unity3D

Recommended Posts

malzbie    1,332

Gerade unerfahrene Leute haben starke Bedenken, wenn es um die Performance in Unity geht.

Sie haben aus unterschiedlichen Quellen gehört, dass Dies oder Jenes schlecht sein soll und jetzt gehen sie total ängstlich an das Projekt heran.

Denen möchte ich aber sagen:

 

Macht euch nicht verrückt!

 

Denn wie immer ist alles eine Frage von der Menge an leistungsfressenden Dingen, dem gewünschten Resultat und der Hardware, auf der das Spiel laufen soll. Viele Dinge beziehen sich auf Hardware, die kaum noch genutzt wird, wie z.B. das iPad1, welches nicht mehr als 120MB Ram für das Spiel zur Verfügung gestellt hatte. Oder aber es bezog sich auf veraltete Techniken bei denen Unity schon längst performatere Dinge gebastelt hat, wie die unterschiedlichen Lighting-Arten.

 

Ich will mal versuchen, die einzelnen Bereiche abzuarbeiten.

 

Das Grafische:

 

Alles was ich sehen kann kostet Leistung. Mal mehr, mal weniger! Je mehr Realismus ich in ein Spiel rein bringen will umso mehr Leistung wird verbraucht. Denn jedes Poygon, jedes Licht, jede Schattenberechnung und jedes Material verbraucht etwas.

Diese Dinge belasten meist die Grafikkarte, denn die ist es, die das ja anzeigen und vorher berechnen muss.

Habt ihr ein Spiel mit üppiger Szenerie und schaut euch zur Laufzeit mal den Profiler an, dann seht ihr, dass der Grafikbereich die meiste Leistung schluckt.

Unity ist von sich aus schon bemüht, sparsam zu sein und kann gleichartige Dinge zusammen fassen, wenn sie z.B. das gleiche Material haben und auch vom selben Licht bestrahlt werden. Das reduziert die Drawcalls, die einen Großteil der Performance ausmachen.

Man hat die Möglichkeit Beleuchtungen und Verschattung vor zu berechnen und die Ausleuchtung einer Szene zu backen. Das reduziert ganz massiv die Last auf der Grafikkarte, kostet aber Speicherplatz und natürlich geht die Dynamik der Beleuchtung dadurch flöten.

Aber was bringt es, wenn man genau diese Dynamik haben will. Genau, es bringt nichts!

Mit Shadern sieht es genauso aus. Ein einfacher Shader mit nur einer Textur ist recht sparsam. Er gibt aber auch nicht viel her. Schöner ist er, wenn er glänzen kann, transparent ist, erhaben ist und eben realistisch aussieht. Will ich das haben muss ich ihn auch einsetzen.

Die Geometrie eines Körpers sollte natürlich so sparsam wie möglich aufgebaut sein. Die Zeit, wo ein Oberarm aus 12 Polygonen besteht, ist aber längst vorbei. Ich kann zwar vieles mit einer NormalMap simulieren, aber wenn die Ränder des Polygons zu eckig sind, sieht man das und es wirkt einfach nicht. Also auch da muss ich mich den Qualitätsansprüchen stellen und mehr Polygone nutzen.

Ich kann sogar DirectX11 einsetzen und aus wenigen Polygonen eine Million Polygone machen. Ja, aber eben nur auf einer Grafikkarte, die das auch kann. Egal, wollt ihr die Technik einsetzen dann funktioniert es eben auch nur auf einer Hardware, die das auch kann.

Lasst euch also nicht zu stark einschränken. Ihr werdet natürlich irgendwann merken, dass das Ganze zu viel geworden ist und die Framerate einbricht. Meist lässt sich das aber mit etwas geänderter Beleuchtung, LOD oder anderen Dingen schon wieder beheben. Da aber niemand genau sagen kann, wo die Grenzen liegen werden, bringt es auch nichts, wenn man vorher seitenweise darüber diskutiert.

 

Die Physik:

 

Die physikalischen Berechnungen kosten Leistung, die der Prozessor bringen muss. Und es ist klar, dass viele Berechnungen auch viel Leistung kosten.

Trotzdem ist das jetzt kaum ein Bereich, wo man "extrem" sparen muss. Unity kann ohne weiteres mehrere 100 Objekte gleichzeitig physikalisch berechnen.

Einfach schauen, dass nur die Objekte einen Rigidbody bekommen, die auch einen haben müssen weil sie der Schwerkraft oder anderen Forces folgen sollen und/oder Kollisionen auswerten sollen. Collider so einfach wie möglich halten und lieber einen Box-Collider mehr nehmen, als einen Mesh Collider zu nutzen. Meist muss es nämlich gar nicht ganz genau sein. Merkt eh keiner.

 

 

Der Code:

 

Ja, hier kann und muss man aufpassen. Denn wenige Kleinigkeiten können das System ganz schön verlangsamen. Aber macht euch auch hier nicht verrückt. Denn auch hier ist alles eine Frage der Dosis.

Ein paar extreme Dinge will ich aber mal aufzählen.

 

Als Faustregel gilt, dass jede Unity-eigene Funktion, die im Script steht, auch durchlaufen wird. Egal, ob innerhalb dieser Funktion etwas drin steht oder nicht. Die OnGUI Funktion ist die hungrigste, weswegen man so wenig Scripte wie möglich mit dieser Funktion bestücken sollte.

Legt also nur die Funktionen an, die auch wirklich nötig sind, auch wenn das einsparpotential hier (außer bei der OnGUI) nur gering ist.

 

Immer wenn aus einem Script heraus ein anderes Objekt oder dessen Komponente gesucht wird, kostet es Performance. Es hilft aber nichts. Manchmal muss man einfach nach anderen Objekten oder Komponenten suchen. Um jedoch so wenig Leistung wie möglich zu verbrauchen, sollte man nur einmal danach suchen und einfach die Referenz des Gesuchten in eine Variable speichern.

 

Manche Befehle sind recht hungrig, wie z.B. die Entfernungsmessung über Vector3.Distance. Da sollte man sich überlegen, ob denn wirklich in jedem Frame die Entfernung gemessen werden muss oder reicht es vielleicht auch, wenn es nur wenige Male pro Sekunde passiert. So eine Messung würde ja in jedem Frame eine gewisse Grundlast verursachen, die nicht unbedingt sein muss. Und gerade wenn viele Objekte viele Entfernungsmessungen machen, ist es sinnvoll das Ganze in der Zeit aufzuteilen um die Grundlast zu verringern. So ist das natürlich auch mit komplexen Berechnungen die in einer Schleife ausgeführt werden.

 

SendMessage ist ein teurer Befehl, der an ein gewisses Objekt und an all seine Komponenten etwas sendet. Egal ob die Komponente damit etwas anfangen kann, oder nicht. Diesen Befehl sollte man wirklich nur sparsam nutzen. Will ich einem anderen Script jedes Frame etwas mitteilen, dann ist dieser Befehl dafür total ungeeignet. Für ein einmaliges oder seltenes Senden ist er aber voll ok. Für das ständige Übergeben von Informationen bietet sich an, die Komponente, also das andere Script, vorher zu suchen und als Referenz in eine Variable zu speichern. Jetzt kann ich auf alle Public Variablen oder Funktionen des anderen Scripts zugreifen und sie aufrufen oder manipulieren. Das kostet nicht oder kaum mehr, als wenn es eine Variable des eigenen Scripts wäre.

 

Alles das, was ich da aufgezählt habe macht sich erst ab einer gewissen Menge bemerkbar. Je schwächer die Hardware ist, desto früher merkt man es.

Nur weil etwas viel Performance kostet, müsst ihr nicht darauf verzichten. Ihr solltet aber weise damit umgehen.

Nur weil ich etwas jedes Frame tue, muss das nicht schlecht sein. Es kommt halt immer darauf an, was ich da tue und wie viele Objekte das gleichzeitig machen.

Macht euch vorher Gedanken, was ihr für euer Spiel alles braucht und wie ihr das am besten lösen könnt. Aber lasst euch durch diese Planung nicht blockieren. Fangt einfach an. Vieles ist im Nachhinein leicht änderbar.

Spiele, die auf einem PC schön aussehen sollen und können, können nicht unbedingt genauso für ein Handy übernommen werden. Es macht aber nicht unbedingt Sinn, sich auf den kleinsten gemeinsamen Nenner zu einigen. Manchmal muss man einfach mehrere Versionen für ein und das selbe Spiel bauen, weil die Qualitysettings nicht ausreichen werden.

 

Fazit:

Es ist also alles gar nicht so schlimm!

  • Like 20

Share this post


Link to post
Share on other sites
burli    1

Schöner Artikel. Was mir fehlt sind aber die Fallstricke, auf die man reinfallen kann. Ich bin zwar noch relativ neu bei Unity, aber ein paar Sachen hab ich schon mitbekommen.

 

So soll man zB die Zahl der Meshes möglichst niedrig halten. Viele Meshes mit wenig vertices brauchen mehr Ressourcen als wenige Meshes mit vielen vertices.

 

Auch bei C# kann man Leistung verschenken. Mehrdimensionale Arrays sollen etwas langsamer sein als zB bei C++, die for Schleife ist schneller als eine foreach Schleife usw

 

Oder kurz gesagt, Programmierfehler, die zwar funktionieren, aber unnötig Performance kosten, wären interessant

Share this post


Link to post
Share on other sites
Life Is Good    59

Die Punkte, die du ansprichst, kann man nicht so einfach verallgemeinern.

 

Um ein Mesh anzuzeigen muss es auch als Ganzes geladen sein, wenn du also 10 Große statt 100 kleinere hast, dann kann das ein Problem sein.

Ein kleines Mesh fällt schnell außer Sicht und kann dann entladen werden, ein großes Mesh kann dann meistens seltener entladen werden, auch wenn es z.B kaum sichtbar ist.

Unter anderem teilt man deswegen sein Terrain auch in Chunks, statt in ein großes Mesh.

 

Der Zugriff auf ein Mehrdimensionales Array lässt sich schon in Millisekunden bei modernen Rechnenern schwer angeben, die Zeit, die so ein Zugriff kostet, musst du dir in den meisten Fällen schon in Ticks ausgeben lassen, so schnell läuft das alles ab.

Das gleiche gilt, meistens, für die Ersparnis bei Nutzung von For statt Foreach Schleifen.

Wobei For auch nicht immer schneller als Foreach ist, aber dazu findet man genügend im Netz.

 

Um hier in Bedrängnis zu kommen musst du also schon ziemlichen Blödsinn anstellen :D

Man sollte in der jeweiligen Situation schauen was am besten (auch für den Workflow !) geeignet ist.

  • Like 1

Share this post


Link to post
Share on other sites
burli    1

Das man bei den Meshes das richtige Maß finden muss ist klar. Aber so etwas meine ich

 

Das sich die Unterschiede bei Arrays und for Schleifen erst im Bereich von größeren Datenmengen bemerkbar machen ist auch klar. Aber gerade wenn man mehrere zig tausend oder mehr Iterationen pro Frame über einen großen Datensatz machen muss können sich ein paar Mikrosekunden mehr oder weniger schon bemerkbar machen. Alles schon erlebt.

Share this post


Link to post
Share on other sites
malzbie    1,332

Das ist ja alles richtig. Aber das ist genau das, worum es in meinem Post geht!

Die Dosis macht's! Deswegen nicht verrückt machen und sich selbst im Weg stehen, nur weil es vielleicht eine minimal bessere Möglichkeit gibt.

Wer so ans Entwickeln heran geht, wird nie fertig.

Meist kommt man gar nicht in den Bereich, wo es sich spürbar auswirkt. Und wenn doch, dann kann man immer noch optimieren.

Nachträgliches Optimieren gehört einfach zum Entwickeln dazu. :)

  • Like 3

Share this post


Link to post
Share on other sites
3ncrypt0    7

Genau so sehe ich das auch - Ich habe vor 2 Jahren angefangen einen Simulator zu entwickeln. Vor rund 1,5 Jahren habe ich diesen veröffentlicht (war eigentlich nur für mich gedacht). Da ich einer der ersten (glaube sogar der erste) war, der so einen Sim rausgebracht hat, waren die Anforderungen an mich extrem hoch. Ich persönlich versuche natürlich immer das beste heraus zu holen. Versuche immer um die 300FPS zu liegen (auf meinem PC) - Hintergrund ist, dass 50% meiner User Mac User sind und die anderen 50% haben eher Leistungsschwache Laptops oder Ähnliches.

 

Wenn man sich aber an verschiedene Regeln hält (LOD, Baked Lightmaps, Occlusion Culling, Mesh Baker, saubere Scripts und vor allem Singleton, keine leeren Schleifen (void Update), komprimeirte Grafiken etc.), kann man schon einiges heraus holen. Ich versuche immer meinen Sim so detail getreu zu halten wie es nur eben geht. Was bei einem Flugsimulator (fpv quads) nicht immer einfach ist. Die Kamera bewegt sich sehr schnell, kann sehr hoch fliegen (somit kein occlusion culling) und muss noch extrem genaue Physics haben.

 

Das einzige was mir immer noch Kopfschmerzen bereitet, sind Bäume und Grass. Aus diesem Grund bin ich auch auf diesen Thread hier gelandet.

 

VG

Share this post


Link to post
Share on other sites
oci300    4

Ich bin bei meinem Projekt auch einfach so dran gegangen, ohne richtig darauf zu achten. Nur einmal kam ich an einen Punkt, wo es sehr stark geruckelt hat, wenn man in eine bestimmte Richtung geschaut hat. Hab dann mal geguckt, was dort so liegt und Schuld war eine Blumenwiese, bei der ich es (Die hatte ich irgendwann morgens voll verpennt "dahingehauen") leicht übertrieben hatte. Da waren dann mal locker an die 2000 einzelne Blumenmodelle :D Joa, am Ende hatte ich nur noch 100 Blumen und es sah fast genauso aus wie vorher. Deswegen, konnte man auch ganz leicht beheben, als es soweit war .

 

Und einmal hatte ich ne Falle gebaut, wo man in eine Grube mit Dutzenden Mannsgroßen Fledermäusen gefallen ist, die einen dann töten.... Naja, das fand mein Rechner auch nicht gut. Habs dann in Genickbruch durch den Fall geändert :D

 

Lange Rede, kurzer Sinn: Stimmt, wenn es soweit ist, kann man es ändern, vorher sich Verrückt machen braucht man nicht :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×