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:

Re: Premultiplied alpha

Beitrag von shadow »

Blue Cobold hat geschrieben:Oder wüsstest Du von allein, ob der ARGB-Wert #70303030 nun pre-multiplied ist oder nicht? ;)
Klar nicht. Hätte ja sein können, dass es beim Laden bekannt ist und bei der Textur hinterlegt wird...
Blue Cobold hat geschrieben:Einfacher wäre es, wenn Du Dich bei allen Texturen auf ein Format einigen würdest.
Da haben wir schon das Problem, ich glaube mein Grafik-Tool exportiert manche PNGs mit und manche ohne premultiplied Alpha... so macht es zumindest den Anschein.
Ich kann das aber leider nicht testen, weil bei einem PNG wohl nicht klar ist, ob es premultiplied ist, oder nicht; kann das sein?: http://stackoverflow.com/questions/9147 ... lied-alpha

Aber wie kann dann zB GIMP die Grafiken korrekt öffnen?
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

Ich wäre erstaunt, wenn Gimp das raten kann. Man kann bei gewissen Farbwerten feststellen, dass ein Bild *nicht* pre-multiplied sein kann, andersrum geht das leider nicht immer. Man kann also nicht immer bestimmen, ob ein Bild pre-mul ist oder nicht. Was Gimp da genau tut, kann ich Dir nicht sagen weiß auch nicht, was "korrekt öffnen" heißen soll.
Welches Tool benutzt Du denn, um Deine Grafiken zu exportieren? Denn eigentlich sollte ein Programm immer den selben Weg nehmen und laut PNG-Spec wäre non-multiplied wohl angeblich immer der richtige Weg. Ich weiß aber, dass z.B. 3DSMax die Render-Ergebnisse nur pre-multiplied exportiert und habe damals mal ein eigenes Plugin geschrieben, um da anders ran zu kommen.

Vielleicht solltest Du nochmal beschreiben, warum Du glaubst, dass manche Bilder pre-mul sind und andere nicht, wenn sie aus dem selben Programm stammen. Und auch, welches Programm das ist.
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Das Programm ist Inkscape auf Ubuntu.

Ich werd mal versuchen das verhalten zu provozieren, ein paar repäsentative Grafiken zu finden, und dann melde ich mich wieder.
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

Möglicherweise speichert das Programm Metadaten im PNG. Du könntest die Datei einmal mit Jason Summers TweakPNG öffnen (Nachtrag: Ups; ist Windows-only. Vielleicht kennt jemand eine Alternative), und nachsehen, ob ein entsprechender Kommentar in einem der Chunks steht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html#R.Non-premultiplied-alpha hat geschrieben:PNG uses "unassociated" or "non-premultiplied" alpha so that images with separate transparency masks can be stored losslessly.

Although each form of alpha storage has its advantages, we did not want to require all PNG viewers to handle both forms. We standardized on non-premultiplied alpha as being the lossless and more general case.
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Blue Cobold »

Das hatte ich schon erwähnt. Ändert aber leider nix, falls Incscape selbst pre-multiplied Werte in das PNG schreibt.
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

OH Noooo! Der GAU! Es scheint nix mit premultiplied alpha zu tun zu haben!

Ich hab jetzt hart kodiert mal bei bestimmten Texturen, bei denen ich das Problem zu haben glaubte, von GL_SRC_ALPHA auf GL_ONE umgestellt. Das hätte es ja zumindest fürs Erste geheben müssen. Aber dann hatte ich erst RICHTIGE Ränder... dh die PNGs sind entweder ohne premultiplied alpha oder werden bei meinem Ladevorgang bereits umgerechnet.

Dann scheint es vermutlich doch etwas mit dem bilinearen filterung zu tun zu haben.

Hier ein Ausschnitt aus meinem Rendering (Das Wasser, die Büsche, der Baum etc... sind separate Objekte):
Bild

Tut mir echt leid Leute, dass das jetzt so in die falsche Richtung ging. Kleiner Trost: ich hab echt was dabei gelernt :?
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Und du zeichnest die Dinger auch brav von hinten nach vorne? Kannst du so ein .png vielleicht mal hochladen, dass man es sich anschauen könnte?
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Jup, brav von hinten nach vorn!
Baum_rund_hinten_90dpi.png
Baum_rund_hinten_90dpi.png (9.83 KiB) 2672 mal betrachtet
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

Blender sagt mir, dass da alles außen herum schwarz ist:

Bild

Damit liegt es am der bilinearem Filterung an der Kante.

Ein ähnliches Problem gibt es bei der Berechnung von MipMaps von Texturatlanten. In der Regel werden die Farbwerte durch einen Pull-Push-Algorithmus (Section 3.4.2 und 3.4.3) nach außen getragen; so vermeidet man, dass da benachbarte Pixel schwarz sind. Das sieht man schön an einer Textur, welcher der Crytek-Sponza-Szene beiliegt:

Bild

Alternativ kann man das auch relativ trivial selbst implementieren, da ein Skirt mit einer Dicke von einem Pixel hier ausreichend ist. Dies ist als solches die schönste Lösung, da kein Laufzeitaufwand anfällt.

Oder, wenn dir das zur Laufzeit eh keine Probleme macht (wovon ich ausgehe), kannst du auch einfach den nächsten Texel mit dem kleinsten Alpha-Wert samplen, siehe hier (Slides 24 und 25).
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Merkwürdig, Paint.NET sagt mir, dass außen rum alles mit transparentem Weiß gefüllt ist. In jedem Fall sollte das aber egal sein, wenn die Texturdaten richtig geladen werden. Du verwendest glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE);?
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Ich benutze:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

dot hat geschrieben:In jedem Fall sollte das aber egal sein, wenn die Texturdaten richtig geladen werden.
Ich muss leider sagen, dass ich das jetzt nicht ganz unterstützen kann, aber ich bin auch noch unsicher.

Angenommen wir haben nur zwei Texel nebeneinander, mit Farben \($\mathbf c_1$\), \($\mathbf c_2$\), und alpha-Werten \($\alpha_1$\) und \($\alpha_2$\). Wenn wir jetzt in der Mitte zwischen den beiden Texeln samplen, kriegen wir als interpoliertes Farb-Alpha-Tupel eben \($$(\mathbf c, \alpha)^{\mathrm T} = 0.5 \cdot (\mathbf c_1, \alpha_1)^{\mathrm T} + 0.5 \cdot (\mathbf c_2, \alpha_2)^{\mathrm T}$$\) heraus. Wenn der linke Texel schwarz ist, d.h. \($\mathbf c_1 = (0, 0, 0)^T$\), und der rechte Texel ziemlich grün, z.B. \($\mathbf c_2 = (0, 0.9, 0)^T$\), und unserem Beispiel entsprechend der linke Texel gar nicht sichtbar, d.h. \($\alpha_1 = 0$\), und der rechte Texel etwas sichtbar, z.B. \($\alpha_2 = 0.5$\), dann kriegen wir als interpolierten Farbwert an der Stelle: \($$(\mathbf c, \alpha)^{\mathrm T} = (0, 0.45, 0, 0.25)^{\mathrm T}$$\)Und das ist alles ohne Blending; denn so weit sind wir noch gar nicht. Wir haben nur einen interpolierten Farbwert aus der Textur gezogen, und dieser ist bereits zu dunkel.

Darum könnte man entweder ein 1-zu-1-Mapping zwischen Textur und Bildschirm fordern, und punktweise Filterung benutzen; oder eben bilineare Filterung benutzen, und einen 1-Pixel-Skirt bauen; oder eben das modifierte Sampling aus den obigen Slides verwenden. Oder halt vormultipliziertes Alpha.
Zuletzt geändert von eXile am 25.08.2013, 02:46, insgesamt 2-mal geändert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Wieso hältst du diesen Wert für zu dunkel? ;)
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

Weil wir gerne den Wert \($(\mathbf c, \alpha)^{\mathrm T} = (0, 0.9, 0, 0.25)^{\mathrm T}$\) hätten, denke ich.

Mmh, wenn man das vormultipliziert hätte man: \($(\mathbf c_1', \alpha_2') = (0, 0, 0, 0)^{\mathrm T}$\), \($(\mathbf c_2', \alpha_2') = (0, 0.45, 0, 0.5)^{\mathrm T}$\)

Nach Interpolation: \($(\mathbf c', \alpha') = (0, 0.225, 0, 0.25)^{\mathrm T}$\)

Und wieder nachmultipliziert: \($(\mathbf c, \alpha) = (0, 0.9, 0, 0.25)^{\mathrm T}$\)

Ich muss nur mal schauen, ob das das ist, was man will.
Zuletzt geändert von eXile am 25.08.2013, 02:46, insgesamt 3-mal geändert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Unsere Ausgangsfarbe war \($(\mathbf c^\prime, \alpha)^{\mathrm T} = (0, 0.9, 0, 0.5)^{\mathrm T}$\), das entspricht der un-premultiplied Farbe \($(\mathbf c, \alpha)^{\mathrm T} = (0, 1.8, 0, 0.5)^{\mathrm T}$\). Wir würden diese nun gerne 50:50 mit völligem schwarz mischen, unser gewünschtes Ergebnis lautet un-premultiplied also \($(\mathbf c_f, \alpha_f)^{\mathrm T} = (0, 0.9, 0, 0.25)^{\mathrm T}$\), das entspricht premultiplied \($(\mathbf c_f^\prime, \alpha_f)^{\mathrm T} = (0, 0.45, 0, 0.25)^{\mathrm T}$\). Und genau das ist das Wunder von premultiplied Alpha... ;)
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

dot hat geschrieben:Unsere Ausgangsfarbe war \($(\mathbf c, \alpha)^{\mathrm T} = (0, 0.9, 0, 0.5)^{\mathrm T}$\), das entspricht der un-premultiplied Farbe \($(\mathbf c, \alpha)^{\mathrm T} = (0, 1.8, 0, 0.5)^{\mathrm T}$\). Wir würden diese nun gerne 50:50 mit völligem schwarz mischen, unser gewünschtes Ergebnis lautet un-premultiplied also \($(\mathbf c, \alpha)^{\mathrm T} = (0, 0.9, 0, 0.25)^{\mathrm T}$\), das entspricht premultiplied \($(\mathbf c, \alpha)^{\mathrm T} = (0, 0.45, 0, 0.25)^{\mathrm T}$\).
Ja, das war mir auch vor drei Minuten wieder in den Sinn gekommen. D.h. der Threadersteller hat einfach die falschen Werte in der Textur, d.h. die sind nicht durch den alpha-Wert geteilt worden?
dot hat geschrieben:Und genau das ist das Wunder von premultiplied Alpha... ;)
Wie gut, dass es Wunder in diesen Sphären ja nicht gibt. ;)
Zuletzt geändert von eXile am 25.08.2013, 02:44, insgesamt 3-mal geändert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

eXile hat geschrieben:D.h. der Threadersteller hat einfach die falschen Werte in der Textur [...]
Vermutlich das oder er blendet falsch...
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

shadow hat geschrieben:Ich benutze:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
D.h. normales lineares Blending...um dein Problem zu lösen, lade die Daten in Form von premultiplied Alpha in die Textur (RGB multipliziert mit Alpha) und benutze glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Genaugenommen müsstest du auf das Gamma auch noch aufpassen, aber hoffen wir einfach mal, dass es so schon gut genug hinhaut... ;)
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Premultiplied alpha

Beitrag von eXile »

dot hat geschrieben:Genaugenommen müsstest du auf das Gamma auch noch aufpassen, aber hoffen wir einfach mal, dass es so schon gut genug hinhaut... ;)
Lustigerweise hatte ich genau das nämlich vorhin in Blender getestet, und man sah besonders am Schatten schon einen Unterschied. Aber wir brauchen das hier gar nicht: Der Threadersteller hat gesagt, es soll so wie in Gimp aussehen; und der Gimp blendet einfach die sRGB-Farbwerte zusammen. Ja das tut weh, ich weiß. Aber ich habe es nachgerechnet. Wenn man es richtig will, muss man halt Blender und darin Compositing-Nodes nehmen, denn der arbeitet im linearen (Vor-)Farbraum.

Er muss tatsächlich wohl einfach nur noch durch Alpha teilen, und die Blending-Funktion umstellen.

Und ich will jetzt nicht so popelig sein, dass das gar keine Gamma-Transformation ist, sondern eine sRGB-zu-linearem-Vorfarbraum-Transformation. ;) Das hatten wir ja alle schon mal hier (der Quark mit 2.2-Exponenten im Internet ist falsch, hält sich aber hartnäckig). Reader's Digest Version, falls sich der Threadersteller doch für eine Farbraum-korrekte Pipeline interessiert:
  1. Die Farbwerte (d.h. R-, G- und B-Kanäle, lass den Alpha in Ruhe!) mittels \($$\operatorname{f_1}(x)=\begin{cases}\frac{x}{12.92}, & x\le0.04045\\\left(\frac{x+0.055}{1.055}\right)^{2.4}, & x>0.04045\end{cases}$$\) transformieren.
  2. Die R-, G- und B-Kanäle durch Alpha teilen.
  3. Die R-, G- und B-Kanäle mittels \($$\operatorname{f_2}(x)=\begin{cases}12.92x, & x\le0.0031308\\(1+0.055)x^{1/2.4}-0.055, & x > 0.0031308\end{cases}$$\) zurücktransformieren.
  4. Die Textur mit Format GL_SRGB8_ALPHA8 erstellen und die Werte aus Schritt 3 reinladen
(Und natürlich das Blending, wie in dem vorherigen Post schon gesagt, umstellen.)

Ich habe jetzt (schon! ;)) auch mal den ganzen Thread durchgelesen, und ohne jetzt popelig² zu sein:
dot hat geschrieben:Gimbal Lock tritt mit Quaternions genauso auf. ;)
Beziehst du dich damit auf das hier?

(Und warum sind in meinem Uralt-Post alle Formeln verrutscht, aber mit einem Edit der nichts änderte ist alles wieder korrekt? Vermutlich eine Versionsänderung vom LaTeX-Formel-Layouter.)
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

eXile hat geschrieben:Blender sagt mir, dass da alles außen herum schwarz ist:

Bild
Falls das Bild der Datei entspricht, war beim Speichern die Optimierung aktiv, die Farbe voll transparenter Pixel wegzuschmeißen. Kenne ich von diversen PNG-Optimierungsprogrammen. Man sieht ja recht deutlich, dass die Deckkraft einen weichen verlauf hat, aber die Farbe einen harten. In diesem Fall würde ich erstmal diese Optimierung deaktivieren (und hoffen, dass die Originaldatei noch existiert).
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 »

Haha, das Problem waere laengst geloest, haettet man sich einfach nur an die allererste Antwort gehalten...
dot hat geschrieben:lade die Daten in Form von premultiplied Alpha in die Textur (RGB multipliziert mit Alpha) und benutze glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Bitte, hoert doch jetzt mal damit auf. Das aendert 0 am Ergebnis. Fuehrt die gleiche Rechnung aus.

Und das aus deinem unsinnigen Post alle Formeln verrutscht sind, ist ja wohl auch nicht weiter schlimm.

@Krishty: Nein, so sieht es nicht aus. Die Grafik die man hier aus Forum runterlaedt hat in volltransparanten Bereichen scheinbar den Wert 0x00ffffff statt gruen oder braun gespeichert. Im halbtransparenten Bereich sind ein paar sehr komische Farben wie rosa. Ziemlich wird sowohl beim Speichern und beim Laden irgendwas per Pixel rumgerechnet und fuehrt dann zu Fehlern beim Filtering.
Benutzeravatar
Krishty
Establishment
Beiträge: 8250
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von Krishty »

TGGC hat geschrieben:[viel Unsinn ignoriert]

@Krishty: Nein, so sieht es nicht aus. Die Grafik die man hier aus Forum runterlaedt hat in volltransparanten Bereichen scheinbar den Wert 0x00ffffff statt gruen oder braun gespeichert. Im halbtransparenten Bereich sind ein paar sehr komische Farben wie rosa. Ziemlich wird sowohl beim Speichern und beim Laden irgendwas per Pixel rumgerechnet und fuehrt dann zu Fehlern beim Filtering.
Ja stimmt. Shadow, womit lädst du die Grafiken? Kannst du uns sagen, welche Farbe die transparenten Pixel (z.B. der ganz links oben) nach dem Laden haben?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Das Laden der Texturen übernimmt eine Third-Party-Lib, von daher ist das eine kleine Black-Box. Damit war ich schon immer unzufrieden, vor allem weil die Lib jetzt nicht mehr maintained wird. Vielleicht schaff ich es, die Textur selbst in OpenGL zu laden. Dann hab ich mehr Kontrolle darüber und kann schauen welche Pixel welche Farbe haben.

Ich meld mich wieder!
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von dot »

Nimm einfach direkt libpng oder unter Windows z.B. WIC. ;)
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

Ich bin in Java unterwegs... *duck*

Hab ich das richtig verstanden: Beim rendern nimmt das bilineare filtering die Werte von dem umliegenden Pixeln, und wenn die Schwarz sind, dann gibts diese Ränder? Ich frage mich dann aber, wenn dieses "Falschverhalten" normal ist, dann ist des doch egal, welche Farbe in den transparenten Bereichen ist, oder? Mit weißen Pixeln hätte ich das selbe Problem... dann wird eben beim filtering mit weiß "gemischt". Ich verstehe nicht, warum hier nicht sofort auch der Alpha-Wert in die Berechnung mit einbezogen wrd... also warum nicht mit einem fast transparenten Pixel gemischt wird.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4260
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Premultiplied alpha

Beitrag von Chromanoid »

Probier's doch mal mit ImageIO?
http://stackoverflow.com/questions/1080 ... nd-strings
Wenn Du es damit hinbekommst, kannst Du wenigstens sicher sein, dass es an Deiner lib liegt.
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 »

shadow hat geschrieben:Hab ich das richtig verstanden: Beim rendern nimmt das bilineare filtering die Werte von dem umliegenden Pixeln, und wenn die Schwarz sind, dann gibts diese Ränder? Ich frage mich dann aber, wenn dieses "Falschverhalten" normal ist, dann ist des doch egal, welche Farbe in den transparenten Bereichen ist, oder? Mit weißen Pixeln hätte ich das selbe Problem... dann wird eben beim filtering mit weiß "gemischt".
Ja, wie ichs dir im zweiten Post dieses Threads schon geschrieben hab. Wenn du nicht mit weiss oder schwarz mischen willst, dann mach da halt die Farbe hin, mit der du mischen willst. Das klappt am besten, wenn du kein Premultiplied Alpha hast, da dann auch in transparenten Bereichen die Farbinformation komplett erhalten bleibt.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von CodingCat »

TGGC hat geschrieben: Wenn du nicht mit weiss oder schwarz mischen willst, dann mach da halt die Farbe hin, mit der du mischen willst. Das klappt am besten, wenn du kein Premultiplied Alpha hast, da dann auch in transparenten Bereichen die Farbinformation komplett erhalten bleibt.
Man könnte auch sagen, das klappt am besten mit Premultiplied Alpha, weil dann für volltransparente Pixel die Farbe tatsächlich egal ist: Premultiplication macht immer Schwarz daraus. ;)
Dafür verlierst du bei Premultiplied Alpha mit sinkendem Alpha natürlich linear Präzision bei der Farbe in transparenten Bereichen. Wenn du in deinen Texturen vorwiegend voll durchlässige und voll undurchlässige Pixel hast, spielt das keine Rolle. Dann sind Texturen in Premultiplied Alpha also insofern praktisch, als dass du dich um die Farbe in volltransparenten Bereichen tatsächlich nicht kümmern musst.

Ohne Premultiplication musst du wie von eXile erwähnt dafür sorgen, dass die Farbe in den transparenten Bereichen korrekt ist / mit der Farbe der benachbarten untransparenten Bereiche übereinstimmt. Liegt dort bedingt durch das Quellbildmaterial keine Farbinformation vor, musst du diese erst synthetisieren, z.B. mit dem erwähnten Push/Pull-Algorithmus oder einer entsprechenden Funktion des Bildprogramms deiner Wahl.

Da du hier offensichtlich in einer 2D-Umgebung arbeitest, können dir Themen wie Mip Mapping vermutlich egal sein. Dort wäre dann noch zu beachten, dass bei der Vorfilterung von Texturen ohne Premultiplication eine einfache Anwendung der Standardfilter auf die Farbkomponenten verglichen mit Supersampling beim Rendern keine 100% korrekten Ergebnisse liefert (wie falsch hängt wieder davon ab, welche Farben den transparenten Bereichen zugewiesen wurden). Für korrekte Ergebnisse müsste man hier in jedem Filterschritt zunächst in Premultiplied Alpha konvertieren, filtern, und anschließend mit einer Division wieder in den Werteraum ohne Premultiplication zurückkehren. Um dabei nicht die gewonnene Genauigkeit von getrennter Farbe/Alpha zu verlieren, würde man diese Berechnungen mit Gleitkommazahlen und hoher Genauigkeit, z.B. float oder double, durchführen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
shadow
Establishment
Beiträge: 147
Registriert: 26.02.2009, 14:04
Alter Benutzername: floyd
Wohnort: Nürnberg
Kontaktdaten:

Re: Premultiplied alpha

Beitrag von shadow »

@Chromanoid:

ImageIO nutze ich. An dieser Stelle hab ich noch Zugriff auf die geladenen Daten (siehe unten). Dann allerdings nutze ich diese Third-Party-Lib, die mir aus dem Java-Image eine OpenGL-Textur macht. Die könnte ich mit dem Link von Dir tatsächlich mal versuchen abzuschaffen. War eh der Plan auf lange Sicht.
TGGC hat geschrieben:Ja, wie ichs dir im zweiten Post dieses Threads schon geschrieben hab.
Sorry, da war ich noch nicht soweit...
TGGC hat geschrieben:Wenn du nicht mit weiss oder schwarz mischen willst, dann mach da halt die Farbe hin, mit der du mischen willst. Das klappt am besten, wenn du kein Premultiplied Alpha hast, da dann auch in transparenten Bereichen die Farbinformation komplett erhalten bleibt.
Das verteh ich grundsätzlich schon. Ich hab jetzt mein mit Java geladenes Image mal in opaque Farbinformation und Alpha-Kanal-Bild getrennt und abgespeichert. Folgendes Ergebnis:
544554_color.png
544554_color.png (6.1 KiB) 2957 mal betrachtet
544554_alpha.png
544554_alpha.png (3.06 KiB) 2957 mal betrachtet
Ich komm jetzt mal wieder mit meinem GIMP um die Ecke (sorry)... da hab ich nämlich das Farbbild als Ebene und das Alpha-Bild als Maske eingefügt -> perfektes Ergebnis ohne Ränder; sieht exakt so aus, wie das "normal" geladene PNG mit alpha drin.

Und da ich ja auch keinen Einfluss darauf habe, wie mir Inkscape das PNG exportiert, es sowohl in allen Image-Viewern korrekt dargestellt wird, als auch im GIMP (das normale PNG und auch Farbe und Alpha-Mask getrennt), bringt mich das zu der Frage *atmen* ..... Muss ich jetzt wirklich meine Bild-Datei nach dem Laden modifizieren, damit sie korrekt dargestellt wird. Ich kann mir irgendwie nicht vorstellen, dass das jeder Viewer oder GIMP macht.

Also wenns so ist dann glaub ich Euch das, aber irgendwie werd ich das Gefühl nicht los, ich überseh hier was... Vielleicht hat auch einfach nur meine Third-Party-Lib einen Schuss.
Antworten