Frage

Ich habe irgendwo gelesen, dass man bei der Wiedergabe einer Menge 3D -Objekte diese zusammenführen könnte, um ein riesiges Netz zu bilden, so dass nur ein Ziehaufruf getätigt wird. Deshalb lassen Sie das Zitat: "GPU machen seine Magie", während die CPU ist kostenlos für andere Anrufe als zeichnen.

Für meine Frage wäre dies also machbar in a 2D -Umgebung mit Leistung In Anbetracht?

Angenommen, wir haben ein einfaches Fliesensystem und anstatt für jede Fliese einen Ziehaufruf zu machen, würde man stattdessen stattdessen Führen Sie alle Kacheln zusammen Um ein großes Sprite zu bilden und dann einen Unentschieden darauf zu rufen.

Jeder Einblick in die Angelegenheit - entweder Tipps, Links oder so weiter - wird sehr geschätzt, da ich keine vorherigen Erfahrung in der Grafikleistung habe.

Bearbeiten: Entschuldigung für meine schlechte Erklärung. Ich erstelle eine TileEngine für den persönlichen Gebrauch und möchte, dass sie so vielseitig wie möglich ist. Deshalb möchte ich in naher Zukunft viele Kacheln zeichnen, falls ich viele Kacheln zeichnen muss.

ich tun Verwenden Sie ein Tilesheet, aber was ich mit der Frage meinte, ist, dass das Zusammenführen aller Kacheln, die aus dem Blatt in eine neue Texture2d gezogen werden sollen, Leistung erzielen. Zum Beispiel:

Wir haben 128x72 Kacheln zum Zeichnen auf dem Bildschirm. Anstatt alle Kacheln zu durchlaufen und Ziehung für jede Fliese zu rufen, verschmelzen wir alle Kacheln in eine neue Sprite 1280x720 in Größe und zeichnen sie. Auf diese Weise wird die Methode draw () nur aufgerufen Einmal pro Rahmen. Mein Frage war, wenn dies die Leistung verbessern wird, da es 3D -Objekte bei 3D in ein einzelnes Netz verschmelzen würde.

Weil die Informationen, die ich gesammelt habe, ist, dass Calling Draw () ein Performance -Schwein ist und so wenig wie möglich genannt werden sollte. Jemand zu bestätigen oder zu leugnen? :)

War es hilfreich?

Lösung

Ich habe keine Erfahrung mit XNA und 3D, aber ich werde Ihnen einige Ratschläge für 2D -Spiele geben. Ich habe einige Zeit damit verbracht, zu Beginn dieses Jahres einen Fliesenmotor in XNA zu erstellen und habe mich dasselbe gefragt. Ich denke, die kurze Antwort hier lautet Ja, es ist eine gute Idee, Ihre Fliesen zu einem größeren Sprite zu kombinieren, wenn Sie sich Sorgen um die Leistung machen. Es gibt jedoch eine viel längere Antwort, wenn Sie interessiert sind.

Im Allgemeinen lautet die Antwort bei Leistungsoptimierungen fast immer: "Tu es nicht." Wenn Sie sicher sind, dass Sie für die Leistung optimieren müssen, lautet die nächste Antwort fast immer: "Tu es noch nicht." Wenn Sie versuchen, die Leistung zu optimieren, können Sie Benchmarks verwenden, um genaue Messungen der Leistung vor und nach den Änderungen zu erfassen. Ohne das wissen Sie nicht, ob Sie Erfolg haben!

Jetzt, mehr mit 2D -Spielen, habe ich erfahren, dass ich in meiner Fliesenmotor eine viel bessere Leistung gesehen habe, je weniger ich die Texturen gewechselt habe. Nehmen wir zum Beispiel an, ich habe eine Grasfliese und eine Kiesfliese. Wenn es sich um zwei separate Texturen im Speicher handelt, zeichne ich eine Grasfliese, dann eine Kiesfliese, dann eine Grasfliese auf den Bildschirm, die GPU lädt die Grasstruktur und schalte sie dann aus, um die Kiesstruktur zu laden, und schalte dann die Grasstruktur zurück, um eine weitere Grasfliese zu zeichnen. Dies tötet die Leistung sehr schnell! Der einfachste Weg, dies umzugehen, besteht darin, ein Spritblech zu haben, in dem Sie Ihr Gras und Kiesfliesen in eine Textur setzen und SpriteBatch jedes Mal aus einem anderen Bereich auf derselben Textur zeichnen sollen.

Eine andere Sache, die Sie berücksichtigen sollten, ist, wie viele Kacheln Sie gleichzeitig auf den Bildschirm zeichnen werden. Ich kann mich nicht speziell erinnern, aber ich zeichnete Tausende von Fliesen gleichzeitig (in einer vergrößerten Ansicht). Ich bemerkte, dass diese Leistung, wie Sie in Ihrer Frage vorschlagen, als ich größere Fliesen benutzte und weniger von ihnen zog, wie Sie in Ihrer Frage vorschlagen. Dies war jedoch keine so große Verbesserung wie das, was ich im letzten Absatz beschrieben habe, und ich würde Sie immer noch dazu ermutigen, die Leistungsänderungen durch verschiedene Implementierungen zu messen. Wenn Sie nur ein Dutzend oder ein paar hundert Kacheln zeichnen, lohnt es sich möglicherweise nicht, dies jetzt zu optimieren (siehe 2. Absatz).

Nur damit Sie wissen, dass ich das nicht vollständig erfinde, hier finden Sie einen Link zu einem Beitrag von Shawn Hargreaves über Texturwacking, Spriteshoeets usw. Es gibt wahrscheinlich bessere Beiträge in den XNA -Foren sowie Shawn Hargreaves 'Blog, wenn Sie suchen das Thema.

http://forums.xna.com/forums/p/24254/131437.aspx#131437

Aktualisieren:

Da Sie Ihre Frage aktualisiert haben, lassen Sie mich meinen Beitrag aktualisieren. Ich habe mich entschlossen, nur einige Proben zu bewerten, um Ihnen eine Vorstellung davon zu geben, was die Leistungsunterschiede aussehen könnten. In meiner Draw () -Funktion habe ich Folgendes:

        GraphicsDevice.Clear(Color.CornflowerBlue);

        Stopwatch sw = new Stopwatch();
        sw.Start();

        spriteBatch.Begin();

#if !DEBUG
        spriteBatch.Draw(tex, new Rectangle(0, 0, 
                         GraphicsDevice.Viewport.Width,
                         GraphicsDevice.Viewport.Height), 
                         Color.White);            
#else
        for (int i = 0; i < 128; i++)
            for (int j = 0; j < 72; j++)
            {
                Rectangle r = new Rectangle(i * 10, j * 10, 10, 10);
                spriteBatch.Draw(tex, r, r, Color.White);
            }
#endif
        spriteBatch.End();

        sw.Stop();

        if (draws > 60)
        {
            numTicks += sw.ElapsedTicks;
        }
        draws++;

        if (draws % 100 == 0)
            Console.WriteLine("avg ticks: " + numTicks / (draws - 60));

        base.Draw(gameTime);

Lassen Sie einfach den Ausrufezeichen in der Erklärung "#if! Debug" fallen, um zwischen den beiden Methoden zu wechseln. Ich habe die ersten 60 Unentschieden übersprungen, weil sie ein erstes Setup (nicht wirklich sicher was) enthielten und die Durchschnittswerte verzerrten. Ich habe ein 1280x720 -Bild heruntergeladen, und für den Top -Testfall habe ich es gerade einmal gezeichnet. Für den unteren Testfall habe ich das eine Quellbild in Fliesen gezeichnet, 128x72, wie Sie in Ihrer Frage gefragt wurden. Hier sind die Ergebnisse.

Zeichnen eines Bildes:

avg ticks: 68566
avg ticks: 73668
avg ticks: 82659
avg ticks: 81654
avg ticks: 81104
avg ticks: 84664
avg ticks: 86626
avg ticks: 88211
avg ticks: 87677
avg ticks: 86694
avg ticks: 86713
avg ticks: 88116
avg ticks: 89380
avg ticks: 92158

Zeichnung 128x72 Fliesen:

avg ticks: 7902592
avg ticks: 8052819
avg ticks: 8012696
avg ticks: 8008819
avg ticks: 7985545
avg ticks: 8028217
avg ticks: 8046837
avg ticks: 8291755
avg ticks: 8309384
avg ticks: 8336120
avg ticks: 8320260
avg ticks: 8322150
avg ticks: 8381845
avg ticks: 8364629

Wie Sie sehen können, gibt es dort eine Reihe von Größenordnung, so dass es ziemlich bedeutsam ist. Es ist ziemlich einfach, solche Dinge zu testen, und ich würde empfehlen, Ihre eigenen Benchmarks für Ihr spezielles Setup auszuführen, um etwas zu berücksichtigen, das ich möglicherweise verpasst habe.

Andere Tipps

Je weniger die Grafikkarte die Texturen wechseln muss, desto besser die Leistung. Sie können nach Textur in der SpriteBatch.begin () -Methode sortieren, wenn Sie möchten, damit die Grafikkarte die Texturen so wenig wie möglich wechselt.

Ich stecke meine Fliesen / Sprites in Laken, wenn es Sinn macht. Beispielsweise kann sich ein Zeichen in einem Blatt befinden und eine Schicht Fliesen kann sich im selben Blatt befinden. Dies hat bisher ziemlich gut funktioniert.

Ich würde sagen, das optimieren nicht, bis Sie müssen. Wenn Ihre Spiele schnell genug laufen, müssen Sie sich mit der Optimierung beschäftigen.

Rechteck r = neues Rechteck (i * 10, j * 10, 10, 10);

Das Erstellen vieler neuer Objekte nennt die Müllsammlung, die viel verlangsamen kann! Sie sollten keine neuen Objekte in großen Schleifen zuweisen:

Leistung ist kein universeller Imperativ oder ein Gebot von Gott; Es ist ein Mittel zum Zweck. Wenn das, was Sie gut genug erbrachten, haben Sie buchstäblich nichts, was Sie durch die Verbesserung seiner Leistung erhalten können. Die Aufrechterhaltung der "bestmöglichen Leistung zu jeder Zeit" ist die Definition der vorzeitigen Optimierung und führt zu mehr Kopfschmerzen, als sie verhindert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top