Wie mache ich Alpha-Transparenz richtig in XNA 4.0?

14

Okay, ich habe einige Artikel, Tutorials und Fragen dazu gelesen. Die meisten verweisen auf dieselbe Technik, die mein Problem nicht löst. Ich brauche die Fähigkeit, halbtransparente Sprites zu erstellen (wirklich texture2D) und sie über ein anderes Sprite legen zu lassen.

Ich kann das mit den gefundenen Codebeispielen etwas erreichen, bin aber mit den Ergebnissen nicht zufrieden und weiß, dass es einen Weg gibt, dies zu tun. In der mobilen Programmierung (BREW) haben wir es nach alter Schule gemacht und tatsächlich jedes Pixel vor dem Rendern auf Transparenz überprüft.

In diesem Fall scheint das darunterliegende Sprite mit dem darüberliegenden Alpha gemischt zu werden. Dies mag ein Artefakt sein, wie ich die Textur rendere, aber wie ich bereits sagte, verweisen alle Beispiele auf diese eine Technik. Bevor ich weiter gehe, werde ich meinen Beispielcode einfügen.

    public void Draw(SpriteBatch batch, Camera camera, float alpha)
    {
        int tileMapWidth = Width;
        int tileMapHeight = Height;

        batch.Begin(SpriteSortMode.Texture,
            BlendState.AlphaBlend,
            SamplerState.PointWrap,
            DepthStencilState.Default,
            RasterizerState.CullNone,
            null, camera.TransformMatrix);

        for (int x = 0; x < tileMapWidth; x++)
        {
            for (int y = 0; y < tileMapHeight; y++)
            {
                int tileIndex = _map[y, x];

                if (tileIndex != -1)
                {
                    Texture2D texture = _tileTextures[tileIndex];

                    batch.Draw(
                        texture,
                        new Rectangle(
                            (x * Engine.TileWidth),
                            (y * Engine.TileHeight),
                            Engine.TileWidth,
                            Engine.TileHeight),
                        new Color(new Vector4(1f, 1f, 1f, alpha )));
                }
            }
        }

        batch.End();

    }

Wie Sie sehen, verwende ich in diesem Code die überladene SpriteBatch.Begin-Methode, die unter anderem einen Mischungsstatus annimmt. Ich bin mir fast sicher, dass das mein Problem ist. Ich möchte die Sprites nicht mischen, sondern transparent machen, wenn Alpha gleich 0 ist. In diesem Beispiel kann Alpha auf 0 gesetzt werden, aber es werden trotzdem beide Kacheln angezeigt, wobei das Sprite in der unteren z-Reihenfolge aufgrund von verfärbt ist mischen. Dies ist kein gewünschter Effekt. Ich möchte, dass das Sprite mit höherer Z-Ordnung ausgeblendet wird und die darunter liegende Farbe nicht auf diese Weise beeinflusst wird.

Ich bin hier möglicherweise weit entfernt, da ich noch ziemlich neu in der XNA-Entwicklung bin. Sie können mich also jederzeit in die richtige Richtung lenken, falls ich das falsche Kaninchenloch betrete.

TIA

Soshimo
quelle
Warum ist es "richtiges" Alpha? Es gibt Alpha-Unterstützung und keine Alpha-Unterstützung, oder?
Die kommunistische Ente
Sie sollten in der Lage sein, den Titel zu bearbeiten, indem Sie auf "Bearbeiten" klicken. Der Titel sollte sich dann oben befinden. Es sei denn, etwas hat sich geändert.
Die kommunistische Ente

Antworten:

18

Wenn ich das Problem richtig befolge, rufe Begin with BlendState.NonPremultiplied auf. Dieser Artikel soll auch Aufschluss darüber geben, wie Alpha-Blending in XNA funktioniert:

https://web.archive.org/web/20130208130323/http://blogs.msdn.com/b/shawnhar/archive/2010/04/08/premultiplied-alpha-in-xna-game-studio-4- 0.aspx

Alex Schearer
quelle
Ja, es sieht so aus, als würde der NonPremultiplied den Trick machen (zumindest gemäß dem von Ihnen geposteten Link). Ich werde abwarten, ob es funktioniert, wenn ich heute Abend nach Hause komme, bevor ich akzeptiere, aber es sieht so aus, als ob dies die Antwort ist. Vielen Dank!
Soshimo
das war der trick. Ich wusste nicht, dass sie das in 4.0 geändert haben. Der Artikel, den Sie verlinkt haben, war sehr anschaulich. Vielen Dank.
Soshimo
1
+1 Vielen Dank! Ich habe nur online gesucht, um herauszufinden, warum das Alpha nur teilweise funktioniert hat. Das hat es gelöst. Die Begriffe, die ich bei Google verwendet habe, waren Spritebatch Opacity. Hoffentlich helfen diese Begriffe den Gogglern jetzt, diese Antwort zu finden.
AttackingHobo
6

Stimmen Sie der Antwort von Alex voll und ganz zu, aber wenn Sie sich an das vormultiplizierte Alpha halten, können Sie es meiner Meinung nach auch auf diese Weise tun

new Color(new Vector4(alpha, alpha, alpha, alpha ))

Shawn hat auch einen Beitrag verfasst, in dem der Unterschied zwischen vormultipliziertem und nichtmultipliziertem Alpha erklärt wird - http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

earok
quelle