Quindi sto sviluppando alcuni DirectX, usando SharpDX sotto .NET per l'esattezza (ma le soluzioni API DirectX / C ++ sono applicabili). Sto cercando il modo più veloce per eseguire il rendering di linee in una proiezione ortogonale (ad esempio, simulando il disegno 2D per app scientifiche) utilizzando DirectX.
Ecco uno screenshot del tipo di grafici che sto cercando di rendere:
Non è raro che questo tipo di grafici abbia linee con milioni di segmenti, di spessore variabile, con o senza antialiasing per linea (o AA a schermo intero on / off). Devo aggiornare i vertici delle linee molto frequentemente (ad es. 20 volte al secondo) e scaricare il più possibile sulla GPU.
Finora ho provato:
- Il rendering del software, ad esempio GDI +, in realtà non è male, ma ovviamente è pesante per la CPU
- API Direct2D: più lenta di GDI, in particolare con Antialiasing attivo
- Direct3D10 utilizza questo metodo per emulare AA usando i colori dei vertici e la tassellatura sul lato CPU. Anche lento (l'ho profilato e l'80% del tempo è impiegato nel calcolo delle posizioni dei vertici)
Per il 3o metodo sto usando Vertex Buffers per inviare una striscia triangolare alla GPU e aggiornando ogni 200 ms con nuovi vertici. Ricevo una frequenza di aggiornamento di circa 5 FPS per 100.000 segmenti di linea. Ne ho bisogno idealmente milioni!
Ora sto pensando che il modo più veloce sarebbe fare la tassellatura sulla GPU, ad esempio in Geometry Shader. Potrei inviare i vertici come un elenco di linee o impacchettare in una trama e decomprimere in un Geometry Shader per creare i quad. Oppure, basta inviare punti grezzi a un pixel shader e implementare il disegno di Bresenham Line interamente in un pixel shader. Il mio HLSL è arrugginito, shader modello 2 del 2006, quindi non conosco le cose folli che le GPU moderne possono fare.
Quindi la domanda è: - qualcuno l'ha mai fatto prima e hai qualche suggerimento da provare? - Hai qualche suggerimento per migliorare le prestazioni con l'aggiornamento rapido della geometria (ad es. Un nuovo elenco di vertici ogni 20 ms)?
AGGIORNAMENTO 21 gennaio
Da allora ho implementato il metodo (3) sopra usando gli shader Geometry usando LineStrip e Dynamic Vertex Buffer. Ora sto ricevendo 100FPS a 100k punti e 10FPS a 1.000.000 di punti. Questo è un enorme miglioramento, ma ora sono pieno e il calcolo è limitato, quindi ho pensato ad altre tecniche / idee.
- Che dire dell'istanza hardware di una geometria del segmento di linea?
- Che dire di Sprite Batch?
- Che dire di altri metodi orientati (Pixel shader)?
- Posso abbattere efficacemente la GPU o la CPU?
I tuoi commenti e suggerimenti sono molto apprezzati!