12,895,774 members (42,437 online)
Technical Blog
Add your own
alternative version

#### Stats

6.4K views
1 bookmarked
Posted 23 Jul 2012

# Creating a smoke using Particle System in Silverlight

, 30 Apr 2013 CPOL
 Rate this:
Please Sign up or sign in to vote.
A look into creating smoke effect in Silverlight using the concept of Particle System.

Here’s what we’re trying to achieve: demo

One of a fellow programmer came up with a question of “How do you create Smoke effect using Silverlight?” Well there may be plenty of code, third-party tools and plug-ins strewn over the internet for this, but out of a professional curiosity I got into the business of creating one out of my own hands.

The whole concept of creating smoke (without fire ) can be done through what they call as Particle System. It’s a technique where in you employ very small graphical objects in large numbers to simulate effects like say Smoke, Fire, Snow, Dust, etc…

We need the smoke to be moving freely, so a canvas would be a best bet for the layout.

```<Canvas x:Name="myCanvas" Background="White">
</Canvas>```

From this point on the rest of the Smoke effect would be programmed in code behind file (C-Sharp in my case)

Let’s think a minute about smoke, shall we? Smoke starts at a point, very concentrated (Generation Point). According to the complex laws of physics, it simply rises up becoming dilute all the way. Finally blending well with the air where it seems to disappear (Vanishing Point).

Understanding the dynamics of smoke

Our approach would be to consider smoke as made up of small particles, which would originate at the Generation Point. These particles as time passes would simply rise up, becoming transparent by smaller percentages as it goes and finally becoming invisible at the Vanishing Point.

These particles are going to be ellipses. Let’s have a method which does just that.

```public static Ellipse createEllipse()
{
Ellipse objEllipse = new Ellipse();
//Smaller sized particles
objEllipse.Width = 1;
objEllipse.Height = 1;

//Giving the particles a Smokey look
RadialGradientBrush rgbObj = new RadialGradientBrush();

GradientStop gsObj1 = new GradientStop();
gsObj1.Color = Colors.Transparent;
gsObj1.Offset = 2;
GradientStop gsObj2 = new GradientStop();
gsObj2.Color = Colors.DarkGray;
gsObj2.Offset = 0.5;
GradientStop gsObj3 = new GradientStop();
gsObj3.Color = Colors.Black;
gsObj3.Offset = 0.001;

rgbObj.GradientStops.Add(gsObj1);
rgbObj.GradientStops.Add(gsObj2);
rgbObj.GradientStops.Add(gsObj3);

objEllipse.Fill = rgbObj;

//Set the position of the ellipses to the Generation Point
Canvas.SetTop(objEllipse, 300);
Canvas.SetLeft(objEllipse, 150);
return objEllipse;
}```

While the Silverlight application initializes, we’d simply call the following line to add a new smoke particle:

`myCanvas.Children.Add(createEllipse());`

Well, this is just one particle. By every tick of the clock, new particles should be generated to give the effect of the smoke billowing. This calls for a DispatcherTimer instance which would give me an event for say every 2 millisecond.

```System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = new TimeSpan(2);
timer.Tick += timer_Tick;
timer.Start();```

At every tick, we need to be doing a set of tasks based on a few decisions.

Firstly, we cannot afford to overload the memory/screen with infinite number of particles. When a smoke particle simply disappears beyond the vanishing point, we can move them down to the generation point and reuse them. For this purpose, let’s have a limit of 1000 particles that can be freshly generated. If the screen has less than 1000 of them, we can go ahead and generate a new one.

```if (myCanvas.Children.Count < 1000){
generateFireParticles();
}```

Secondly, at every instant – *all* the smoke particles should perform the following tasks:

• Rise up
`Canvas.SetTop(item, Canvas.GetTop(item) - 1.25);`
• Grow and become lighter in visibility
```item.Opacity = item.Opacity - 0.009;
item.Width = item.Width + 0.075;
item.Height = item.Height + 0.075;```
• And take a wavy path up. Smoke particles take a simply chaotic path up, they just don’t go up in a straight line.
```Random randObj = new Random(10);
Canvas.SetLeft(item, Canvas.GetLeft(item) - (Math.Pow(-1, randObj.Next(5)) * randObj.Next(2)));```

Thirdly, Move every vanished particle back to its original point.

```if (item.Opacity < 0.0001){
item.Opacity = 1;
item.Width = item.Height = 1;
Canvas.SetTop(item, 150);
Canvas.SetLeft(item, 300);
}```

So, considering all above, my timer tick event would look like this:

```void timer_Tick(object sender, EventArgs e)
{
if (myCanvas.Children.Count < 1000)
{
generateFireParticles();
}
foreach (Ellipse item in myCanvas.Children)
{
if (item.Opacity < 0.0001)
{
item.Opacity = 1;
item.Width = item.Height = 1;
Canvas.SetTop(item, Y);
Canvas.SetLeft(item, X);
}
else
{
item.Opacity = item.Opacity - 0.009;
item.Width = item.Width + 0.075;
item.Height = item.Height + 0.075;
Canvas.SetTop(item, Canvas.GetTop(item) - 1.25);
Canvas.SetLeft(item, Canvas.GetLeft(item) - (Math.Pow(-1, randObj.Next(5)) * randObj.Next(2)));
}
}
}```

Thus, was how we can generate a smoke effect in Silverlight using Particle System. With a minor change in the color and nature of the ellipse, you can create Fire or other similiar effects.

Once again, visit this link to view the final Silverlight application: demo

Suggestions welcome from expert readers on alternate or even better ways!

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Technical Lead United States
Engineer.

 Pro

## Comments and Discussions

 -- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 30 Apr 2013
Article Copyright 2012 by Jyothikarthik_N
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid