Bagaimana Saya Melakukan Transparansi Alpha dengan Benar di XNA 4.0?

14

Oke, saya sudah membaca beberapa artikel, tutorial, dan pertanyaan tentang ini. Kebanyakan menunjuk ke teknik yang sama yang tidak menyelesaikan masalah saya. Saya perlu kemampuan untuk membuat sprite semi-transparan (benar-benar tekstur2D) dan meminta mereka overlay sprite lain.

Saya dapat mencapainya dengan sampel kode yang saya temukan tetapi saya tidak puas dengan hasilnya dan saya tahu ada cara untuk melakukan ini. Dalam pemrograman seluler (BREW) kami melakukannya di sekolah lama dan benar-benar memeriksa setiap piksel untuk transparansi sebelum rendering.

Dalam hal ini tampaknya membuat sprite di bawahnya dicampur dengan alpha di atasnya. Ini mungkin artefak tentang bagaimana saya memberikan tekstur tetapi, seperti yang saya katakan sebelumnya, semua contoh menunjukkan teknik yang satu ini. Sebelum saya melangkah lebih jauh saya akan melanjutkan dan menempelkan kode contoh saya.

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

    }

Seperti yang Anda lihat, dalam kode ini saya menggunakan metode SpriteBatch.Begin kelebihan beban yang mengambil, antara lain, keadaan campuran. Saya hampir yakin itu masalah saya. Saya tidak ingin MENYAMPAIKAN sprite, saya ingin mereka transparan ketika alpha adalah 0. Dalam contoh ini saya dapat mengatur alpha menjadi 0 tetapi masih membuat kedua ubin, dengan z yang lebih rendah memerintahkan sprite muncul, berubah warna karena pencampuran. Ini bukan efek yang diinginkan, saya ingin sprite z-ordered lebih tinggi memudar dan tidak mempengaruhi warna di bawahnya sedemikian rupa.

Saya mungkin berada jauh di sini karena saya cukup baru dalam pengembangan XNA sehingga merasa bebas untuk mengarahkan saya ke arah yang benar jika saya turun ke lubang kelinci yang salah.

TIA

Soshimo
sumber
Mengapa itu 'tepat' alpha? Ada dukungan alpha, dan tidak ada dukungan alpha, kan?
Bebek Komunis
Anda harus dapat mengedit judul dengan menekan 'edit' dan kemudian judulnya harus di atas. Kecuali ada yang berubah.
Bebek Komunis

Jawaban:

18

Jika saya mengikuti masalah dengan benar, coba panggil Begin with BlendState.NonPremiplied. Artikel ini juga dapat membantu menjelaskan bagaimana alpha blending bekerja di 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
sumber
Yap, sepertinya NonPremultiplied akan melakukan trik (setidaknya sesuai dengan tautan yang Anda posting). Saya akan menunggu dan melihat apakah itu berfungsi ketika saya pulang malam sebelum menerima tetapi sepertinya ini adalah jawabannya. Terima kasih!
Soshimo
itulah triknya. Saya tidak menyadari mereka mengubahnya di 4.0. Artikel yang Anda tautkan sangat ilustratif. Terima kasih.
Soshimo
1
+1 Terima kasih! Saya hanya mencari online mencoba mencari tahu mengapa alfa hanya bekerja sebagian. Ini menyelesaikannya. Istilah yang saya gunakan di google adalah Spritebatch Opacity, semoga istilah itu sekarang akan membantu para goggler menemukan jawaban ini.
AttackingHobo
6

Sepenuhnya setuju dengan respons Alex, meskipun jika Anda tetap menggunakan alpha yang telah ditiru sebelumnya, saya yakin Anda juga bisa melakukannya dengan cara ini

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

Shawn juga melakukan posting yang menjelaskan perbedaan antara alfa yang dipultipultasikan dan yang tidak dikalikan - http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

earok
sumber