5
\$\begingroup\$

I've got an XNA game which essentially has "floating combat text": short-lived messages that display for a fraction of a second and then disappear.

I've recently added a gradual "fade-away" effect, like so:

 public void Update()
        {
            color.A -= 10;
            position.X += 3;
            if (color.A <= 10) isDead = true;
        }

Where color is the Color int the message displays as. This works as expected, however, it fades the messages to white, which is very noticeable on my indigo background.

Is there some way to fade it to transparent, rather than white? Lerp-ing towards the background color isn't an option, as there's a possibility there will be something between the text and the background, which would simply be the inverse of the current problem.

\$\endgroup\$
  • \$\begingroup\$ Have you tried lerping to Color.Transparent (which is in the Color lib for XNA) and just gradually change the interpolation rate? \$\endgroup\$ – AndrewAchilles Apr 13 '12 at 6:00
  • \$\begingroup\$ @tigersnack I... didn't know there was such a thing. I'll have to try it in the morning. \$\endgroup\$ – Raven Dreamer Apr 13 '12 at 6:02
6
\$\begingroup\$

If you work with premultiplied alpha, the default behaviour, you have to multiply the alpha....

public void Update()
{
      color*= 0.95f;
      position.X += 3;
      if (color.A <= 10) isDead = true;
}

The difference here is you're modifying the color, i.e. all values simultaneously and uniformly, rather than just the alpha value.

\$\endgroup\$
  • \$\begingroup\$ this is right... I'm not changing only the alpha, I'm changing the color, when you multiply color(255,255,255,255) by 0.5f, you get color(128,128,128,128), if you continue doing it you will get Color(0,0,0,0) ... that is what is expected when you are working with premultiplied alpha, and it is the default behaviuour in xna 4.0 \$\endgroup\$ – Blau Apr 13 '12 at 9:58
  • \$\begingroup\$ the reference is that code... color*=0.95f... it works... is easy to check... \$\endgroup\$ – Blau Apr 13 '12 at 9:59
  • \$\begingroup\$ I checked. You're right! I didn't notice that you were altering the entire color, not just the alpha channel. I also edited your post so I could reverse my vote. Thanks, I've learned something today. :) \$\endgroup\$ – doppelgreener Apr 13 '12 at 10:02
  • \$\begingroup\$ by the way is the expected way of working with xna 4.0, you should use it... here is the explanation blogs.msdn.com/b/shawnhar/archive/2009/11/06/… \$\endgroup\$ – Blau Apr 13 '12 at 10:05
9
\$\begingroup\$

You're doing exactly what you should do - changing the alpha channel of the color you use when drawing the sprite. That isn't where the problem lies.

The problem is that if you just use the default SpriteBatch.Begin() behaviour, your sprite blends to its color (normally: white) rather than blending to actual transparency. What you need to do is set your BlendState to BlendState.NonPremultiplied, then everything will be fine.

SpriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.NonPremultiplied)

Blau's answer provides a different method (the premultiplied one) which apparently has a few advantages over this one.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.