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?