Ich habe eine Folge von Compute-Shadern, die ein indiziertes Netz erzeugen. Der letzte davon schreibt die generierten Indizes wie folgt:
void addTriangle (uint i0, uint i1, uint i2) {
uint ic = atomicCounterIncrement(indirectIndexCount);
meshIndices[ic*3+0] = i0;
meshIndices[ic*3+1] = i1;
meshIndices[ic*3+2] = i2;
}
Nachdem das Netz generiert wurde, wird es mit glDrawElementsIndirect gezeichnet . Der indirekteIndexCount im obigen Code ist ein atomic_uint- Zähler an Position 0 innerhalb des GL_DRAW_INDIRECT_BUFFER (siehe die Struktur DrawElementsIndirectCommand ). Dieser Zähler ist jetzt offensichtlich um den Faktor drei zu klein, da er für jedes Dreieck nur einmal erhöht wurde. Derzeit multipliziere ich es kurz vor dem Ausgeben des Draw-Aufrufs mit 3.
(Im Moment geschieht dies durch Zuordnen des Puffers und Multiplizieren auf der CPU, was natürlich Unsinn ist, aber zeigt, dass das Ganze im Grunde funktioniert. Alles ist korrekt gezeichnet. Ich könnte es mit einem Aufruf eines einzelnen 1x1x1x1x1x1-Compute-Shaders tun , aber das scheint nur etwas weniger albern.)
Wie werde ich diesen zusätzlichen Multiplikationsschritt los?
Da dies ein offensichtliches Problem zu sein scheint, wenn Netze mit variabler Indexanzahl generiert werden, muss es wohl eine einfache Lösung geben, die ich übersehen habe?
quelle
Antworten:
Wenn Sie Zugriff auf glsl 4.3+ (oder glsl ES 3.1) haben, können Sie atomicAdd verwenden
Die nächste Option besteht darin, a zu verwenden,
barrier()
nachdem alle Scheitelpunkte in der Berechnung generiert wurden, und dann den Wert im Zähler zu multiplizieren:Dies emuliert das Ausführen eines anderen 1x1x1-Compute-Shaders, um den Index zu multiplizieren.
Andernfalls können Sie ein zweites Atom verwenden, um die Scheitelpunktzahl zu speichern:
Beide
indirectIndex
undindirectIndexCount
werden auf 0 initialisiert undindirectIndexCount
an übergebenglDrawElementsIndirect
.quelle