Premultiplied alpha

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Premultiplied alpha

Beitrag von shadow »

Hi Leute,

ich steh mal wieder vorm Berg und hoffe, dass Euch das Thema nicht zu lame ist... Ein Schubs in die richtige Richtung würde mir schon reichen. Thema: Premultiplied alpha.

Generell gehts hier mal wieder um 2D in OpenGL. Seltsamerwiese hatte ich nie Probleme bzw. mir ist nie etwas negativ aufgefallen. In der letzten Zeit aber dann plötzlich: schwarze Ränder um die Grafiken. Kurz gegoogelt und auf das Thema "Premultiplied alpha" gestoßen, was ich vorher noch nie gehört hatte. Falls es unklar ist, was ich meine: http://www.idevgames.com/forums/thread- ... 60124.html

Erst dachte ich, das ist mir eh zu hoch. Noch einiger Recherche ist mir jetzt zumindest eine Grundlage klar: Und zwar dass premultiplied alpha lediglich bedeutet, dass R, G und B vor dem Abspeichern in eine Rastergrafik-Datei (zB PNG) mit Alpha multipliziert wurden. Da ist dann allerdings ein ganzer Schwung an neuen Fragen aufgetaucht, die ich mit Hilfe von Google und Foren-Suche nicht hinreichend beantworten konnte:

* Stimmt meine Annahme überhaupt, das mit R/G/B * A ?
* Stimmt es also folglich, dass die schwarzen Ränder deshalb kommen, weil OpenGL denkt die Grafik wäre premultiplied, sie ist es aber nicht, oder andersrum?
* Warum kann man unterschiedliche Effekte erzeugen, also mit premultiplied alpha, oder ohne? Oder hab ich das falsch gelesen...
* Kann ich irgendwie erkennen, ob mein PNG premultiplied alpha hat, oder nicht?
* Vmtl. ist es einfältig, aber: Ich möchte lediglich das gleiche "Ebenen-Verhalten" beim "Übereinander-Rendern" von Texturen haben, wie in Grafik-Programmen (GIMP, Inkscape etc...) haben. Dort dachte ich eigentlich, dass ich mit dem Alpha-Kanal immer gut klargekommen bin... Und bisher lief das auch immer gut in OpenGL, nur bei manchen Grafiken gibt es jetzt diese seltsamen Ränder
* Stimmt etwas mit meinen Grafiken (PNGs) nicht, oder mache ich beim Rendering etwas falsch?

Btw: Aktuell benutze ich:
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

Folgende Links hab ich schon durch, teilweise aber mit Verständnis-Problemen:
http://blog.rarepebble.com/111/premulti ... in-opengl/
http://home.comcast.net/~tom_forsyth/blog.wiki.html
https://groups.google.com/forum/#!topic ... qbDPmP4L8o
... und noch ein paar mehr ...


Vielen Dank wieder einmal für Eure Unterstützung!
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Die schwarzen Raender kommen normalerweise durch das bilineare Filtering. Bei premultiplied Alpha hat man zusaetzlich noch das Problem, das in durchsichtigen Bereichen keine Farbinformation ist.
Benutzeravatar
Krishty
Establishment
Beiträge: 8247
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

Das landläufige Alpha (im weiteren Verlauf „Deppenalpha“) ist totaler Schwachsinn, weil es auf linearer Interpolation beruht: Du gibst im Alphakanal einen Faktor an, mit dem deine Vordergrundfarbe multipliziert wird; und die Hintergrundfarbe wird mit der Inversen multipliziert:

color = foreground * alpha + background * (1 - alpha)

Die "Deckkraft" der Vordergrundfarbe, also wie viel sie von hinten durchlässt, hat dabei Einfluss darauf, wie viel Licht die Vordergrundfarbe selbst abstrahlt. Das ist kompletter Unfug – so als würden die Spiegelungen auf deiner Glasscheibe umso dunkler werden, je besser du sie putzt. (Das ist tatsächlich die Wirkung. Deshalb sahen Glasscheiben in Videospielen anno 1999 auch so scheiße aus – sie haben Deppenalpha benutzt.) Dabei wissen wir alle, dass gut geputzte Scheiben noch mehr strahlen!

Wie das zusammen mit Interpolation deine hässlichen dunklen Ränder bewirkt, können dir andere erklären; merk dir nur, dass Deppenalpha jeder physikalischen Grundlage entbehrt und darum solche kontraintuitiven Ergebnisse verzapft wie die, die dich dieses Thema haben eröffnen lassen.

Premultiplied Alpha hingegen entspricht in etwa der Art und Weise, wie Transparenz auch in der Natur entsteht: Nämlich immer durch einen multiplikativen Teil für die Durchlässigkeit und einen additiven Teil für die Reflektion:

color = background * transmittance + emission

Bemerk, dass es nur eine Multiplikation gibt statt zweien wie oben. Beispiele dafür, wie du das interpretieren musst:

• Ein Stück heller Pappe hat die Durchlässigkeit 0 (undurchlässig; es kommt kein Licht von hinten durch, darum kannst du nicht durchsehen). Würde es nicht selber Licht von der Lampe reflektieren, die draufstrahlt, wäre es schwarz. Aber das Licht, das es reflektiert, lässt es hell erscheinen; Emission ist also 1.

• Ein dunkles Fliegengitter hat im Durchschnitt die Durchlässigkeit 0,2 (du kannst ein wenig hindurchsehen); emittiert aber kein Licht (ist schwarz) – Emission ist 0. Es dunkelt also den Hintergrund ab.

• Eine Glasscheibe hat die Durchlässigkeit 0,6 (habe ich mir sagen lassen; du kannst also gut hindurchsehen). Zusätzlich reflektiert sie das meiste Licht, das drauffällt (die Spiegelungen sind immer da). Sie hat also da, wo die Spiegelungen hell sind, eine Emission von 1; da, wo nichts spiegelt, 0.

• Feuer: Transmittance gegen 1; Emission gegen 1.

• Nebel: Transmittance < 0,2; Emission (reflektiertes Umgebungslicht) um die 0,5; aber pro Volumen statt pro Oberfläche.

usw usf; setz in die Formel die Werte aus den Beispielen ein und manipulier sie entsprechend allen möglichen Beleuchtungssituationen; dann wirst du sehen, dass die Ergebnisse immer super sind.

Du kannst also alle möglichen Phänomene damit abbilden. PLUS viele Berechnungen werden damit einfacher; aber das werden dir auch andere erklären können. Eine der Nebenwirkungen der einfacheren Rechnungen ist, dass es keine schwarzen Ränder mehr bei Interpolationen gibt.

Jedenfalls jetzt zur Frage, warum du mit Alpha multiplizieren musst:

Alpha ist die inverse Durchlässigkeit. (Das ist schonmal große Scheiße. Wenn du deine Grafikpipeline selber konfigurierst, invertier deine Alphakanäle und benenn sie in Transmittance um, dann wird vieles einfacher nachvollziehbar. Menschen sind große große Trottel und wissen nichts von Physik, das ist der einzige Grund, warum der „Alpha“-Ausdruck noch existiert.) Ist Alpha 1, lässt der Pixel kein Licht von hinten durch. Ist Alpha 0, lässt er alles durch (voll transparent).

Du möchtest den Vordergrund in den Hintergrund übergehen lassen, aber dabei die Durchschnittshelligkeit erhalten. Also nicht etwa wie eine Glasscheibe, die die Hintergrundhelligkeit erhält, und noch mehr reflektiertes Licht draufhaut. Sondern du willst, dass wenn der Hintergrund stark sichtbar ist, dein Vordergrund schwach sichtbar ist. Oder, dass er stark sichtbar ist, wenn der Hintergrund schwach sichtbar ist. Oder 50-50.

Das bedeutet: immer, wenn dein Vordergrund durchlässiger wird, muss er auch weniger Licht emittieren. Wenn er deckender wird, muss er mehr Licht emittieren.

Dein Alpha ist die inverse Durchlässigkeit. Damit ist es also gleichzeitig der Faktor für die Emission, wenn du nicht übermäßig aufhellen willst. Darum musst du das vom Vordergrund emittierte Licht (die Pixelwerte in deiner Bitmap, denn nichts anderes stellen sie dar) mit Alpha multiplizieren. Denn die Inverse davon ist die Durchlässigkeit, und damit wird das Hintergrundlicht gedämpft, sobald es deinen Vordergrund passiert.

Und das ist die Multiplikation mit der inversen Durchlässigkeit, die in der Formel des Premultiplied Alpha entfallen ist, und die du nun selber vornehmen musst. Was ja auch richtig ist: Warum zur Hölle sollte die GPU jeden Pixel unentwegt mit seinem Alpha multiplizieren, wenn du das auch einmal beim Laden der Textur erledigen kannst?

Und jetzt muss ich ganz schnell ins Bett, sonst komme ich auf so Sachen wie: Du musst im linearen Farbraum rechnen, wenn du vernünftiges Alpha haben willst; und eigentlich brauchst du nicht einen Kanal für die Durchlässigkeit, sondern drei (denn denk mal nach warum man rote Signallichter auf größere Distanz sieht als blaue – weil die Durchlässigkeit der Atmosphäre für Rot höher ist natürlich). Das nennt man dann Dual-Source Color Blending.

Was für eine Katastrophe, dass nicht jeder Grafikalgorithmus seit 1962 von mir persönlich entwickelt wurde; dann müsste ich mir jetzt nicht das Maul fusselig labern! Nehmt mir schnell die Batterien raus!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Bitte keinen Quatsch erzaehlen, wenn man es nicht weiss. Das verwirrt nur unnoetig.

Die beiden Formeln sind genau das Gleiche:
color = foreground * alpha + background * (1 - alpha)
color = background * transmittance + emission
Man muss nur die erste mal kurz umschreiben, dann sieht man es
color = background * transmittance + foreground * (1 - transmittance )

Der einzige Unterschied ist nun, das man bei Premultiplied Alpha den Wert "foreground * (1 - transmittance )" abspeichert statt einfach Foreground. Die Multiplikation ist schon ausgefuehrt: premultiplied

In der Praxis hat man bei begrenzten Wertvorrat manchmal bei einer der Versionen den Vorteil der hoeheren Genauigkeit, das haengt aber von der Textur ab, was genau man waehlen sollte.
Benutzeravatar
Krishty
Establishment
Beiträge: 8247
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

Die Formeln sind genau das gleiche, nachdem man sie kurz umgeschrieben hat – nur mit einem Unterschied. Brilliant! Das verwirrt sicher weniger.

Bei quasi allen Warum funktioniert Z mit X, aber nicht mit Y?-Fragen hilft dem OP eine konkrete Antwort garnicht. Bei „Warum haben Euler-Winkel Gimbal Lock und Quaternions nicht“ kannst du auch schön die Situation des Gimbal Locks herleiten und dann beweisen, warum sie im Quaternion-System nicht auftritt. Sowas hat imho aber keinen Lehr- oder Nährwert, weil man damit nur ein eher unnötiges Randproblem erklärt statt dem abstrakten Ganzen. Sollte dich aber nicht davon abhalten, dich ganz ganz dolle anzustrengen und deine Sicht einer Lösung verständlich zu artikulieren :)

Und wo man nicht Quatsch erzählen soll fällt mir noch das hier auf:
TGGC hat geschrieben:Bei premultiplied Alpha hat man zusaetzlich noch das Problem, das in durchsichtigen Bereichen keine Farbinformation ist.
Unsinn; bei Premultiplied Alpha ist das ja gerade entkoppelt, darum ist es so 1337. Nötig ist es aber nur bei additivem Blending. Aber weder dass du es gesagt hast noch dass ich es richtigstelle hilft Shadow.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Krishty hat geschrieben:Die Formeln sind genau das gleiche, nachdem man sie kurz umgeschrieben hat – nur mit einem Unterschied.
Wie gesagt, bitte bring hier nicht dein Halbwissen ein, wenn du das Thema nicht verstehst. Die Formeln sind _EXAKT_ gleich. Der Unterschied ist nur, _WANN_ sie berechnet werden. Deine "Fensterausfuehrungen" sind auch Unsinn und haben nichts mit dem Thema Alpha zu tun.

Bei Premultiplied Alpha, ist der Alpha Wert statisch in die Farbe eingerechnet, was eben sofort Probleme gibt, wenn der Alpha Wert irgendwie dynamisch manipuliert werden soll. Wenn ich bei color = background * transmittance + foreground * (1 - transmittance ) will, dass color = background gilt (also die Textur komplett durchsichtig ist), so muss ich einfach nur transmittance auf 1 setzen, d.h. also Alpha auf 0. In Foreground kann dann ein beliebiger Wert stehen. Wenn ich bei color = background * transmittance + emission ebenso ein Ergebnis haben moechte. Dann muss sowohl transmittance = 1 als auch emission = 0 sein. Der Pixel muss also komplett schwarz sein.

Wenn man jetzt irgendwie den Alpha aendert, dann kann in der ersten Variante eine beliebige Farbe rauskommen, bei Premultiplied Alpha aber immer schwarz! Und wenn man filtert, dann aendert sich der Alpha eben schon dynamisch, da der Alpha Wert vom Nachbarn dazukommt.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Nur weil die eine Formel sich zur anderen Umformen lässt, heißt das noch lange nicht, dass der gesame Blending Algorithmus exakt äquivalent ist, das ist er nämlich absolut nicht. Die beiden unterscheiden sich fundamental, dieser Unterschied wird aber erst klar, wenn man mehr als zwei Farben blended. Dann fällt sofort auf: Blending mit Premultiplied Alpha ist, im Gegensatz zum herkömmlichen Alpha Blending, ein assoziativer Operator. Aus diesem Grund, treten gewisse Filteringartefakte mit premultiplied Alpha nicht auf. Außerdem wird jeder, der Recht bei Sinnen ist, für Image Compositing zu premultiplied Alpha greifen...

Btw: Gimbal Lock tritt mit Quaternions genauso auf. ;)
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Bitte hoert auf, Unsinn zu erzaehlen. Das hilft echt nicht weiter. Alpha Blending ist nicht und soll nie eine assoziative Verknuepfung sein. Das hiesse naemlich, das es voellig egal ist in welcher Reihenfolge man durch die halbtransparenten Objekte schaut.

Das der Algorithmus anders ablaeuft, sagte ich ja gerade. Die Multiplikation wird zu einen anderen Zeitpunkt ausgefuehrt. Der Punkt ist nur, bei gleicher Eingabe, erhaelt man am Ende das gleiche Ergebnis, wenn man alle Zwischenschritte mit ausreichender Genauigkeit ausfuehrt. Reicht die Genauigkeit nicht, gehen Informationen verloren. Da muss dann entsprechend der Informationen, die man verarbeitet, das passende gewaehlt werden, da kann man nicht per se eines der Verfahren als besser annehmen.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

TGGC hat geschrieben:Bitte hoert auf, Unsinn zu erzaehlen. Das hilft echt nicht weiter. Alpha Blending ist nicht und soll nie eine assoziative Verknuepfung sein. Das hiesse naemlich, das es voellig egal ist in welcher Reihenfolge man durch die halbtransparenten Objekte schaut.
Bitte hör auf, Unsinn zu erzählen ;)
Du verwechselst wohl gerade assoziativ mit kommutativ. Assoziativ bedeutet z.B. dass ich benachbarte Layer zusammenfassen und das Ergebnis mit dem Rest zusammenfügen kann und das gleiche Ergebnis erhalte, so lange die Reihenfolge eingehalten wird, was z.B. für Compositing wahnsinnig praktisch ist. Die schwarzen Ränder des OP sind sehr wahrscheinlich ein Filteringartefakt, das mit premultiplied Alpha nicht auftreten würde...

Mehr dazu:

http://home.comcast.net/~tom_forsyth/bl ... lpha%5D%5D
https://developer.nvidia.com/content/al ... or-not-pre
http://blogs.msdn.com/b/shawnhar/archiv ... alpha.aspx
http://blogs.msdn.com/b/shawnhar/archiv ... touts.aspx
http://blogs.msdn.com/b/shawnhar/archiv ... ition.aspx
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

dot hat geschrieben:benachbarte Layer zusammenfassen
Dafuer brauch man aber kein Premultiplied Alpha.
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

Wenn man Premultiplied Alpha Texturen hat und mit den GL-Faktoren SRC_ALPHA und ONE_MINUS_SRC_ALPHA arbeitet, kommt natürlich Quatsch raus und die Ränder werden dunkel. Egal, ob durch Filtering oder nicht. Das ist ganz offenbar so, weil SRC_ALPHA ja bereits verrechnet ist in den Farben der Textur. Es nochmal drauf zu multiplizieren, dunkelt die Farben noch weiter ab und die teil-transparenten-Ränder werden dunkel.
Die Lösung ist hier einfach GL_ONE und GL_ONE_MINUS_SRC_ALPHA zu verwenden und fertig ist der Lack und alles sieht wieder hübsch aus. Damit hätte man dann nämlich die ursprüngliche Formel von src*src_alpha + dst*one_minus_src_alpha überführt zu srcx+dst*one_minus_src_alpha, was der Formel von Krischty entspricht. Ich schreibe absichtlich "srcx", weil srcx=src*alpha bereits pre-multiplied in der Textur gespeichert wird und exakt das ist, was TGGC beschreibt, nämlich die identische Formen zu anderen Zeitpunkten berechnet.

Die Lösung hätte auch jemand dem OP mitteilen können statt hier eine sinnlose Debatte über Gleichheit verschiedener Formeln zu entfachen, die letztlich ja doch alle wieder dasselbe ausrechnen. Schwarze Bereiche bluten damit ebenfalls nicht mehr ein bei Filtering.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

TGGC hat geschrieben:
dot hat geschrieben:benachbarte Layer zusammenfassen
Dafuer brauch man aber kein Premultiplied Alpha.
Du meinst also, dass \($(a \oplus b) \oplus c = a \oplus (b \oplus c)$\) hält, wenn \($\oplus$\) dem üblichen linearen Blending entspricht, sofern man alles richtig macht. Ausgeschrieben:
\(\begin{equation}
(1 - c_a) \cdot ((1 - b_a) \cdot a_{rgb} + b_a \cdot b_{rgb}) + c_a \cdot c_{rgb} = (1 - f(b_a, c_a)) \cdot a_{rgb} + f(b_a, c_a) \cdot ((1 - c_a) \cdot b_{rgb} + c_a \cdot c_{rgb}))
\end{equation}\)
wobei \($f(\alpha_1, \alpha_2)$\) die Funktion sei, die den Alphawert der geblendeten Farbe angibt. Durch Koeffizientenvergleich ist sofort ersichtlich, dass dies nur erfüllt sein kann, wenn gilt:
\(\begin{align}
(1 - c_a) \cdot (1 - b_a) \cdot a_{rgb} &= (1 - f(b_a, c_a)) \cdot a_{rgb} \\
\Leftrightarrow\;b_a + c_a - b_a \cdot c_a &= f(b_a, c_a) \\
\end{align}\)
sowie \(\begin{align}
(1 - c_a) \cdot b_a \cdot b_{rgb} &= f(b_a, c_a) \cdot (1 - c_a) \cdot b_{rgb} \\
\Leftrightarrow\;b_a - b_a \cdot c_a &= f(b_a, c_a) \cdot (1 - c_a),
\end{align}\)
was zu einem Widerspruch führt:
\(\begin{align}
b_a - b_a \cdot c_a &= (b_a + c_a - b_a \cdot c_a) \cdot (1 - c_a) \\
c_a &= c_a \cdot (b_a + c_a - b_a \cdot c_a).
\end{align}\)

Sofern ich nichts übersehen habe, ist was du postulierst also rein prinzipiell unmöglich. Blending mit premultiplied Alpha erfüllt diese Eigenschaft dagegen...

Oder anders ausgedrückt: Mit premultiplied Alpha spielt nur die Reihenfolge, "in der man durch die Objekte schaut" eine Rolle. Mit herkömmlichem, linearem Blending dagegen, spielt zusätzlich noch die Reihenfolge, in der Zwischenergebnisse berechnet werden eine Rolle; es macht dort einen Unterschied, ob ich zuerst das oberste Objekt auf das zweite von oben und dann beide zusammen auf das dritte von oben lege oder zuerst das zweite von oben auf das dritte von oben und dann das letzte oben drauf, obwohl die Reihenfolge, "in der ich durch die Objekte schaue", identisch ist...genau das meint Krishty wohl, wenn er sagt, dass es "jeder physikalischen Grundlage entbehrt"... ;)
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Bild
Benutzeravatar
Krishty
Establishment
Beiträge: 8247
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

dot hat geschrieben:Oder anders ausgedrückt: Mit premultiplied Alpha spielt nur die Reihenfolge, "in der man durch die Objekte schaut" eine Rolle. Mit herkömmlichem, linearem Blending dagegen, spielt zusätzlich noch die Reihenfolge, in der Zwischenergebnisse berechnet werden eine Rolle; es macht dort einen Unterschied, ob ich zuerst das oberste Objekt auf das zweite von oben und dann beide zusammen auf das dritte von oben lege oder zuerst das zweite von oben auf das dritte von oben und dann das letzte oben drauf, obwohl die Reihenfolge, "in der ich durch die Objekte schaue", identisch ist...
… übrigens ist auch das Zusammenspiel aus Transparenz und Nebel zu erwähnen. (von hier) Alpha:
notok.png
notok.png (70.67 KiB) 4180 mal betrachtet
… denn mehrere Interpolationen zusammenschmeißen ist Murks. Premultiplied Alpha:
ok.png
ok.png (62.88 KiB) 4180 mal betrachtet
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

In wie fern ist das für den OP relevant oder interessant?
Die einzige wirklich hilfreiche Antwort für ihn wäre gewesen:

GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);

Feierabend.
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Aber man will doch immer gerne wissen, wer im Forum noch nicht mal Grundlagen Mathematik beherrscht f'`8k
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Schrompf »

Hört auf zu stänkern, Leute. Krishty hat eine sehr anschauliche Deutung der Alphablending-Formel geliefert, das würde als Antwort völlig reichen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Schrompf hat geschrieben:Hört auf zu stänkern, Leute. Krishty hat eine sehr anschauliche Deutung der Alphablending-Formel geliefert, das würde als Antwort völlig reichen.
Jo, wenn er die falschen Aussagen weggelassen haette...
Benutzeravatar
Krishty
Establishment
Beiträge: 8247
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

Blue Cobold hat geschrieben:In wie fern ist das für den OP relevant oder interessant?
Die einzige wirklich hilfreiche Antwort für ihn wäre gewesen:

GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);

Feierabend.
So gern ich das auch geschrieben hätte (aber mangels OpenGL-Kenntnisse nicht konnte) – man soll nichts benutzen ohne es im Ansatz zu verstehen (was Shadow NICHT tat); und diesen Thread werden in den nächsten Jahren auch noch tausende Besucher lesen, die ebenfalls nicht wissen, warum sie Premultiplied Alpha nutzen sollten.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Jo, und darum ist es halt schlecht, wenn Leute mit Halbwissen daherkommen und im Prinzip erklaeren: Mir fehlen die einfachsten mathematischen Grundlagen um mit Alpha umzugehen, daher benutzt fuer alles immer Premultiplied.
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

Krishty hat geschrieben:So gern ich das auch geschrieben hätte (aber mangels OpenGL-Kenntnisse nicht konnte) – man soll nichts benutzen ohne es im Ansatz zu verstehen (was Shadow NICHT tat); und diesen Thread werden in den nächsten Jahren auch noch tausende Besucher lesen, die ebenfalls nicht wissen, warum sie Premultiplied Alpha nutzen sollten.
So sehr ich deinen Erklärungswillen auch gutheiße, aber der Grund, warum ich jahrelang nicht zu zfx wollte ist der, dass eine Erklärung hier gern mit scheinbar übermäßig wissenschaftlichen Ansprüchen derart verkompliziert wird, dass man sich total untersetzt und lächerlich gemacht fühlt. Eine Erklärung hätte einfach nur kurz auf den Punkt der mit Faktoren versehenen Summe der verschiedenen Farbanteile eingehen müssen statt irgendwelche wüsten Assoziationen mit Physik und weiß der Geier. Das ist meiner Meinung nach sicherlich noch immer ein Punkt, warum zfx so unterbevölkert ist. Hier traut man sich als nicht-studierter Elite-Soldat ja kaum eine Frage zu stellen und wenn doch, kapiert man die Antwort dennoch nicht. Für Anfänger sehr erschreckend und genau diese Befürchtung klingt in einigen Topics schon bei der Fragestellung deutlich mit oder wird sogar explizit geäußert.
Vielleicht sollte man daher an der Stelle versuchen die Sache mal etwas simpler darzustellen. Sogar in meiner Diplomarbeit, wo ich auch auf die Verrechnung der Farbkomponenten durch die GL-Spezifikation kurz eingehe, ist das viel einfacher nachvollziehbar. Der OP hat ja mehr als deutlich gemacht, dass ihm das Thema zu komplex ist und dann mit einer noch komplizierteren Antwort statt mit einer kurzen und einfachen Erklärung daher zu kommen, finde ich irgendwie mehr als unpassend. Zudem wurde ihm ja nichteinmal mitgeteilt, WIE er sein Problem denn nun überhaupt beheben kann. Mit den falschen Blend-Faktoren nützt ihm auch diese ganze mathematisch Erklärung nämlich rein gar nichts. Dass Du kein OpenGL kannst, das sei mal außen vor gelassen, aber dass man den einen Faktor von Alpha auf 1 setzen muss, das hätte man doch wirklich mal kurz erwähnen können, das ist für manche eben aus der rein mathematischen Formel nicht erkennbar.
Auch die zukünftig von Dir erhofften tausende User werden Deine mathematische Rauchwolke wohl nicht nachvollziehen können und keine Lösung für ihr Problem darin finden.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Premultiplied alpha

Beitrag von Artificial Mind »

Und das ist der Punkt wo ich mich auf die Seite von Krishty stelle: Ich habe aus seiner Antwort viel gelernt und mich überzeugen lassen in der nächsten Iteration meiner Grafik Pipeline mit Transmittance statt Alpha zu arbeiten (und sei es nur semantisch).

Das ganze Alpha-Rumgerate bis das Blending so klappt, wie ich mir das vorgestelle, ging mir immer tierisch auf die Nerven. Das auf die Physik zurückzuführen hat mir wesentlich mehr geholfen, als nur die "richtigen Gleichungen" zu bekommen.

Ich wünsche mir, dass ZFX weiter so bleibt.
Bergmon
Beiträge: 46
Registriert: 03.05.2003, 16:39
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Bergmon »

Hallo shadow,

noch zwei Links, die vielleicht die ganze Sache etwas für dich aufhellen. Vielleicht kennst du sie noch nicht?

http://blogs.msdn.com/b/shawnhar/archiv ... ition.aspx
http://home.comcast.net/~tom_forsyth/bl ... ed%20alpha

Für die mathematisch Interessierten: Der Knackpunkt ist (Nicht-)Assoziativität der gewählten Blendoperation.
Für die physikalisch Interessierten: Superposition von Licht ist assoziativ, wenn man die EM-Wechselwirkung vernachlässigt, deswegen benötigt man eine Blendoperation die assoziativ ist. Das ist insbesondere dann wichtig, wenn Transmission und Reflexion überlagert werden (Superposition!), so wie Krishty es erwähnt hat. Ich denke da gibt es erst ein Mal nicht viel weiteres zusagen.

Viele Grüße
Bergmon

p.s.: Ist im Forum Winterzeit :mrgreen:?
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

Artificial Mind hat geschrieben:Ich wünsche mir, dass ZFX weiter so bleibt.
Genau so wird es auch bleiben, denn so war es schon immer. Das ändert aber nichts daran, dass die einfache Erklärung für einen Einsteiger nicht vorhanden war. Schön und gut, wenn du doch noch was dabei gelernt hast, dem Anfänger allerdings war damit vermutlich nicht geholfen. Genau der hat aber übrigens nach Hilfe gesucht, nicht Du.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Premultiplied alpha

Beitrag von Artificial Mind »

Blue Cobold hat geschrieben:
Artificial Mind hat geschrieben:Ich wünsche mir, dass ZFX weiter so bleibt.
Genau so wird es auch bleiben, denn so war es schon immer. Das ändert aber nichts daran, dass die einfache Erklärung für einen Einsteiger nicht vorhanden war. Schön und gut, wenn du doch noch was dabei gelernt hast, dem Anfänger allerdings war damit vermutlich nicht geholfen. Genau der hat aber übrigens nach Hilfe gesucht, nicht Du.
Wahrscheinlich bin ich da auch zu idealistisch. Zugegeben, eine einfachere _Erklärung_ hätten dem OP vielleicht schneller geholfen, eine einfache _Lösung_ (aka einfach die Formel posten) hat aber kaum/keinerlei Lerneffekt. Für Fragen im Format "ich habe ABC geschrieben und es geht nicht" mit der Antwort "du hättest AB.C() schreiben müssen" gibt es ja immerhin Stackoverflow.

Und außerdem: "Stellt euch mal alle nicht so an". Das was Krishty geschrieben hat war eine gut verständliche Erklärung ohne große mathematische Kenntnis vorauszusetzen. Hättet ihr euch z. B. bei so einer Antwort wie dieser hier beschwert, hätte ich ja nachvollziehen können, dass dies nicht einsteigerfreundlich ist.

Ansonsten: was Schrompf gesagt hat ;)
Matthias Gubisch
Establishment
Beiträge: 470
Registriert: 01.03.2009, 19:09

Re: Premultiplied alpha

Beitrag von Matthias Gubisch »

Sorry für Offtopic

Also ich finds toll dass einem hier nicht nur die Lösung hingeklatscht wird sondern es ausführliche Erklärungen dazu gibt.
Machmal wäre es für Anfänger vielleicht hilfreich wenn die Lösung zustäzlich zur Erklärung gepostet wird, nur ob dann noch jemand die Erklärung liest?
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Waere ja schoen und gut, wenn Krishtys Erklaerungen eben nicht so falsch waeren.
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Ok Leute... puh :D

Erstmal danke für die vielen Antworten.
Und sorry, dass es jetzt etwas unruhig wurde hier...

Ich finde es auch schön, nicht einfach nur eine "Lösung" vorgelegt zu bekommen. Eine Diskussion zum Thema ist mir sehr recht. Ich hoffe, das war auch aus der Fragestellung herauszulesen.
Problem ist hier eh: Das mit GL_ONE hatte ich auch schon probiert. Da habe ich dann bei anderen Texturen Probleme bekommen, was ich mit den Informationen her so langsam hoffentlich nachvollziehen kann.
Blue Cobold hat geschrieben:Wenn man Premultiplied Alpha Texturen hat und mit den GL-Faktoren SRC_ALPHA und ONE_MINUS_SRC_ALPHA arbeitet, kommt natürlich Quatsch raus und die Ränder werden dunkel. Egal, ob durch Filtering oder nicht. Das ist ganz offenbar so, weil SRC_ALPHA ja bereits verrechnet ist in den Farben der Textur. Es nochmal drauf zu multiplizieren, dunkelt die Farben noch weiter ab und die teil-transparenten-Ränder werden dunkel.
Die Lösung ist hier einfach GL_ONE und GL_ONE_MINUS_SRC_ALPHA zu verwenden und fertig ist der Lack und alles sieht wieder hübsch aus. Damit hätte man dann nämlich die ursprüngliche Formel von src*src_alpha + dst*one_minus_src_alpha überführt zu srcx+dst*one_minus_src_alpha, was der Formel von Krischty entspricht. Ich schreibe absichtlich "srcx", weil srcx=src*alpha bereits pre-multiplied in der Textur gespeichert wird und exakt das ist, was TGGC beschreibt, nämlich die identische Formen zu anderen Zeitpunkten berechnet.
Das erscheint mir aktuell noch am einleuchtensten für mein Problem... eben weil es mit manchen Texturen funktioniert, und mit manchen nicht.

Also stimmt das Folgendes? Egal ob ein PNG premultiplied alpha hat oder nicht, so liegt sie auch im Grafikspeicher vor? Das würde ja bedeuten, ich muss für jede Textur wissen, ob sie premultiplied alpha hat, und dann die glBlendFunc umstellen...

So langsam glaub ich, ich hab beim Texture-Laden irgendeinen Fehler drin...
Benutzeravatar
TGGC
Establishment
Beiträge: 569
Registriert: 15.05.2009, 18:14
Benutzertext: Ich _bin_ es.
Alter Benutzername: TGGC
Echter Name: Ich _bin_ es.
Wohnort: Mainz
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von TGGC »

Das würde ja bedeuten, ich muss für jede Textur wissen, ob sie premultiplied alpha hat, und dann die glBlendFunc umstellen
Genau.

Und wenn in der png eine Normalmap, Specularmap, Glossmap etc. ist musst du auch wissen, wie das interpretiert werden soll.
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

shadow hat geschrieben:Also stimmt das Folgendes? Egal ob ein PNG premultiplied alpha hat oder nicht, so liegt sie auch im Grafikspeicher vor?
Natürlich. Die GPU kann schließlich nicht wissen, wie die Bilddaten im Bild liegen und dann spontan entscheiden, ob die Pixel nun pre-multiplied sind oder nicht. Daher fasst sie die nicht an, das ist Deine Sache. Oder wüsstest Du von allein, ob der ARGB-Wert #70303030 nun pre-multiplied ist oder nicht? ;)
shadow hat geschrieben:Das würde ja bedeuten, ich muss für jede Textur wissen, ob sie premultiplied alpha hat, und dann die glBlendFunc umstellen...
Natürlich heißt es das. Einfacher wäre es, wenn Du Dich bei allen Texturen auf ein Format einigen würdest. ;) Selbst dann will man allerdings gern mal ein paar Sachen anders blenden als den Rest. Zum Beispiel irgendwelche Funken additiv oder solche Späße. Da änderst Du auch wieder nur die Blend-Faktoren.
Antworten