2 Stimmen

Grafik: beste Leistung mit Gleitkomma-Akkumulationsbildern

Ich muss einige Augenweiden des Partikelsystems beschleunigen, an denen ich gerade arbeite. Die Augenweide beinhaltet additive Blending, Akkumulation, und Spuren und glühen auf die Partikel. Im Moment bin ich Rendering von Hand in eine Fließkomma-Bildpuffer, Konvertierung in vorzeichenlose Zeichen in der letzten Minute dann hochladen, um eine OpenGL-Textur. Um das Glühen zu simulieren, rendere ich dieselbe Textur mehrmals in verschiedenen Auflösungen und mit verschiedenen Offsets. Dies erweist sich als zu langsam, so bin ich auf etwas zu ändern suchen. Das Problem ist, meine Dev-Hardware ist eine Intel GMA950, aber die Zielmaschine hat eine Nvidia GeForce 8800, so ist es schwierig, OpenGL Sachen in diesem Stadium zu profilieren.

Ich habe einige sehr unwissenschaftliche Profilerstellung und fand heraus, dass die meisten der Verlangsamung kommt aus dem Umgang mit dem Float-Bild: Skalierung alle Pixel durch eine Konstante, um sie auszublenden, und Konvertierung der Float-Bild zu vorzeichenlosen Zeichen und Hochladen auf die Grafik-Hardware. Also, ich bin auf der Suche nach den folgenden Optionen für die Optimierung:

  • Ersetzen von Floats durch uint32s in einer Festkomma-Konfiguration 16.16
  • Optimierung von Float-Operationen mit SSE2-Assembler (Bildpuffer ist ein 1024*768*3-Array von Floats)
  • Verwenden Sie OpenGL Akkumulationspuffer anstelle von Float-Array
  • Verwenden Sie OpenGL Fließkomma-FBOs anstelle von Float-Array
  • OpenGL-Pixel/Vertex-Shader verwenden

Haben Sie Erfahrungen mit einer dieser Möglichkeiten? Irgendwelche Gedanken, Ratschläge? Gibt es noch etwas, an das ich nicht gedacht habe?

0 Stimmen

Das klingt sehr fortschrittlich, gibt es eine Möglichkeit, einen Screenshot zu sehen?

4voto

Nils Pipenbrinck Punkte 80152

Das Problem ist einfach die schiere Menge an Daten, die Sie verarbeiten müssen.

Ihr Float-Puffer ist 9 Megabyte groß, und Sie berühren die Daten mehr als einmal. Höchstwahrscheinlich sieht Ihre Rendering-Schleife in etwa so aus:

  • Den Puffer löschen
  • Rendering von etwas darauf (verwendet Lesen und Schreiben)
  • In Bytes ohne Vorzeichen umwandeln
  • Hochladen zu OpenGL

Das sind eine Menge Daten, die Sie bewegen, und der Cache kann Ihnen nicht viel helfen, weil das Bild viel größer ist als Ihr Cache. Nehmen wir an, Sie berühren jedes Pixel fünfmal. Dann bewegen Sie 45 MB Daten in und aus dem langsamen Hauptspeicher. 45 MB klingt nicht nach viel Daten, aber bedenken Sie, dass fast jeder Speicherzugriff ein Cache-Miss ist. Die CPU wird die meiste Zeit damit verbringen, auf das Eintreffen der Daten zu warten.

Wenn Sie für das Rendering auf der CPU bleiben wollen, können Sie nicht viel tun. Einige Ideen:

  • Verwendung von SSE für nicht temporäre Lasten und Speicher Mai helfen, aber sie erschweren Ihre Aufgabe erheblich (Sie müssen Ihre Lese- und Schreibvorgänge aufeinander abstimmen).

  • Versuchen Sie, Ihr Rendering in Kacheln aufzuteilen. Machen Sie z.B. alles auf kleineren Rechtecken (256*256 oder so). Die Idee dahinter ist, dass Sie einen Nutzen aus dem Cache ziehen können. Nachdem Sie zum Beispiel Ihr Rechteck gelöscht haben, befindet sich die gesamte Bitmap im Cache. Das Rendern und Konvertieren in Bytes wird nun viel schneller sein, da die Daten nicht mehr aus dem relativ langsamen Hauptspeicher geholt werden müssen.

  • Letzter Ausweg: Verringern Sie die Auflösung Ihres Partikeleffekts. Dadurch erhalten Sie ein gutes Preis-Leistungs-Verhältnis auf Kosten der visuellen Qualität.

Die beste Lösung ist, das Rendering auf die Grafikkarte zu verlagern. Die Rendering-to-Texture-Funktionalität ist heutzutage Standard. Es ist ein bisschen schwierig, es mit OpenGL zum Laufen zu bringen, weil man sich entscheiden muss, welche Erweiterung man verwenden will, aber sobald es funktioniert, ist die Leistung kein Problem mehr.

Übrigens - haben Sie vraiment benötigen Sie Gleitkomma-Rendering-Ziele? Wenn Sie mit 3 Byte pro Pixel auskommen, werden Sie eine schöne Leistungssteigerung sehen.

0 Stimmen

Vielen Dank für Ihre Antwort! Ich habe das in der ursprünglichen Frage nicht deutlich gemacht, aber ich bin wirklich daran interessiert, schöne Spuren zu hinterlassen, die schwebende Bilder benötigen, damit man sie über einen langen Zeitraum hinweg sanft ausblenden kann...

2voto

Crashworks Punkte 39230

Es ist am besten, die Rendering-Berechnung für massive Partikelsysteme wie dieses auf die GPU zu verlagern, deren Hardware genau für diese Aufgabe so schnell wie möglich optimiert ist.

Aaron hat recht: Stellen Sie jedes einzelne Partikel mit einem Sprite dar. Sie können die Bewegung der Sprites im Raum (z.B. ihre Position pro Frame akkumulieren) auf der CPU mit SSE2 berechnen, aber alle additiven Überblendungen und Akkumulation auf der GPU über OpenGL durchführen. (Zeichnen Sprites additiv ist einfach genug.) Sie können Ihre Spuren und Unschärfe behandeln, indem Sie es entweder in Shadern (die "pro" Weg), Rendering zu einem Akkumulationspuffer und zurück, oder einfach eine Reihe von zusätzlichen Sprites auf der CPU, die die Spur und werfen sie an den Rasterizer.

1voto

Aaron Digulla Punkte 308693

Versuchen Sie, den manuellen Code durch Sprites zu ersetzen: Eine OpenGL-Textur mit einem Alpha-Wert von, sagen wir, 10%. Dann zeichnen Sie viele von ihnen auf dem Bildschirm (zehn von ihnen an der gleichen Stelle, um das volle Glühen zu erhalten).

0 Stimmen

Danke, aber das Leistungsproblem tritt nicht im Sprite-Rendering auf (da ich sowieso nur einzelne Pixel zeichne).

0 Stimmen

Wie ich schon sagte: Hör auf, das selbst zu zeichnen und ersetze jedes Teilchen durch mehrere halbtransparente Sprites. Je mehr Sprites du an einer Stelle zeichnest, desto mehr "Glow" solltest du bekommen.

0 Stimmen

Ich habe das in der ursprünglichen Frage nicht deutlich gemacht, aber ich bin wirklich daran interessiert, schöne Spuren zu hinterlassen, und das Leuchten ist zweitrangig. schöne Spuren brauchen schwebende Bilder, damit man sie über eine lange Zeit sanft ausblenden kann.

1voto

unwind Punkte 377331

Wenn Sie mit "manuell" meinen, dass Sie die CPU verwenden, um Pixel zu stoßen, denke ich, dass so ziemlich alles, was Sie tun können, wo Sie texturierte Polygone mit OpenGL stattdessen zeichnen eine enorme Beschleunigung darstellen wird.

0 Stimmen

Hanks; ich bin nicht stochern Pixel auf der Grafik-Hardware, eher mit additiven Blending auf einem Gleitkomma-Array dann Zeichnung, die als eine Textur. das größte Problem mit der Verwendung von texturierten Polygone direkt ist anschließend immer Zugang zu/Änderung der FBO, so dass ich Trails, die im Laufe der Zeit verblassen tun können

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X