I've been reading the last few entries from Shawn's blog about premultiplied alpha and thought I'd got it all sussed. Now I'm trying to implement it in my game with a bit of additive blending for a particle system and have run in to a bit of a problem.
(I've used a content processor to pre-multiply the textures)
Premultiplied alpha is better than conventional blending for several reasons:
- It works properly when filtering alpha cutouts (see below)
- It works properly when doing image composition (stay tuned for my next post)
- It is a superset of both conventional and additive blending. If you set alpha to zero while RGB is non zero, you get an additive blend. This can be handy for particle systems that want to smoothly transition from additive glowing sparks to dark pieces of soot as the particles age.
That's the part I'm having trouble with.
When I set alpha to zero (e.g. 128, 32, 32, 0) my particle disappears.
Note:
(128, 0, 0, 128 to 255) does the alpha blending perfectly
(128, 0, 0, 1 to 127) does additive
So why when setting the alpha to 0 does the sprite disappear? I'm setting up the SpriteBatch as in Shawn's example.
| 1 | spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None); |
| 2 | this.GraphicsDevice.RenderState.SourceBlend = Blend.One; |
And here's the Premultiply code
| 1 | private void PremultiplyAlpha(BitmapContent source) |
| 2 | { |
| 3 | byte[] pixels = source.GetPixelData(); |
| 4 | |
| 5 | for(int i = 0; i < pixels.Length; i += 4) |
| 6 | { |
| 7 | pixels[i] = (byte)(pixels[i] * pixels[i + 3] / 255); |
| 8 | pixels[i + 1] = (byte)(pixels[i + 1] * pixels[i + 3] / 255); |
| 9 | pixels[i + 2] = (byte)(pixels[i + 2] * pixels[i + 3] / 255); |
| 10 | } |
| 11 | |
| 12 | source.SetPixelData(pixels); |
| 13 | } |
Any ideas?