Es ist mir größtenteils gelungen, eine Implementierung von Marching Cubes von der CPU auf OpenGL-Compute-Shader zu portieren, aber ich habe mich noch nicht mit Normalen befasst und mich gefragt, wie ich am besten vorgehen kann.
Meine Implementierung befasst sich speziell mit binär bewerteten Feldern (ich versuche, 3D-Fraktalfunktionen zu modellieren, die noch keinen Entfernungsschätzer haben), sodass Gradienten- und Vorwärtsdifferenzmethoden nicht funktionieren. Ich habe gemeinsame Scheitelpunkte, und meine CPU-Implementierung verwendet die hier beschriebene Quilez-Methode, um Gesichtsnormalen auf jedem benachbarten Scheitelpunkt zu akkumulieren.
Ich könnte diese Implementierung einfach auf einen anderen Shader portieren, aber das Problem, das ich dabei sehe, ist die enorme Anzahl der benötigten Atomics. Da wir Atomics nur für skalare Ganzzahltypen verwenden können und ich mir keine Möglichkeit vorstellen kann, 3 vorzeichenbehaftete Ints summierbar in 1 zu packen, bedeutet dies 3 Achsen * 3 Eckpunkte = 9 atomare Adds pro Shader-Aufruf. Sie werden natürlich im ganzen Gedächtnis verteilt sein, also ist es nicht so, als würde man neun Mal einen einzelnen Atomzähler treffen, aber es scheint immer noch verdammt viel zu sein.
Die andere Alternative besteht darin, einen Shader-Aufruf pro Polygon auszuführen und die Liste der Gesichtsnormalen zu erstellen (ich könnte wahrscheinlich auf diese Weise auf x10y10z10 packen), dann einen Shader pro Scheitelpunkt, um alle Normalen benachbarter Gesichter zu akkumulieren. Dies wäre jedoch ein enormer Speicherbedarf. Der Speicherplatz der Gesichtsindizes würde 12 int pro Scheitelpunkt benötigen, um den schlimmsten Fall zu bewältigen. Es gibt auch das Problem, wie man in diesen Speicher schreibt, ohne erneut auf Atomics zurückzugreifen, um herauszufinden, wie viele Gesichter bereits auf einen bestimmten Scheitelpunkt geschrieben wurden.
Hat jemand bessere Ideen, wie das geht?
quelle