Come posso utilizzare la pipeline grafica per eseguire il rendering di dati volumetrici basati su una funzione di densità?


12

Entrambe le API grafiche (OpenGL e DirectX) escogitano una pipeline ben definita in cui sono programmabili diverse fasi. Queste fasi programmabili richiedono di prendere una quantità minima fissa di dati e si suppone che facciano un intervallo ben definito di operazioni su di esso e forniscano un output minimo definito, in modo che i dati possano essere passati correttamente allo stadio successivo. Sembra che queste pipeline siano progettate per funzionare solo con una quantità limitata di tipi di dati geometrici, che nel caso di D3D e OGL sono dati di vertici e coordinate di trama.

Ma, se viene dato un caso in cui l'applicazione che intendo realizzare non utilizza vertici (o anche voxel) per rappresentare i suoi dati geometrici e non esegue esattamente trasformazioni o proiezioni o rasterizzazione o interpolazione o qualcosa del genere, tali limiti delle API o la conduttura rende le cose difficili.

Quindi, c'è un modo in cui possiamo cambiare la pipeline grafica in modo tale che la funzionalità di ciò che ogni fase fa ai dati e il tipo di dati che viene emesso in ogni fase viene modificata a mio vantaggio? In caso contrario, esiste un modo per utilizzare le funzioni API "non elaborate" per costruire la mia pipeline? In caso contrario, si prega di menzionare il motivo per cui non è possibile.

EDIT : My Application utilizza le funzioni di densità per rappresentare la geometria. La funzione ha un valore in ogni punto dello spazio. Divido il frustum della telecamera in una griglia 3d, ogni blocco può essere proiettato come un pixel. Su ogni blocco, integro la funzione di densità e controllo se il suo valore è più di un valore richiesto. Se sì, allora si presume che esista qualcosa in quel blocco e che il pixel corrispondente a quel blocco sia reso. così, ora nel mio renderer, voglio passare la funzione (che rappresento con una stringa) all'hardware grafico anziché ai dati dei vertici nei buffer dei vertici. questo implica anche che lo shader di vertice non avrà vertici da trasformare in spazio di clip omogeneo e che lo shader di frammenti non ottiene informazioni sui pixel. invece, ora la maggior parte della ricerca e della valutazione avviene per pixel.


La "funzione densità di funzione" è una tautologia?
Pharap,

@Pharap, quello era un errore di battitura. è semplicemente "desity functon" che rappresenta la presenza di "materia" nello spazio.
The Light Spark

2
Sembra che tu voglia solo costruire un'isosuperficie, che è un problema ben studiato. Hai visto http.developer.nvidia.com/GPUGems3/gpugems3_ch07.html o cercato su Metaballs, visualizzazione di nuvole di punti, estrazione di isosurface o rendering di volume? Inoltre, quale tipo di prestazioni è necessario, ciò farà un'enorme differenza nella scelta della tecnica che cerchi quando combinato con la complessità dei tuoi calcoli. Penso che scoprirai anche che il per-pixel provocherà un luccichio quando la telecamera si sposta e sarà richiesto un sub-pixel.
Patrick Hughes,

Risposte:


18

Puoi assolutamente usare la GPU per eseguire il rendering di dati volumetrici.

Poiché si desidera valutare una serie di funzioni per pixel sullo schermo, un approccio semplice è il rendering di un triangolo a schermo intero. Questo è solo un singolo triangolo che copre l'intero schermo (in realtà, copre più dello schermo, poiché lo schermo non è triangolare, ma le parti fuori dallo schermo vengono scartate dalla GPU). È quindi possibile utilizzare il pixel shader (che riceve le coordinate dello schermo del pixel che sta sfumando) per costruire un raggio attraverso il volume, valutare le funzioni, qualunque cosa tu debba fare.

(Contrariamente alle altre risposte, non consiglio uno shader di calcolo perché sembra che tu voglia fare operazioni per pixel, e un triangolo a schermo intero + pixel shader è generalmente più efficiente di quello di uno shader di calcolo, anche se anche gli shader di calcolo funzioneranno.)

Il metodo a triangolo a schermo intero è molto comune nella grafica in tempo reale per le operazioni di postelaborazione, quindi puoi probabilmente trovare tutte le informazioni necessarie su di esso con un po 'di googling.

A proposito, potrebbe interessarti leggere Rendering di mondi con due triangoli di Iñigo Quílez, un discorso che descrive come rendere scene 3D composte usando funzioni matematiche (in particolare, campi di distanza) usando la tecnica del pixel shader a schermo intero.


Quindi il pixel shader accetta input arbitrari (come stringhe o altri tipi di oggetti definiti dall'utente) in modo che io possa passare le mie funzioni?
The Light Spark

Dubito che vorresti provare a eseguire un parser e / o una lingua su stringhe di funzioni arbitrarie su GPU, sarebbe imbarazzante poiché le GPU non sono davvero di uso generale. Molto probabilmente vorrai creare lo shader stesso in modo dinamico nel tuo codice principale, quindi lasciare che il sistema grafico compili ed esegua lo shader risultante.
Patrick Hughes,

@TheLightSpark Giusto, non passeresti stringhe allo shader (i linguaggi di shading non hanno nemmeno un tipo di stringa), vorresti generare e compilare il codice shader per le tue funzioni desiderate. Questo può essere fatto in fase di esecuzione, se necessario.
Nathan Reed,

Ho iniziato a leggere la tua risposta, ho immaginato un monitor a forma di triangolo;) Ha un vantaggio usare solo un singolo triangolo anziché due che coprono lo schermo senza scartare i pixel?
danijar,

@danijar Sì, ha un leggero vantaggio rispetto all'utilizzo di un quad poiché alcuni pixel lungo la diagonale verranno ombreggiati due volte se si utilizza un quad a schermo intero. D'altra parte, scartare i pixel fuori dallo schermo è gratuito poiché il rasterizzatore non genererà quei pixel per cominciare.
Nathan Reed,

6

Il ray tracing e altre tecniche sono comunemente eseguite con Compute Shader, che Direct3D ha supportato dal rilascio di D3D11 e OpenGL dal 4.3 (e più a lungo tramite l'uso di OpenCL e alcune contorsioni).


5

Sembra davvero che tu voglia utilizzare uno shader di elaborazione GPU o utilizzare un oggetto "Shader Storage Buffer" per aumentare la pipeline in base alle tue esigenze. Matematici, scienziati e altre persone che guardano alla GPU per il calcolo su cose che non si traducono esattamente in grafica standard usano questo tipo di cose.

Sebbene la pipeline grafica contemporanea sia molto flessibile, gli sviluppatori tendono ancora a imbattersi in alcune restrizioni. La funzione di shader di calcolo, tuttavia, ci rende più semplice non pensare alle fasi della pipeline, poiché siamo abituati a pensare al vertice e al frammento. Non siamo più limitati dagli input e dagli output di alcune fasi della pipeline. La funzione Shader Storage Buffer Object (SSBO), ad esempio, è stata introdotta insieme agli shader di calcolo e offre ulteriori possibilità per lo scambio di dati tra le fasi della pipeline, oltre a essere input e output flessibili per gli shader di calcolo.

http://community.arm.com/groups/arm-mali-graphics/blog/2014/04/17/get-started-with-compute-shaders

Se questo non ti indica la giusta direzione, ti dispiacerebbe espandere il tuo concetto che non si adatta al paradigma vertice / frammento?


Ho modificato la mia risposta per includere ciò che sto facendo. lo shader di calcolo sembra essere la risposta, ma dimmi solo se c'è qualcos'altro che posso fare.
The Light Spark
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.