0
votes

I created a particle system that draws a number of primitives and adds a texture to them. The source sprite is a PNG image with transparency, but when I draw it in XNA using the below code, the transparent areas are replaced with black. How can I preserve this transparency?

effect.View = camera.View;
effect.Projection = camera.Projection;
effect.World = Matrix.CreateBillboard(pos, camera.Pos, camera.Up, camera.Dir);
effect.Texture = texture;


foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
    pass.Apply();
    g.DrawUserPrimitives(PrimitiveType.TriangleStrip, verts, 0, 2);
}

Here is the code where I set up the vertices:

float s = 0.25f; ; // initial size of a particle

verts[0].Position = new Vector3(-s, -s, 0);
verts[1].Position = new Vector3(+s, -s, 0);
verts[2].Position = new Vector3(-s, +s, 0);
verts[3].Position = new Vector3(+s, +s, 0);

verts[0].TextureCoordinate = new Vector2(0, 0);
verts[1].TextureCoordinate = new Vector2(1, 0);
verts[2].TextureCoordinate = new Vector2(0, 1);
verts[3].TextureCoordinate = new Vector2(1, 1);

verts[0].Color = Color.White;
verts[1].Color = Color.White;
verts[2].Color = Color.White;
verts[3].Color = Color.White;

Hope someone can help me with this. Thanks.


EDIT: Code for loading image::

smokeParticle = Content.Load<Texture2D>("particle_smoke");
1

1 Answers

0
votes

Are you sure, that the texture image is loaded correctly? You did not post the code where you load the image, so I can only speculate. But in my experience, loading images can often go wrong, and there may be some unwanted conversions taking place in the loading API.

You could use the debugger, and see if texture has a pixel type that supports transparency. If not, you can be sure, that the error is during your loading code (assuming that your PNG has transparency).

[EDIT]

Blend State would have been my second guess. Good that you found that on your own.

To your second question: alpha-blending requires objects to be drawn back to front in order to look correct, so you would have to do some spatial sorting before rendering.

But if you only have full/no opacity you can skip the sorting, as it will always look correct. But then you have to take care, that the fully transparent parts don't overwrite the z-buffer, and hide particles behind them that are rendered at a later point.

Here is a nice article on the different options. It is written in C for openGL, but I'm sure you can translate that to C#/XNA.