Also mache ich eine DirectX-Entwicklung, und zwar mit SharpDX unter .NET (aber DirectX / C ++ - API-Lösungen sind anwendbar). Ich bin auf der Suche nach der schnellsten Möglichkeit, Linien in einer orthogonalen Projektion (z. B. Simulation von 2D-Linien für wissenschaftliche Apps) mit DirectX zu rendern.
Ein Screenshot der Arten von Plots, die ich zu rendern versuche, folgt:
Es ist nicht ungewöhnlich, dass diese Arten von Plots Linien mit Millionen von Segmenten und variabler Dicke aufweisen, mit oder ohne zeilenweisem Antialiasing (oder Vollbild-AA ein / aus). Ich muss die Eckpunkte für die Linien sehr häufig aktualisieren (z. B. 20 Mal pro Sekunde) und so viel wie möglich auf die GPU auslagern.
Bisher habe ich versucht:
- Software-Rendering, z. B. GDI +, ist eigentlich keine schlechte Leistung, belastet aber offensichtlich die CPU
- Direct2D-API - langsamer als GDI, insbesondere mit aktiviertem Antialiasing
- Direct3D10 emuliert mit dieser Methode AA mit Vertexfarben und Tessellation auf der CPU-Seite. Auch langsam (ich habe ein Profil erstellt und 80% der Zeit wird für die Berechnung der Scheitelpunktpositionen aufgewendet)
Bei der dritten Methode verwende ich Vertex-Puffer, um einen Dreiecksstreifen an die GPU zu senden und alle 200 ms mit neuen Vertices zu aktualisieren. Ich erhalte eine Bildwiederholfrequenz von ca. 5 Bildern pro Sekunde für 100.000 Liniensegmente. Ich brauche im Idealfall Millionen!
Jetzt denke ich, dass der schnellste Weg wäre, die Tessellation auf der GPU durchzuführen, z. B. in einem Geometry Shader. Ich könnte die Eckpunkte als Linienliste senden oder in eine Textur packen und in einen Geometrie-Shader entpacken, um die Quads zu erstellen. Oder senden Sie einfach Rohpunkte an einen Pixel-Shader und implementieren Sie das Zeichnen von Bresenham-Linien vollständig in einem Pixel-Shader. Mein HLSL ist rostig, Shader Model 2 aus dem Jahr 2006, also weiß ich nicht, was moderne GPUs für verrückte Sachen können.
Die Frage ist also: - Hat das schon jemand gemacht und haben Sie Vorschläge, die Sie ausprobieren sollten? - Haben Sie Vorschläge zur Verbesserung der Leistung durch eine schnelle Aktualisierung der Geometrie (z. B. alle 20 ms eine neue Scheitelpunktliste)?
UPDATE 21. Jan
Ich habe seitdem Methode (3) oben mit Geometry Shader mit LineStrip und Dynamic Vertex Buffers implementiert. Jetzt erhalte ich 100 FPS bei 100.000 Punkten und 10 FPS bei 1.000.000 Punkten. Dies ist eine enorme Verbesserung, aber jetzt bin ich auf Füllrate und Rechenleistung beschränkt, sodass ich über andere Techniken / Ideen nachdenke.
- Was ist mit der Hardware-Instanzierung einer Liniensegmentgeometrie?
- Was ist mit Sprite Batch?
- Was ist mit anderen (Pixel Shader) orientierten Methoden?
- Kann ich die GPU oder die CPU effizient ausmerzen?
Ihre Kommentare und Vorschläge werden sehr geschätzt!