Welche Methoden gibt es, um Transparenz in OpenGL zu rendern?

14

Alpha Blending kann aktiviert werden, um Oberflächen transparent zu machen:

glDisable(GL_DEPTH_TEST); //or glDepthMask(GL_FALSE)? depth tests break blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Dies funktioniert jedoch nur, wenn Objekte in der Reihenfolge von hinten nach vorne gerendert werden. Ansonsten erscheinen Dinge im Hintergrund vor näheren Objekten, wie z. B. der Boden im Bild unten. Das Sortieren von Partikeln und GUI-Elementen wäre in Ordnung, aber für Dreiecksnetze scheint es zu aufwendig und zu langsam zu sein, wie hier beschrieben: https://www.opengl.org/wiki/Transparency_Sorting .

Was sind die gängigen Methoden, um damit umzugehen? Ich weiß, dass dies ziemlich weit gefasst ist und nicht nach eingehenden Implementierungsdetails, sondern nur einer kurzen Beschreibung einiger Ansätze und der möglichen Auswirkungen.

Bildbeschreibung hier eingeben

jozxyqk
quelle
Ich bin nicht sicher, ob dies eine Antwort sein soll oder nicht, aber die Fehler in Ihrem Bild werden durch Rendern ohne Tiefenprüfung aller Grundelemente verursacht. Sie sollten die Szene in 2 Durchgängen rendern: Rendern Sie zunächst normalerweise alle Volumenkörpergeometrien. Danach deaktivieren Tiefe schreibt (nicht GL_DEPTH_TEST) und macht durchscheinend Geometrie in etwa wieder nach vorne um. Dadurch wird sichergestellt, dass transparente Geometrie nicht vor der Volumenkörpergeometrie gezeichnet wird, die davor liegt.
Yuriks
@yuriks In diesem Fall ist es wahrscheinlich ein schlechtes Beispiel von meiner Seite, aber alles soll transparent sein. Ich wollte etwas zeigen, wie falsch Transparenz aussehen könnte, wenn schlecht gemacht. Auch ein Beispiel, bei dem die Sortiergeometrie erstaunlich schwierig wäre (zum Beispiel ist der Boden hier ein riesiges Polygon und deckt den gesamten Tiefenbereich ab).
Jozxyqk

Antworten:

10

Eine Reihe von Techniken zur Vermeidung einer expliziten Bestellung wird als Order Independent Transparency (kurz OIT) bezeichnet.

Es gibt viele OIT-Techniken.

Historisch gesehen ist dies das Tiefenpeeling . Bei diesem Ansatz rendern Sie zuerst die vordersten Fragmente / Pixel, dann finden Sie diejenige, die der im vorherigen Schritt gefundenen am nächsten kommt, und fahren mit so vielen "Ebenen" fort, wie Sie benötigen. Es wird Tiefenschälen genannt, da Sie bei jedem Durchgang eine Tiefenschicht "schälen". Alle Ebenen können dann normalerweise von hinten nach vorne neu kombiniert werden. Um diesen Algorithmus zu implementieren, benötigen Sie eine Kopie des Tiefenpuffers.

Ein weiterer Satz von Techniken sind die OIT-Mischtechniken. Eine der neuesten und interessantesten ist die von McGuire und Bavoil vorgeschlagene Weighted Blended OIT . Grundsätzlich wird eine gewichtete Summe für alle Flächen angewendet, die ein bestimmtes Fragment belegen. Das von ihnen vorgeschlagene Gewichtungsschema basiert auf dem Kameraraum Z (als Annäherung an die Okklusion) und der Opazität. Die Idee ist, dass, wenn Sie das Problem auf eine gewichtete Summe reduzieren können, Sie sich nicht wirklich für die Bestellung interessieren.

Im Gegensatz zum Originalpapier finden Sie in Matt Pettineos Blog eine hervorragende Quelle für Implementierungsdetails und Probleme mit Weighted Blended OIT . Wie Sie aus seinem Beitrag lesen können, ist diese Technik keine Wunderwaffe. Das Hauptproblem ist, dass das Gewichtungsschema von zentraler Bedeutung ist und entsprechend Ihrer Szene / Ihrem Inhalt angepasst werden muss. Aus seinen Experimenten geht hervor, dass die Technik bei relativ niedriger und mittlerer Opazität gut zu funktionieren scheint. Sie schlägt jedoch fehl, wenn die Opazität gegen 1 geht, und kann daher nicht für Materialien verwendet werden, bei denen ein großer Teil der Oberfläche opak ist (er macht das Beispiel von Laub).

Auch hier kommt es darauf an, wie Sie Ihre Tiefengewichte abstimmen, und es ist nicht unbedingt trivial, diejenigen zu finden, die perfekt zu Ihren Anwendungsfällen passen.

Was für die Weighted Blended OIT erforderlich ist, sind lediglich zwei zusätzliche Renderziele. Eine, die Sie mit der vormultiplizierten Alpha-Farbe (color * alpha) und Alpha füllen, die beide entsprechend gewichtet sind. Der andere nur für die Gewichte.

cifz
quelle
6

Eine Möglichkeit ist das Tiefenschälen.

Im Wesentlichen verarbeitet man die Szene eine festgelegte Anzahl von Malen (sagen wir nMalen), um den nächsten, zweitnächsten bis zu den nnächsten Fragmenten der Szene zu bestimmen .

Diese Verarbeitung wird durchgeführt, indem zuerst ein regelmäßiger Tiefentest auf die gesamte Szene angewendet wird (was natürlich die nächstgelegene Oberfläche ergibt). Das Ergebnis des Tiefentests wird dann zum Herausfiltern der ersten Ebene verwendet, indem alles ignoriert wird, was eine geringere Tiefe als die im Tiefentest zurückgegebene aufweist.

Durch erneutes Anwenden des Tiefentests wird die zweite Schicht zurückgegeben. Wiederholen Sie diesen Vorgang nach Bedarf.

Sobald Sie die Ebenen haben, können Sie einfach alle Ebenen in umgekehrter Reihenfolge zeichnen (vorausgesetzt, Sie haben die RGBA-Farben für jede Ebene im Auge), wobei die Ebenen normal überblendet werden, da sie in der Reihenfolge von vorne nach hinten angeordnet sind.

es1024
quelle
1
Vielen Dank! Es sieht so aus, als würde ich dafür zwei Tiefenpuffer benötigen. Dh eine, um die letzten Tiefen zu speichern und herauszufiltern, und eine, um die Tiefenprüfung für das aktuelle Rendering durchzuführen. Korrigieren Sie mich, wenn ich mich irre, aber ich gehe davon aus, dass ich zwei Tiefenstrukturen für den FBO benötige, die ich zwischen den einzelnen Peelings austausche.
Jozxyqk
1
@jozxyqk Richtig, für dieses Verfahren sind zwei Tiefenpuffer erforderlich.
es1024
1

Die Crème de la Crème von Single-Pass ohne (oder mit wenigen) Kompromissen bei der Transparenz in OpenGL ist ein A-Puffer. Mit modernem OpenGL ist es möglich:

http://blog.icare3d.org/2010/06/fast-and-accurate-single-pass-buffer.html

Es vermeidet die mehrfachen Durchgänge des Tiefenschälens und erfordert kein lästiges Sortieren.

XenonofArcticus
quelle
3
Im Idealfall sollten die Antworten in sich geschlossen sein und von externen Links abhängen. Links zu haben ist hilfreich für ergänzendes Material, aber eine Antwort sollte nicht nur aus einem Schlüsselwort bestehen. Wenn Sie ein paar Details dazu hinzufügen könnten, was ein A-Buffer ist und wie er funktioniert, würde dies Ihre Antwort erheblich verbessern.
Martin Ender