Sign in to follow this  

[C#,MDX]Particle blending not working correctly[solved]

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have these classes: ParticleManager ParticleSystem Particle My ParticleSystem consists of an arraylist storing Particle objects and a vertex buffer that stores vertices of type CustomVertex.PositionColoredTextured . I use point sprites. blending is done as such:
	d3dDevice.RenderState.PointSpriteEnable = true;
			d3dDevice.RenderState.PointScaleEnable = false;
			d3dDevice.RenderState.PointSize = 10.0f;

			d3dDevice.RenderState.SourceBlend = Blend.SourceAlpha;
			d3dDevice.RenderState.DestinationBlend = Blend.One;
			d3dDevice.RenderState.AlphaBlendEnable = true;
			
		

			d3dDevice.SetTexture(0,tex);
			d3dDevice.SetStreamSource(0,particleVB,0);
			d3dDevice.VertexFormat = CustomVertex.PositionColoredTextured.Format;
			d3dDevice.DrawPrimitives(PrimitiveType.PointList,0,particleAmount);

			d3dDevice.RenderState.AlphaBlendEnable = false;
			d3dDevice.RenderState.PointSpriteEnable = false;

and whether I set the alpha color component in each vertex to 0 or 255, it makes no difference. Is this the right way to do blending? There must be something wrong since the alpha component of each vertex isnt being taken into account. [Edited by - deathtrap on January 10, 2006 6:51:44 PM]

Share this post


Link to post
Share on other sites
Looking at the blending equation, which is.
OutputPixel = SourcePixel * SourceBlendFactor + DestPixel * DestBlendFactor
SourcePixel : Pixel currently being computed
DestPixel : Pixel in the backbuffer
SourceBlendFactor : A value in the range 0 and 1 that specifies the percent of the source pixel to use in the blend
DestBlendFactor : A value in the range 0 and 1 that specifies the percent of the destination pixel to use in the blend

Have you tried setting the render states to

//Take the alpha component from the source
Device.RenderState.SourceBlend = Blend.SourceAlpha;
//Then we specify that the destination blend factor is one minus the source blend
//factor
Device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
//Enable alpha blending
Device.RenderState.AlphaBlendEnable = true;




I hope this helps.
take care.

Share this post


Link to post
Share on other sites
Nope, gives totally undesired output.

let me describe the problem a bit better.
Each particle has a color, which has 4 components(Alpha,R,G,B).
What I want is for the particle to slowly fade out by lowering the Alpha component. However, no matter what I set the Alpha component to, the particle remains at the same visibility, and when it gets to the end of its life, it 'pops' back to its start location instead of fading out.

Share this post


Link to post
Share on other sites
Well, it seems you have two seperate problems then, both of which are not apparent in the code you posted. Firstly, how do you alter the alpha color component of the particle? If you are using the diffuse color of the vertices, you might want to check out what DrunkenHyena has to say in this thread (halfway down the page). He shows how to set up the render states to modulate the texture and vertex diffuse color, which I guess isn't happening in your code and causing the lack of blending.

As for the particles popping back to the original location, this is a problem that is most likely caused by your code, so all we can do is guess. I'll give it a shot and guess that your code resets the 'used' particles once their lifetime is over. Because they're not fading out correctly, this effect is noticable, while it should go unnoticed when the particles are invisible, ie faded out correctly. Any further guesses would have me make too many assumptions on how your code works, so I'll refrain from that :)

If you could post some more code on how you update the alpha values and particle positions, we might be able to offer some more informed suggestions on how to fix it.

Share this post


Link to post
Share on other sites
Thanks.

Popping back was not a problem, sorry if I made it seem like one. What I meant was that when the particle is at the end of its life, it is still being rendered with max alpha, meaning full visibility and then it is reset back to its start position which makes it pop. What I wanted was for the particle to slowly fade out as it drew nearer to the end of its life, which I tried unsuccessfully to do using the alpha component of the vertex.

I will try the method suggested by drunkenhyena and post back.

Share this post


Link to post
Share on other sites
Awesome, got it to work.
Solved it by adding these lines:
d3dDevice.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
d3dDevice.TextureState[0].AlphaArgument1 = TextureArgument.Diffuse;
d3dDevice.TextureState[0].AlphaArgument2 = TextureArgument.TextureColor; //ignored

However, one thing perplexes me, when I use the following:
d3dDevice.RenderState.SourceBlend = Blend.SourceAlpha;
d3dDevice.RenderState.DestinationBlend = Blend.InvSrcAlpha;
d3dDevice.RenderState.BlendOperation = BlendOperation.Add;
It makes it appear as if theres no blending being performed, just a completely opaque textured quad appears.

but when I use:
d3dDevice.RenderState.SourceBlend = Blend.SourceAlpha;
d3dDevice.RenderState.DestinationBlend = Blend.One;
d3dDevice.RenderState.BlendOperation = BlendOperation.Add;

Everything works fine. yet DrunkenHyena says the first method is correct, i'm confused.

Share this post


Link to post
Share on other sites
Good to see it worked out and thanks for posting back the solution!

As for your confusion on the blend factors, I'm afraid I can only say I share it :) I've checked out what Toymaker and MSDN had to say, but I can only conclude that the src/invSrc should give the correct results...

With the src/invSrc states, you'd get:

source colour * source alpha + destination colour * (1 - source alpha)

And with the src/one states you'd get:

source colour * source alpha + destination colour


So basically the src/invSrc should indeed be what you want, but if it isn't working for you I'm a bit stumped too. The only thing I can think off is that either the inverse source blend somehow isn't computed correctly due to the alpha operation you changed, but that's just plain guessing and I can't really imagine DX doesn't take this into account.

Another guess would be that you somehow exceed the range of 0-255 for the alpha component of the particles somewhere. It's a bit of a long shot, but I had this problem with a particle system of my own and it produced incorrect blendings no matter what I set for the states.

Hope this somehow helps and that someone more knowledgeable than me can help us out :)

Share this post


Link to post
Share on other sites

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this