Comment faire correctement la transparence alpha dans XNA 4.0?

14

D'accord, j'ai lu plusieurs articles, tutoriels et questions à ce sujet. La plupart indiquent la même technique qui ne résout pas mon problème. J'ai besoin de pouvoir créer des sprites semi-transparents (vraiment des texture2D) et les faire superposer à un autre sprite.

Je peux y arriver quelque peu avec les exemples de code que j'ai trouvés mais je ne suis pas satisfait des résultats et je sais qu'il existe un moyen de le faire. En programmation mobile (BREW), nous l'avons fait à l'ancienne et avons vérifié la transparence de chaque pixel avant le rendu.

Dans ce cas, il semble que le sprite en dessous se mélange avec l'alpha au-dessus. Cela peut être un artefact de la façon dont je rend la texture mais, comme je l'ai déjà dit, tous les exemples pointent vers cette technique. Avant d'aller plus loin, je vais continuer et coller mon exemple de code.

    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();

    }

Comme vous pouvez le voir, dans ce code, j'utilise la méthode SpriteBatch.Begin surchargée qui prend, entre autres, un état de fusion. Je suis presque certain que c'est mon problème. Je ne veux pas MÉLANGER les sprites, je veux qu'ils soient transparents lorsque alpha est 0. Dans cet exemple, je peux mettre alpha à 0 mais cela rend toujours les deux tuiles, avec le sprite ordonné en z inférieur, décoloré à cause de la mélange. Ce n'est pas un effet souhaité, je veux que le sprite d'ordre z supérieur disparaisse et n'affecte pas la couleur en dessous de cette manière.

Je suis peut-être loin d'ici car je suis relativement nouveau dans le développement XNA, alors n'hésitez pas à me diriger dans la bonne direction au cas où je descendrais dans le mauvais terrier de lapin.

TIA

Soshimo
la source
Pourquoi est-ce un «bon» alpha? Il y a un support alpha et aucun support alpha, non?
The Communist Duck
Vous devriez être en mesure de modifier le titre en appuyant sur «Modifier», puis le titre devrait être en haut. Sauf si quelque chose a changé.
The Communist Duck

Réponses:

18

Si je suis le problème correctement, essayez d'appeler Begin avec BlendState.NonPremultiplied. Cet article peut également aider à faire la lumière sur le fonctionnement du mélange alpha dans XNA:

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
la source
Oui, il semble que le NonPremultiplied va faire l'affaire (au moins selon le lien que vous avez publié). Je vais attendre et voir si ça marche quand je rentre ce soir avant d'accepter, mais il semble que c'est la réponse. Merci!
Soshimo
c'était l'astuce. Je ne savais pas qu'ils avaient changé cela en 4.0. Cet article que vous avez lié était très illustratif. Je vous remercie.
Soshimo
1
+1 Merci! Je regardais simplement en ligne pour essayer de comprendre pourquoi l'alpha ne fonctionnait que partiellement. Cela l'a résolu. Les termes que j'utilisais sur Google étaient Spritebatch Opacity, j'espère que ces termes aideront désormais les lunettes à trouver cette réponse.
AttackingHobo
6

Entièrement d'accord avec la réponse d'Alex, bien que si vous vous en tenez à l'alpha prémultiplié, je crois que vous pouvez également le faire de cette façon

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

Shawn a également publié un article expliquant la différence entre l'alpha prémultiplié et non multiplié - http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

earok
la source