Wenn ich ein Objekt baue, dann stelle ich mir folgende Fragen:
- Sieht man dem Objekt an, wie es sich auf die Performance auswirkt?
Beantwortet man diese Frage für sich mit nein, ist da etwas schief gelaufen!
- Inwieweit ergibt es Sinn, gerade in Bezug auf einen Eisenbahnsimulator, das Objekt so zu bauen wie ich es gemacht habe?
Jeder mag hochdetaillierte Objekte, es sieht gut aus, wenn an einem Haus Fenster und Türen ausgearbeitet sind. Aber man sollte sich trotzdem fragen,
ob es in einem Eisenbahnsimulator Sinn ergibt ein Wohnhaus so hochdetailliert zu erstellen. Man könnte es einfacher halten und dafür nützliche Funktionen, wie ein vom Wetter abhängiges Aussehen einzubauen (Ein Dach das mit Schnee bedeckt ist, zB).
- Habe ich gängige Techniken angewandt, um zu mind. ernsthaft zu versuchen, meine Arbeit zu optimieren?
In der heutigen Welt der 3D Grafik gibt es unzählige Techniken, man kann so gut wie nie versuchen die richtige Balance zwischen guten Texturen und detailliertem Mesh zu finden. Es gibt Optimierungsmöglichkeiten für beide Seiten: LOD-Stufen ermöglichen das Umschalten zwischen Meshes unterschiedlicher Detailstufe. Bibliotheken erlauben mehreren Meshes die gleiche Texturen zu nutzen, was natürlich nur dann Sinn ergibt, wenn es eine Fülle an Objekten gibt, die sich Texturen teilen (zB Vegetation).
'Scripts sind das Wundermittel'!
Nicht jedes klitzekleine Objekte muss einen Scriptthread haben, der sekündlich oder gar in der Framezeit (wobei Trainz da nen Riegel vorschiebt) irgendwelche Werte überprüft. Führerstände müssen die Update-Loop (die mit jedem Frame geschossen wird!) auslassen, wenn Sie nicht vom Spieler gesteuert werden.
Bibliotheken können nicht nur als Scriptsammlung sondern auch als eigenes Script im Spiel Threads zur Verfügung stellen und mittels PostMessage(World, ...) Statusupdates an die Spielwelt senden -> Ein Thread für sämtliche Objekte, statt 100 Objekte mit 100 Threads. Gerade wenn jemand mit Scripting anfängt erscheint oftmals als einfachster Weg ein Thread, der zur Überprüfung läuft, statt auf ein auf Ereignisse basiertes System zu setzen. Das ist logisch, weil ein Ereignisbasiertes System etwas schwieriger zu verstehen ist.
Also auch hier: Muss das Script so sein, wie ich es gemacht habe? Sollte ich vielleicht jemand anderen nochmal drüber schauen lassen für eine 2. Meinung?
Sind meine Scripts auf dem aktuellen Stand?
Die API ändert sich ständig. Kompatibilitäten brauchen Performance und tragen null zur Verbesserung bei. Gerade in TRS19 haben wir nichts vom neuen Streckenformat und nichts von der Streaming-Funktion, wenn die Software auf alte Objekte und Scripts Rücksicht nehmen muss. Zu allem Übel scheint der TRS19 komplett zu versagen, wenn man die Funktion zum Streamen einschaltet, weil nichts mehr geht. Und dann wird der Fehler in der Software gesucht. Aber das ist nicht wahr, denn: Es gibt unter meinen von N3V Games eingebauten und standardmäßig für jede Strecke geladenen Objekten nur eine Ausnahme, wo ein Script einen sog. Legacy-Call (also einfach ausgedrückt einen veralteten Funktionsaufruf, der noch zur Kompatibilität nutzbar ist) ausführt. Und das ist ein veraltetes Senden einer Nachricht.
Zum Abschluss;
Unter TS12 waren die sog. Performance Statistiken im Editor und Fahrermodus noch ein Begriff. Hier finden sich auch in TANE und TRS19 Informationen, die wertvoll sein können.
- Worst Script Library
Taucht da ein Script auf, dass zu einem Objekt gehört, welchem man relativ wenig Funktion zurechnent, ist hier etwas komisch! Die Zahl dahinter in Klammern gibt die Anzahl der Calls an, die das Script bisher geleistet hat. Achtung: Ein Führerstand bekommt mit jedem Frame zu mind. einen Call auf seine Update-Funktion.
- Worst Index Count & Worst Buffer Count
Das sind Werte die sich auf die Kombination der sog. Index- und Vertex-Buffer beziehen. Je kleiner das Objekt bei Worst Index Count (und je größer die Zahl dahinter), desto eher wurde verschwenderisch und uneffizient gebaut. Nicht jedes Polygon muss drei eigene Vertices haben, sondern kann sich diese auch mit anderen Polygonen teilen. Hierzu stellen die Modellierungsprogramme Funktionen zum Verschweißen von Vertices zur Verfügung.
Worst buffer count zählt die Anzahl der Vertex-Buffer, je größer die Zahl dahinter, desto mehr einzelne Meshes hat das Objekt. Das ist bei zusammengesetzten Objekten, wie Führerständen und solchen des neuen Gleistyps technisch nicht anders lösbar. Auch hier gilt: Je unbedeutender das Objekt, desto schwerwiegender ist eine hohe Angabe an dieser Stelle.
Quote"Hier finden sich Informationen, die wertvoll sein können"
Man sieht nun, die Angaben bedeuten nicht zwingend etwas schlimmes. Es muss geschaut werden, wie viele Objekte man auf der Map so verbaut hat und dann bewerten, wie der Einfluss der Objekte, die angegeben werden, eigentlich im Vergleich zum Rest angenommen werden sollten. Beispiel: Ich fahre mit einem voll ausgestattetem und ausmodelliertem Fahrzeug mit einer Fülle an Funktionen auf meiner Strecke. Dann würde ich erwarten, dass der Führerstand eventuell in den Statistiken auftaucht. Taucht aber stattdessen Haus XY 1000m Weg von der Strecke dort auf, sollte ich mir jenes Haus nochmal anschauen und seine Position auf meiner Strecke überdenken.
Also immer schön vergleichen, denn Objekte rauswerfen weil sie dort auftauchen ist dann doch zu brachial Es geht hier nämlich um die Bewertung, nicht um das Herausfiltern von schönen Objekten.
Comments 9
Newly created comments need to be manually approved before publication, other users cannot see this comment until it has been approved.
Newly created comments need to be manually approved before publication, other users cannot see this comment until it has been approved.
mick1960
Das predige ich seit Jahren und alles was bislang von allen Daechern gepfiffen wird :"Kreisch, die Polygone, die Polygone...".
callavsg
Das weiß ich
Ich finde man sollte lieber schauen, ob ein Straßenschild tatsächlich eine 2048er Textur benötigt.
Eine 512er reicht oftmals, dafür für ein paar Details ein paar Polys mehr am Mesh ist unter'm Strich dann doch besser.
mick1960
Also nach meinen Erfahrungen, die ich teilweise auch durch empirische Versuche erlangt haben, kann man in der Skala von Performance-Killer bis hin zu vertretbar eindeutig eine Reihe erstellen.
Von schlecht nach macht nicht allzu viel:
- Anzahl der Materialien (nicht zu verwechseln mit der Anzahl der Maps!)
- Anzahl der Textur-Maps
- Groesse der Textur-Maps
- Anzahl der Vertices
Von Polygonen schreibe ich bewusst nichts...
callavsg
Was ich auf jeden Fall deiner Liste noch hinzufügen würde, sind Transparenzen.
Ich habe Tests gemacht, die zeigen, dass 2D Bäume ab T:ANE immer mehr die schlechtere Wahl wurden.
Scheinbar überwiegt die aufwändigere Beleuchtung mittlerweile die damaligen Vorteile von 2D Bäumen gegenüber ausgearbeiteten Bäumen. Im Nachhinein muss ich sagen, dass es auch logisch erscheint. PostProcessing und die physikalisch näher kommendere Beleuchtung in TRS19 müssen Transparenzen ja auch mit einbeziehen.
Mika
Das, und außerdem nutzen SpeedTrees einen eigenen und recht performanten Renderer. Speedtrees in der Entfernung werden z.b. nicht jeden Frame gerendert, was aber nur auffällt, wenn man versucht, weit entfernte Bäume im Editor zu verschieben. Die werden erst nach ein paar Sekunden am neuen Platz angezeigt.
Ich glaube viele dieser Fehler sind auch dem geschuldet, dass viele Tutorials Neulingen ein falsches Verhalten antrainieren, da die meisten Tutorials für 3d-Programme (konkret ist das zumindest bei Blender so) auf einen Rendereinsatz hinarbeiten. Da gilt dann ein je mehr desto besser und es wird zu Wundermitteln wie Bevel o.Ä. geraten die in einer Echtzeitumgebung kompletter Unfug sind. Genauso wird dann auch jedem kleinen Detail ein neues Material zugewiesen, denn anders als die Engine von Trainz welche die Parameter über die Textur pro Pixel steuert, ists beim Rendern oft eine globale Einstellung pro Material.
Dann sind da so Sachen wie Mesh-Libraries mit Materialsharing und Mesh stitching. Fiel mir jetzt relativ leicht da ich bevor ich Blender angefangen hab zu lernen mit der Entwicklung für Trainz vertraut war und das alles logisch erschien. Aber da das halt doch ein recht Spielspezifischer Ansatz ist, denke ich dass auch viele Anfänger erstmal einen Moment brauchen, bis sie das Libraryprinzip verstanden haben. Ich muss auch mal ganz erlich sagen, dass Skriptlibraries als solches schon ein wenig dämlich umgesetzt sind mit der LibraryCall-Methode. Das macht so gut wie niemand sondern lädt dann lieber eine eigene Klasse mit eigenen Methoden.
Gerne würde ich Sachen auch Ereignisbasiert umsetzen, statt ständig über einen Thread zu pingen. Es kommt mir aus anderen Sprachen auch wie ein Verbrechen vor, die verbotenen Worte "while(true)" zu schreiben, aber scheint hier gängige Praxis zu sein. Die meisten bauen dann noch nicht mal nen sleep ein...
Rührt aber leider alles daher, dass das Spiel von sich aus recht wenige Ereignisse ausgibt.
Ich schau mir das mal an wenn ich wieder was habe, was dazu verleitet, vieles mit einem Thread auszustatten. Wusste gar nicht, dass PostMessage an die World funktioniert, denn PostMessage zum Broadcast wird ja in TRS19 von abgeraten.
Greets; Mika
callavsg
Moin Mika,
doch PostMessage(World, ...) funktioniert. Musst den Handler dann aber auch AddHandler(World,...) setzen.
Seit T:ANE Sp3 ist World ein GameObject, funktioniert aber auch mit Interface.
Das ist nicht wahr. Schonmal was von Methodenaufruf gehört? Du brauchst die LibraryCall nicht, es geht viel eleganter.
Der dicke Vorteil von Scriptlibraries, du solltest dir das nochmal in Ruhe anschauen.
Jain, es ist viel hinzugekommen, was nicht in den Scripts steht. Aktiviere mal das Router/Message-Logging im Developer-Reiter des Launchers. Dann siehst du, wie viel eigentlich da hin und her geschickt wird. Und es ist nie verkehrt, wenn man auf Ereignisse im Script reagiert indem man eine Message schickt. Das kann entweder an "World" gehen oder gar an sich selbst, das ist nicht schlimm. Wenn man sich da zu mind. etwas dran hält, dann reichen die eingebauten Messages dicke.
Als Beispiel für einen deutschen Führerstand:
Wenn die PZB eine Zwangsbremsung auslöst, einfach ne Message mitschicken, dass ne Zwangsbremsung ausgelöst wird. Dann kann ein anderer der eine Session bastelt mit einer Rule eventuell darauf reagieren, etc.
Aber mal was anderes: Das ist eine sehr angenehme Diskussion hier!