Seite 1 von 3
Premultiplied alpha
Verfasst: 18.08.2013, 20:13
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!
Re: Premultiplied alpha
Verfasst: 18.08.2013, 20:28
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.
Re: Premultiplied alpha
Verfasst: 18.08.2013, 21:36
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!
Re: Premultiplied alpha
Verfasst: 19.08.2013, 00:09
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.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 05:59
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.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 09:01
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.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 09:44
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. ;)
Re: Premultiplied alpha
Verfasst: 19.08.2013, 10:31
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.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 10:44
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
Re: Premultiplied alpha
Verfasst: 19.08.2013, 10:58
von TGGC
dot hat geschrieben:benachbarte Layer zusammenfassen
Dafuer brauch man aber kein Premultiplied Alpha.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 13:07
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.
Re: Premultiplied alpha
Verfasst: 19.08.2013, 13:50
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"... ;)
Re: Premultiplied alpha
Verfasst: 19.08.2013, 23:19
von TGGC
Re: Premultiplied alpha
Verfasst: 20.08.2013, 06:16
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 (70.67 KiB) 5049 mal betrachtet
… denn mehrere Interpolationen zusammenschmeißen ist Murks. Premultiplied Alpha:
- ok.png (62.88 KiB) 5049 mal betrachtet
Re: Premultiplied alpha
Verfasst: 20.08.2013, 10:19
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.
Re: Premultiplied alpha
Verfasst: 20.08.2013, 10:48
von TGGC
Aber man will doch immer gerne wissen, wer im Forum noch nicht mal Grundlagen Mathematik beherrscht f'`8k
Re: Premultiplied alpha
Verfasst: 20.08.2013, 11:53
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.
Re: Premultiplied alpha
Verfasst: 20.08.2013, 12:52
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...
Re: Premultiplied alpha
Verfasst: 20.08.2013, 18:53
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.
Re: Premultiplied alpha
Verfasst: 20.08.2013, 19:46
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.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 08:28
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.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 08:43
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.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 08:53
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:?
Re: Premultiplied alpha
Verfasst: 21.08.2013, 09:53
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.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 10:17
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 ;)
Re: Premultiplied alpha
Verfasst: 21.08.2013, 10:20
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?
Re: Premultiplied alpha
Verfasst: 21.08.2013, 14:45
von TGGC
Waere ja schoen und gut, wenn Krishtys Erklaerungen eben nicht so falsch waeren.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 17:44
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...
Re: Premultiplied alpha
Verfasst: 21.08.2013, 18:05
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.
Re: Premultiplied alpha
Verfasst: 21.08.2013, 21:27
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.