Jak prawidłowo wykonywać przezroczystość alfa w XNA 4.0?

14

Okej, przeczytałem kilka artykułów, samouczków i pytań na ten temat. Większość wskazuje na tę samą technikę, która nie rozwiązuje mojego problemu. Potrzebuję zdolności do tworzenia półprzezroczystych duszków (naprawdę texture2D) i każę im nakładać inne duszki.

Mogę to nieco osiągnąć dzięki próbkom kodu, które znalazłem, ale nie jestem zadowolony z wyników i wiem, że jest na to sposób. W programowaniu mobilnym (BREW) zrobiliśmy to w starej szkole i sprawdziliśmy przezroczystość każdego piksela przed renderowaniem.

W tym przypadku wydaje się, że duszek pod nim jest mieszany z alfą nad nim. Może to być artefakt tego, w jaki sposób renderuję teksturę, ale, jak powiedziałem wcześniej, wszystkie przykłady wskazują na tę jedną technikę. Zanim przejdę dalej, wkleję mój przykładowy kod.

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

    }

Jak widać, w tym kodzie używam przeciążonej metody SpriteBatch.Begin, która przyjmuje między innymi stan mieszania. Jestem prawie pewien, że to mój problem. Nie chcę mieszać duszków, chcę, aby były przezroczyste, gdy alfa wynosi 0. W tym przykładzie mogę ustawić alfa na 0, ale nadal renderuje obie płytki, z pokazanym niższym duszka uporządkowanym z, przebarwionym z powodu mieszanie To nie jest pożądany efekt, chcę, aby duszek o wyższej kolejności z znikał i nie wpływał na kolor pod nim w taki sposób.

Mogę być tutaj daleko, ponieważ jestem całkiem nowy w rozwoju XNA, więc nie krępuj się poprowadzić mnie we właściwym kierunku, na wypadek, gdy pójdę do niewłaściwej króliczej nory.

TIA

Soshimo
źródło
Dlaczego jest to „właściwa” alfa? Istnieje obsługa alfa i brak obsługi alfa, prawda?
Kaczka komunistyczna
Powinieneś móc edytować tytuł, naciskając „edytuj”, a następnie tytuł powinien znajdować się na górze. Chyba, że ​​coś się zmieniło.
Kaczka komunistyczna

Odpowiedzi:

18

Jeśli problem zostanie rozwiązany poprawnie, spróbuj wywołać Begin with BlendState.NonPremultiplied. Ten artykuł może także rzucić nieco światła na działanie mieszania alfa w 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
źródło
Tak, wygląda na to, że NonPremultiplied wykona lewę (przynajmniej zgodnie z opublikowanym linkiem). Zanim to zaakceptuję, poczekam i zobaczę, czy to zadziała, kiedy wrócę do domu, ale wygląda na to, że to odpowiedź. Dzięki!
Soshimo,
to była sztuczka. Nie zdawałem sobie sprawy, że zmienili to w 4.0. Artykuł, który podłączyłeś, był bardzo ilustracyjny. Dziękuję Ci.
Soshimo,
1
+1 Dziękujemy! Właśnie szukałem w Internecie, próbując dowiedzieć się, dlaczego alfa działa tylko częściowo. To rozwiązało. Warunki, których użyłem w Google, to Spritebatch Opacity, mam nadzieję, że te warunki pomogą teraz goglerom znaleźć tę odpowiedź.
AttackingHobo
6

Całkowicie zgadzam się z odpowiedzią Alexa, choć myślę, że jeśli trzymasz się wstępnie pomnożonej alfa, myślę, że możesz to zrobić w ten sposób

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

Shawn napisał również post wyjaśniający różnicę między alfa wstępnie zmnożonej i nieprzemnożonej - http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

earok
źródło