Как правильно сделать альфа-прозрачность в XNA 4.0?

14

Хорошо, я прочитал несколько статей, учебных пособий и вопросов по этому поводу. Большинство указывают на ту же технику, которая не решает мою проблему. Мне нужна возможность создавать полупрозрачные спрайты (на самом деле texture2D), чтобы они перекрывали другой спрайт.

Я могу добиться этого с помощью примеров кода, которые я нашел, но я не удовлетворен результатами и знаю, что есть способ сделать это. В мобильном программировании (BREW) мы делали это по старой программе и проверяли прозрачность каждого пикселя перед рендерингом.

В этом случае кажется, что спрайт под ним смешивается с альфа над ним. Это может быть артефактом рендеринга текстуры, но, как я уже говорил, все примеры указывают на этот метод. Прежде чем идти дальше, я вставлю свой пример кода.

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

    }

Как вы можете видеть, в этом коде я использую перегруженный метод SpriteBatch.Begin, который принимает, среди прочего, состояние смешивания. Я почти уверен, что это моя проблема. Я не хочу БЛИЗКАТЬ спрайтов, я хочу, чтобы они были прозрачными, когда альфа равен 0. В этом примере я могу установить альфа на 0, но он по-прежнему рендерит обе плитки, причем более низкий упорядоченный спрайт z показывает сквозной, обесцвеченный из-за смешивания. Это нежелательный эффект, я хочу, чтобы высший z-упорядоченный спрайт исчезал и не влиял на цвет под ним таким образом.

Я могу быть далеко отсюда, так как я довольно новичок в разработке XNA, поэтому не стесняйтесь направлять меня в правильном направлении, если я спущусь не по той кроличьей норе.

ТИА

Soshimo
источник
Почему это «правильная» альфа? Есть альфа-поддержка, и нет альфа-поддержки, верно?
Коммунистическая утка
Вы должны иметь возможность редактировать заголовок, нажав «изменить», и тогда заголовок должен быть вверху. Если что-то не изменилось.
Коммунистическая утка

Ответы:

18

Если я правильно понимаю проблему, попробуйте вызвать Begin с BlendState.NonPremultiplied. Эта статья может также помочь пролить свет на то, как альфа-смешение работает в 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

Алекс Шеарер
источник
Да, похоже, что NonPremultiplied сделает свое дело (по крайней мере, по ссылке, которую вы разместили). Я подожду и посмотрю, сработает ли это, когда я вернусь домой сегодня вечером, прежде чем принять, но похоже, что это ответ. Благодарность!
Сосимо
это был трюк. Я не знал, что они изменили это в 4.0. Та статья, на которую вы ссылались, была очень показательной. Спасибо.
Сошимо
1
+1 Спасибо! Я просто смотрел онлайн, пытаясь понять, почему альфа работает только частично. Это решило это. Термины, которые я использовал в Google, были Spritebatch Opacity, надеюсь, теперь эти термины помогут гуглерам найти этот ответ.
AttackingHobo
6

Полностью согласен с ответом Алекса, хотя, если вы придерживаетесь предварительно умноженной альфы, я думаю, вы могли бы сделать это и так

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

Шон также сделал пост, объясняющий разницу между предварительно умноженной и немноженной альфа-версией - http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

earok
источник