2016-05-30 16 views
8

F: Gibt es eine Möglichkeit, die Standard-Pipeline zu verwenden, um die Alpha-Komponente ordnungsgemäß zu mischen?OpenGL-Standard-Pipeline-Alpha-Blending macht keinen Sinn für die Alpha-Komponente

Problem: Ich zeichne halbtransparente Oberflächen in eine Textur, dann möchte ich diese Textur in den Hauptrahmen zurück Puffer blit. Normalerweise, wenn Sie geradliniges Alpha-Blending für Transparenz oder Antialiasing verwenden, müssen Sie Farbkomponenten in den Back-Buffer mixen (der keinen Alphakanal von taubult hat).

Wenn jedoch in eine Textur Mischen, die eine Alpha-Komponente hat, die übliche GL_SRC_ALPHA, hat GL_ONE_MINUS_DST_ALHPA nicht mischen, um das „Alpha“ Komponente richtig:

enter image description here

Beachten Sie die problematische Zone über den Todesstern zu der Rand der roten und blauen Kreise; Die Alpha-Komponente soll vollständig undurchsichtig sein. Beachten Sie, dass die RGB-Komponenten erwartungsgemäß bündig sind.

Also spielte ich mit verschiedenen Einstellungen für die BlendFunc und am nächsten, was ich will, ist mit GL_DST_ALPHA als meine dst alpha Skalierungsfaktor.

enter image description here

Es ist immer noch ein Problem mit diesem Ansatz, weil zwei Oberflächen mit 50% Opazität Mischen sollte eine kombinierte Oberfläche von 75% Opazität geben. 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 Blend-Gleichung 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 noch nicht ausprobiert habe. Jede Idee ist willkommen.

EDIT: Ich versuchte auch GL_ONE als src und dst Skalierungsfaktor. 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: Nach wissen die Antwort (siehe Kommentare), fand ich mehrere Referenzen über die gleiche Lösung sprechen:

https://www.opengl.org/discussion_boards/showthread.php/167554-FBO-and-blending

https://forum.openframeworks.cc/t/weird-problem-rendering-semi-transparent-image-to-fbo/2215/10

https://www.opengl.org/wiki/Blending

ich dumm fühle mich nicht Finden Sie diese selbst

p.s. : Ich habe Anders Riggelsen 's Blending-Tool für die Bilder verwendet.

+1

Probieren Sie vormultiplizierte Texturen ('r * = a, g * = a, b * = a 'beim Laden von Texturen oder direkt im Shader) plus' GL_ONE, GL_ONE_MINUS_SRC_ALPHA'. Dies ist eine klassische Methode, um in OpenGL richtig zu blenen. – HolyBlackCat

+0

@HolyBlackCat - Ich lade keine Textur, wie ich im ersten Abschnitt des Abschnitts "Problem" darauf hingewiesen habe: "Ich zeichne halbtransparente Oberflächen in eine Textur". Aber ich werde versuchen, die Combo vorgeschlagen, danke. –

+0

@HolyBlackCat - Genau das habe ich gesucht. Wer wusste, dass es so einfach wäre? Ich poste das als Antwort, ich werde es akzeptieren. –

Antwort

6

Eine Standardtechnik perfekte Mischung zu tun ist,

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

mit Texturen Premultiplied zu verwenden (oder Farben, wenn Sie Texturen nicht haben).

Vormultiplikation bedeutet im Wesentlichen, 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).


können Sie gleiche Ergebnis erzielen ohne Vormultiplikation mit folgenden Mischmodus:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

Beachten Sie, dass beide Füllmethoden produzieren Ausgang Premultiplied.

+0

Ich habe bereits GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA für Farbkomponenten verwendet. Das Problem wurde behoben, indem GL_ONE, GL_ONE_MINUS_SRC_ALPHA für die Alpha-Komponente verwendet wurde. Bedeutung Ich musste separate Faktoren verwenden mit: glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); –

+0

@ Jean-SimonBrochu Das ist ein anderer Weg. Aus irgendeinem Grund habe ich nicht erkannt, dass dasselbe Ergebnis ohne Prämultiplikation erreicht werden kann. Ich habe deine Lösung zu der Antwort hinzugefügt. – HolyBlackCat

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 Art, weil, wie ich mich erinnere, separate Mischung Func erschien spät in der veralteten API.

Edit: nach dem Mathe sind diese Mischfaktoren mathematisch gleichwertig mit HolyBlackCat Antwort.

Verwandte Themen