|
Framerate Booster |
Top Previous Next |
|
Der Artikel in diesem Monat wurde inspiriert von einer Frage, die im Forum gestellt wurde: “Ich habe etwa 400 Models in meinem Gebäude, jedes hat etwa 5000 Polygone. Ich versuche, die Framerate etwas zu erhöhen und habe mich gefragt, ob Code, der Entities die nicht zu sehen sind ausblendet die Framerate erhöht.”
Eines vorweg: Eigentlich bin ich niemand, der andere dazu ermuntert, Level mit 2.000.000 Polygonen zu erstellen, es sei denn Sie arbeiten an einer Anwendung für eine Firma, die über einen oder mehrere Supercomputer verfügt. Aber die Frage ist berechtigt: Was kann man tun, um die Framerate in den Spielen zu erhöhen und trotzdem viele Details beizubehalten?
Sehen wir uns zunächst die Demo an: Starten Sie WED, öffnen lod_level.wmp aus dem \boosters Ordner und starten Sie das Level mit der main.wdl; Sie sehen folgendes Fenster.
Ich habe vier verschiedene Demos vorbereitet und jede demonstriert eine Methode, die Framerate signifikant zu verbessern. Drücken Sie “1”, um die erste Demo zu laden; folgendes Bild sollte erscheinen.
Das Level enthält mehrere Kugeln mit je 9.800 Polygonen. Die gesamte Szene enthält 147.000 Polygone, wie der “Engine Polygons” Zähler am unteren Bildschirmrand zeigt. Drücken Sie nun die Leertaste und halten Sie diese gedrückt, damit der Mauszeiger erscheint und ziehen Sie damit den Slider am oberen Bildschirmrand nach links, bis “Clip_far” ungefähr 3.000 zeigt.
Wie Sie sehen sind die Kugeln, die weiter entfernt sind verschwunden und die Anzahl der gerenderten Polygone hat sich von 147.000 auf 49.000 verringert. Auf meinem Rechner hat dies die Framerate von 21 auf 62 fps erhöht. Falls Sie denken, dass Nebel allein genügt, um die Framerate zu erhöhen, weil die Entities verdeckt werden, liegen Sie falsch: der Nebel verschleiert nur die Arbeit von clip_far, wie diese kleine Funktion aus der boosters.wdl zeigt:
starter set_fog() { fog_color = 1; // show the white fog (RGB = 255 set in Wed's File -> Map Properties -> Fog -> Fog1) while (1) { camera.fog_end = camera.clip_far * 0.9; // set fog_end to a value that's 90% of camera.clip_far camera.fog_start = camera.fog_end * 0.01; // set fog_start to 1% of fog_end (play with 0.01 = 1%) wait (1); } }
Die Engine entfernt alle Objekte, die weiter als clip_far Quants von der Kamera entfernt sind automatisch; der Slider ändert nur den Wert von clip_far und die starter Funktion berechnet den Nebel entsprechend (dieser endet dann bei 90% des clip_far Wertes), um sicherzustellen, dass das einfache Ausblenden von clip_far nicht bemerkt wird. Falls Sie mir nicht glauben, entfernen Sie den weißen Nebel aus dem Level und schauen sich an, wie clip_far arbeitet. Oh und vergessen Sie nicht, dass der Hintergrund (bg_color.red green und blue) die gleiche Farbe haben soltle wie der Nebel, damit es keine seltsamen Grafikeffekte gibt.
Gehen Sie auf die verschwundenen Kugeln zu und Sie werden sehen, wie diese wieder auftauchen, wenn Sie näher kommen; diese Technik wirkt wahre Wunder, wenn Sie Nebel in Ihren Levels haben. Aber was ist, wenn Nebel aus einem gewissen Grund ausscheidet oder wenn der Nebel viel zu dicht sein müsste, um die Framerate geeignet zu verbessern?
Verlassen Sie das Level und starten Sie die Demo erneut. Drücken Sie “2” für die LOD Booster Demo.
Ich habe ein extrem detailliertes WMB Gebäude für diese Demo benutzt. Es gibt sogar zwei Kopien davon: eine dunklere, die im Bild oben zu sehen ist und eine hellere, die Sie sehen, wenn Sie die Kamera nach links drehen.
Aber bewegen Sie sich noch nicht; betrachten Sie das dunklere Gebäude, merken Sie sich die Framerate und drehen sich dann nach links. Mein PC zeigt 45 fps für das dunkle Gebäude und 18 fps für das hellere, obwohl sie gleichwertig sind. Warum ist das so? Das dunkle Gebäude nutzt LOD und das andere nicht.
Entfernen Sie sich vom dunklen Gebäude; wie Sie sehen erhöht sich die Framerate noch mehr, weil das LOD System das Gebäude mit einer weniger detaillierten Ansicht austauscht. Gehen Sie nun nahe heran, dann wird es wieder durch die Version mit mehr Polygonen ersetzt. Schauen Sie auf den “Map Polygons” Zähler und die Framerate; LOD hilft dabei, die Framerate enorm zu verbessern!
Meine Demo nutzt das LOD System, das bereits in A6 integriert ist; für diejenigen Leser, die A6 Standard verwenden und keinen Zugriff auf das System haben, habe ich auch eine leicht modifizierte Version des “LOD für alle” Codes aus AUM 53 in die boosters.wdl eingefügt. Um das Skript zu verwenden, geben Sie Ihren Entities die “lod_booster” Action und stellen Sie die Distanzen, bei denen die Veränderung stattfinden soll in Skill1 und Skill2 im WED. Und stellen Sie sicher, dass Ihre Dateinamen der Namenskonvention folgen: building-1.wmb, building-2.wmb und building-3.wmb. Eines noch, was Sie sich vermutlich schon dachten: das integrierte LOD System ist (natürlich) schneller als mein Code.
Bereit für den nächsten Frameratebooster? Starten Sie das Level erneut und drücken Sie die “3” für den vec_dist Booster.
Gehen Sie vorwärts; Sie sehen eine Menge Bäume vor der Kamera auftauchen, die sanft einfaden, wenn Sie näherkommen und wieder transparent werden und verschwinden, wenn Sie sich entfernen.
Die unsichtbaren Entities müssen nicht dargestellt werden, wenn wir also diejenigen ausblenden, die von der Kamera nicht erfasst werden, gibt es einen guten Frameratebonus. Plazieren Sie eine Entity im Level und geben Sie dieser die Action “dist_booster”. Setzen Sie ihren Skill1 (culling_distance) auf den Wert, ab dem die Entity unsichtbar sein soll – das ist alles!
Bevor wir weitermachen, bedenken Sie, dass die Engine nicht auf dem Schirm sichtbare Entities gar nicht erst rendert; wenn Sie viele Gebäude hinter der Kamera haben, dann ist es für die Framerate so, als existierten diese gar nicht.
Starten Sie nun die Demo ein letztes Mal und drücken die “4” für die c_trace Demo. Sie sehen folgendes Bild:
Sie sehen auf eine Wand, die in Wahrheit eine bewegliche WMB Entity ist; drücken Sie die Pfeiltasten links und rechts, um sie zu bewegen.
Sie sehen nun 147.000 Polygone auf dem Bildschirm. Bewegen Sie die Wand etwas und verdecken Sie einige Kugeln; die Engine rendert nun weniger Polygone. Falls Sie denken, dass dies automatisch geschieht, liegen Sie leider falsch.
A6 ist eine BSP (binary space partition) Engine; wenn das Level berechnet wird, dann teilt die Engine es in kleine, irreguläre Bereiche auf, die durch die Wände bestimmt werden. Diese Methode funktioniert super für Lvel, die im Inneren von Gebäuden etc. spielen, weil sie hohe Frameraten auch bei großen Komplexen erlaubt. Wenn ich zum Beispiel alle Kugeln in einen “Käfig”, also einen Hohlwürfel aus Levelblocks sperren würde, dann würden sie nie gerendert werden, da sie unter normalen Umständen nicht sichtbar wären.
In großen Außenlevels jedoch rendert eine BSP Engine auch einige Entities, die nicht sichtbar sind und normalerweise wäre das auch in meiner Demo so. Die Kugeln würden wichtige Ressourcen verbrauchen, selbst wenn die Wand im Weg wäre, manchmal selbst wenn es ein Levelblock und keine WMB Entity wäre. Um dies zu beheben habe ich eine Action definiert, die einen trace von jeder Kugel zur Kamera ausführt und das Model nur dann anzeigt, wenn es von der Kamera gesehen werden kann. Um diese Methode zu nutzen, geben Sie Ihren Entities im Level die “trace_booster” Action.
Die Resultate sprechen für sich: das Panel zeigt “Entity Polygons: 0”, wenn die Mauer alle Kugeln verdeckt. Dies führt, wie man sich leicht vorstellen kann, zu einer insgesamt guten Verbesserung der Framerate. Die Entities werden sanft ein- und ausgeblendet, wenn sie verschwinden und auftauchen; viele moderne Spiele nutzen diese Technik. Schauen Sie sich die booster.wdl genauer an, um mehr über den Code zu lernen und experimentieren Sie ein wenig mit den Methoden oder mischen Sie sie – damit laufen Ihre Projekte sicher schneller!
|