J'ai surtout réussi à porter une implémentation de Marching Cubes du CPU vers des shaders de calcul OpenGL, mais je n'ai pas encore abordé les normales et je me demande la meilleure façon de procéder.
Mon implémentation traite spécifiquement des champs à valeurs binaires (j'essaie de modéliser des fonctions fractales 3D qui n'ont pas encore d'estimateur de distance), donc les méthodes de gradient et de différences directes ne fonctionneront pas. J'ai partagé des sommets en fonctionnement, et mon implémentation CPU utilise la méthode de Quilez décrite ici pour accumuler des normales de face sur chaque sommet voisin.
Je pourrais simplement porter cette implémentation sur un autre shader, mais le problème que je vois avec cela est le nombre massif d'atomes nécessaires. Puisque nous ne pouvons utiliser l'atomique que sur des types entiers scalaires, et je ne peux pas penser à un moyen de regrouper 3 entiers signés en 1 de manière sommable, cela signifie 3 axes * 3 sommets = 9 ajouts atomiques par invocation de shader. Ils seront répartis dans la mémoire bien sûr, ce n'est donc pas comme frapper un seul compteur atomique 9 fois, mais cela semble encore beaucoup.
L'autre alternative est d'exécuter un shader invocation par polygone et de construire la liste normale des faces (je pourrais probablement emballer à x10y10z10 de cette façon), puis un shader par sommet pour accumuler toutes les normales des faces voisines. Ce serait un énorme porc de mémoire cependant, l'espace de stockage des indices de visage aurait besoin de 12 int par sommet pour faire face au pire des cas. Il y a aussi le problème de l'écriture dans ce stockage sans recourir à nouveau à l'atomique pour déterminer combien de faces ont déjà été écrites sur un sommet particulier.
Quelqu'un a-t-il de meilleures idées sur la façon de procéder?