Tuesday, 3 July 2012

3D PointSprite Particle Tutorial II

Now we have a simple particle and emitter we can have a look at other blending modes, in the previous tutorial we did what is called and additive blend, this type of blending is called Frame Buffer Alpha Blending and a full description of this can be found in your DirectX SDK documentation. Additive blending is just one of many types of alpha blending. In the Draw call of the emitter we set up the additive alpha blending by using these three values in the RenderState
game.GraphicsDevice.RenderState.AlphaBlendEnable = true;
game.GraphicsDevice.RenderState.SourceBlend = Blend.One;
game.GraphicsDevice.RenderState.DestinationBlend = Blend.One;

If you take a look at you DirectX documentation you will see the final pixel color is calculated like this

Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

Where ObjectColor will be our particle, SourceBlendFactor is our SourceBlend RenderState value, PixelColor is the color of the pixel before we draw our particles pixel and DestinationBlendFactor is our DestinationBlend RenderState value. so with both values set to One, the color is added to and so gives rise to the name additive blend. This is great for bright particle effects like sparks or I guess Lasers, where you have a high density of particles you get a brightening effect, but a bit crap if you want smoke and detail from the particle texture.

So how to keep this texture integrity is to use the following settings
game.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
game.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;

You will now be able to use the PointSpriteElemets AlphaValue to thin the particle. Also we will need a new particle texture as the one in the first tutorial has a black background but we want a nice transparent texture to be used with this blend mode, so I am going to use one I have created my self, it is a png file so we can have a transparent back ground.

So now we can also play with the alpha value in the PointSpriteElement structure. In the Update method of the project we add another line just after where we set the particle size so that we can have a faded tail. The 
Update method now looks like this
public override void Update(GameTime gameTime)
for (int p = 0; p < particleArray.Length; p++)
if (p == nextParticle && myLastpos != myPosition)
particleArray[p].Position = myLastpos;
particleArray[p].Color = particleColor;
particleArray[p].SpriteSize = 1 - (Vector3.Distance(particleArray[p].Position, targetPos) / 25);
particleArray[p].AlphaValue = 1 - (Vector3.Distance(particleArray[p].Position, targetPos) / 15);

if (nextParticle >= particleArray.Length)
nextParticle = 0;

myLastpos = targetPos;
targetPos = new Vector3((float)Math.Cos(gameTime.TotalGameTime.TotalSeconds) * 10, (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds) * 10, (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds));

Source for this tutorial can be found here.

No comments:

Post a Comment