[FIXED] Warum bekomme ich schwarze Umrisse/Kanten an einer Textur in libgdx?

Ausgabe

Immer wenn ich eine Textur zeichne, die Alpha an den Rändern hat (sie wird von Photoshop geglättet), werden diese Ränder dunkel. Ich habe endlos mit Texturfiltern und Mischmodi herumgespielt, hatte aber keinen Erfolg.

Hier ist, was ich meine:

minFilter: Linear magFilter: Linear

Kreis auf gelbem Hintergrund
Roter Hintergrund

minFilter: MipMapLinearNearest magFilter: Linear

Geben Sie hier die Bildbeschreibung ein
Geben Sie hier die Bildbeschreibung ein

minFilter: MipMapLinearLinear magFilter: Linear

Geben Sie hier die Bildbeschreibung ein
Geben Sie hier die Bildbeschreibung ein

Wie Sie sehen können, macht das Ändern des Filters im libGDX Texture Packer einen großen Unterschied im Aussehen, aber Alphas sind immer noch dunkel .

Ich habe versucht, den Texturfilter in libgdx manuell einzustellen mit:

texture.setFilter(minFilter, magFilter);

Aber das geht nicht.

Ich habe gelesen, dass das Herunterskalieren mit einem linearen Filter dazu führt, dass die Alpha-Pixel standardmäßig schwarz sind? Wenn dies der Fall ist, wie kann ich es vermeiden?

Ich habe auch versucht, den Mischmodus zu ändern: glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_APHA)macht keinen Unterschied. glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)entfernt Alpha vollständig, so dass das nicht funktioniert.

Ich möchte mein nicht auf setzen minFilter, Nearestweil es die Dinge schrecklich pixelig aussehen lässt. Ich habe jede andere Kombination von Texturfiltern ausprobiert, aber alles führt zu demselben Effekt mit schwarzen/dunklen Kanten/Konturen.

Lösung

Ich habe gelesen, dass das Herunterskalieren mit einem linearen Filter dazu führt, dass die Alpha-Pixel standardmäßig schwarz sind?

Dies ist nicht unbedingt wahr; es hängt davon ab, welche Farbe Photoshop in die vollständig transparenten Pixel eingefügt hat. Anscheinend ist dies in Ihrem Fall schwarz.

Das Problem tritt auf, weil die GPU zwischen zwei benachbarten Pixeln interpoliert, von denen eines vollständig transparent ist (wobei alle Farbkanäle ebenfalls auf Null gesetzt sind). Nehmen wir an, das andere Pixel ist hellrot:

(255,   0,   0, 255)  // Bright red, fully opaque
(  0,   0,   0,   0)  // Black, fully transparent

Interpolation mit einem Verhältnis von 50/50 ergibt:

(128,   0,   0, 128)

This is a half-opaque dark red pixel, which explains the dark fringes you’re seeing.

There are two possible solutions.

1. Add bleeds to transparent regions

Make sure that the fully transparent pixels have the right colour assigned to them; essentially “bleed” the colour from the nearest non-transparent pixel into adjacent fully transparent pixels. I’m not sure Photoshop can do this, but the libGDX TexturePacker can; see the bleed and bleedIterations settings. You need to be careful to set bleedIterations high enough, and add enough padding for the bleed to expand into, for your particular level of downscaling.

Now the example comes out like this:

(255,   0,   0, 255)
(255,   0,   0,   0)  // Red bled into the transparent region

Interpolation now gives a bright red transparent pixel, as desired:

(255,   0,   0, 128)

2. Use premultiplied alpha

This is less finicky to get right, but it helps to know exactly what you’re doing. Again TexturePacker has you covered, with the premultipliedAlpha setting. This is OpenGL blend mode glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).

The numbers in the example don’t change; this is still the pixel that comes out:

(128,   0,   0, 128)

However, this is no longer interpreted as “half-transparent dark red”, but rather as “add some red, and remove some background”. More generally, with premultiplied alpha, the colour channels are not “which colour to blend in” but “how much colour to add”.

Beachten Sie, dass ein Pixel wie (255, 0, 0, 0)in der Quelltextur nicht mehr existieren kann: Da das Alpha vormultipliziert ist, bedeutet ein Alpha von Null automatisch, dass alle Farbkanäle ebenfalls Null sein müssen. (Wenn Sie wirklich schick werden möchten, können Sie solche Pixel sogar verwenden, um additives Mischen im selben Renderdurchlauf und dieselbe Textur wie beim normalen Mischen anzuwenden!)

Weiterführende Literatur zum vormultiplizierten Alpha:


Beantwortet von –
Thomas


Antwort geprüft von –
Marilyn (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like