Creazione di normali vertici condivisi su GPU


9

Sono principalmente riuscito a portare un'implementazione di Marching Cubes dalla CPU agli shader di calcolo OpenGL, ma non ho ancora affrontato le normali e mi chiedo il modo migliore per farlo.

La mia implementazione si occupa in modo specifico di campi a valore binario (sto cercando di modellare funzioni frattali 3D che non hanno ancora uno stimatore di distanza), quindi i metodi delle differenze gradiente e in avanti non funzioneranno. Ho condiviso i vertici funzionanti e la mia implementazione della CPU utilizza il metodo di Quilez qui descritto per accumulare le normali delle facce su ciascun vertice vicino.

Potrei semplicemente trasferire questa implementazione su un altro shader, ma il problema che vedo in questo è il numero enorme di atomici necessari. Dato che possiamo usare l'atomica solo su tipi interi scalari e non riesco a pensare a un modo per raggruppare 3 in segno in 1 in modo sommabile, ciò significa che 3 assi * 3 vertici = 9 aggiunte atomiche per invocazione dello shader. Ovviamente saranno diffusi nella memoria, quindi non è come colpire un singolo contatore atomico 9 volte, ma sembra comunque un inferno di molto.

L'altra alternativa è quella di eseguire un invocazione shader per poligono e creare l'elenco normale delle facce (probabilmente potrei comprimere x10y10z10 in questo modo), quindi uno shader per vertice per accumulare tutte le normali delle facce vicine. Questo sarebbe un enorme ostacolo alla memoria, tuttavia, lo spazio di archiviazione degli indici dei volti avrebbe bisogno di 12 int per vertice per affrontare il caso peggiore. C'è anche il problema di come scrivere in questo archivio senza ricorrere nuovamente all'atomica per capire quante facce sono già state scritte su un particolare vertice.

Qualcuno ha idee migliori su come farlo?

Risposte:


5

Per una sola soluzione nVidia è possibile utilizzare i valori intrinseci di aggiunta atomica a virgola mobile (come NvInterlockedAddFp32) Sblocco della GPU Intrinsics in HLSL | Sviluppatore NVIDIA

Ho provato questo su 80.000 mesh di vertici ed è abbastanza veloce (qualcosa come 1 o 2 ms su una GTX980M, se ricordo bene)

Fai attenzione a compilare i tuoi shader in versione affinché gli intrinseci funzionino (a causa del bug / limitazione di nvidia)

Inoltre, fai attenzione alle spaccature dei vertici (ad esempio a causa delle discontinuità UV), dovrai gestirle o altrimenti avrai bordi duri indesiderati nelle cuciture UV.


Perché la domanda è vecchia, ti chiederò invece :-) Per quello che ho capito, semplicemente avere informazioni di adeguamento per ogni vertice non era abbastanza buono per Russ?
Andreas,

Questo è stato per il mio progetto di tesi l'anno scorso, ho finito per andare semplicemente in modo stupido e usando aggiunte atomiche intere, ridimensionate per massimizzare la precisione, quindi normalizzandomi con vettori mobili. Non è stato possibile trovare un modo per elencare le facce attorno a ciascun vertice senza allocare lo spazio nel caso peggiore e utilizzare i contatori atomici per costruire comunque gli elenchi. Probabilmente è inefficiente come l'inferno, ma ho ancora un paio di ordini di accelerazione di magnitudo dalla versione della CPU e un marchio di prima classe, quindi ne sono abbastanza contento :)
russ
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.