OpenGL-Standard-Pipeline-Alpha-Blending macht keinen Sinn für die Alpha-Komponente

8

F: Gibt es eine Möglichkeit, die Standard-Pipeline zu verwenden, um die Alpha-Komponente richtig zu mischen?

Problem: Ich zeichne halbtransparente Flächen in eine Textur, dann möchte ich diese Textur in den Hauptrahmen-Puffer putzen. Normalerweise, wenn Sie geradliniges Alpha-Blending für Transparenz oder Antialiasing verwenden, müssen Sie Farbkomponenten in den Back-Buffer mixen (der keinen Alpha-Kanal durch Gehörlose hat).

Beim Mischen mit einer Textur, die eine Alpha-Komponente enthält, mischt die übliche GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALHPA die "Alpha" -Komponente jedoch nicht richtig:

Beachten Sie die problematische Zone über dem Todesstern am Rand der roten und blauen Kreise; Die Alpha-Komponente soll vollständig undurchsichtig sein. Beachten Sie, dass die RGB-Komponenten wie erwartet fließend sind.

Also habe ich mit verschiedenen Einstellungen für die BlendFunc herumgespielt und das, was ich am meisten möchte, ist GL_DST_ALPHA als mein dst Alpha Skalierungsfaktor.

Es gibt immer noch ein Problem mit diesem Ansatz, da das Mischen von zwei Oberflächen mit 50% Opazität eine kombinierte Oberfläche von 75% Opazität ergeben sollte. Aber mit OpenGL-Standardformeln bekomme ich (0,5 * 0,5) + (0,5 * 0,5) = 0,5. Beunruhigender, wenn ich 2 Oberflächen mit 40% Opazität habe, bekomme ich eine weniger deckende Oberfläche: (.4 * .4) + (. 4 * .4) = 0.32.

Die reelle Formel (1 - (1 - srcAlpha) * (1 - dstAlpha)) würde bedeuten, dass ich GL_FUNC_MULT anstelle von GL_FUNC_ADD in der Mischungsgleichung für die Alpha-Komponente verwenden könnte. Leider existiert das nicht.

Also gab ich auf und versuchte eine Lösung mit einem Shader zu machen. Dies wird sehr schnell kompliziert, wenn die Textur, auf die du renderst, auch die Textur ist, von der du liest. Vor allem, wenn Sie mehrere halbtransparente Oberflächen rendern.

Ich suche nach alternativen Lösungen, die ich nicht schon versucht habe. Jede Idee ist willkommen.

BEARBEITEN: Ich habe GL_ONE auch sowohl als src als auch als dst Skalierungsfaktor getestet. dies macht die Alpha-Komponente viel zu undurchsichtig, da 1 * .5 + 1 * .5 1 als das resultierende Alpha ergibt. Ich frage mich, ob GL_ONE und GL_DST_ALPHA bessere Ergebnisse liefern würden.

Gelöst: Nachdem ich die Antwort (siehe Kommentare) kannte, fand ich mehrere Referenzen, die über dieselbe Lösung sprachen:

Ссылка

Ссылка

Ссылка

Ich fühle mich dumm, diese selbst nicht zu finden

ps. : Ich habe Anders Riggelsen 's Mischwerkzeug für die Bilder verwendet.

    
Jean-Simon Brochu 30.05.2016, 19:21
quelle

2 Antworten

6

Eine Standardtechnik zum perfekten Mischen ist die Verwendung von

%Vor%

mit premultipliziert Texturen (oder Farben, wenn Sie keine Texturen haben).

Vormultiplikation bedeutet im Grunde, color.rgb *= color.a auf die Texturen anzuwenden, wenn Sie sie laden (oder die gleiche Gleichung auf die endgültige Farbe in einem Shader anwenden).

Sie können dasselbe Ergebnis erzielen ohne Premultiplikation mit folgendem Mischmodus:

%Vor%

Beachten Sie, dass beide Füllmethoden eine vormultiplizierte Ausgabe erzeugen.

    
HolyBlackCat 30.05.2016, 21:11
quelle
1

Ja, irgendwie.

Mischfaktoren ONE_MINUS_DST_ALPHA, ONE kann zum korrekten Mischen von Alpha verwendet werden. Wenn Sie glBlendFuncSeperate haben, können Sie verschiedene Mischfaktoren für Farbe und Alpha einstellen. Operation ist Hinzufügen.

Ich sage irgendwie, weil, wie ich mich erinnere, getrennte Mischung Func spät in der veralteten API erschien.

Edit: Nach der Mathematik sind diese Mischfaktoren mathematisch äquivalent zu HolyBlackCat Antwort.

    
Andreas 30.05.2016 21:33
quelle

Tags und Links