Maybe the hardest feature to implement from the entire site was the Smoking menu effect. We’ve tried out a lot of ideas and I’m going to summarize some of them:

We thought to use a video as a background, but its performance was bad. Blending the video with the background was hard to do. Randomizing the smoke to make it more realistic would be almost impossible if using a video, as well.

After that we tried to make a Path that looks close to one knot from the smoke. We copied that path for example 50-100 times, randomized these paths in some manner and animated them to move like smoke. This idea was partly close to the effect, but still far away from a real smoke effect. And also hard to scale.

One very interesting approach that we found was to create a snapshot of real smoke. And then to use PixelShader effect to create the fluid movement of the smoke. This idea could be implemented but needs a lot of work, more than basic physics knowledge and the writing of lots of code in HLSL, which wasn’t that easy. Also it was not very clear if this was going to perform good enough (knowing that the whole site is moving and flying around).

Particle system. There are already some Silverlight smoke particle system realizations out there on the web. This was maybe the most obvious way of creating a smoke effect and also somehow easy to do, but the actual result was not very satisfying and didn't look like fluid smoke.

Here is a snapshot of the real look of the smoke.

Smoke effect in Action

We’ve decided to implement an idea that is very old and well-know in games development. A sprite animation is a predefined sequence of related images that looks like an animation/movement when changed in a fast way. In our example we change smoke frames on 20 frames per second. All image frames are around 100.

Implementation

There are a couple of different approaches to achieve sprite by using Silverlight. And one of the widespread implementations includes creating an Image control in Blend for every frame and after that creating a Key-Frame animation that hides the previous and shows the new one. Also you can create a big image that has all the frames and you can then clip this big image to show the current frame.

But we’ve implemented it in another way. We hold only one Image control and change its Source property on every frame. We’ll create a base class called ImageSequenceControl that will do most of our job. It’ll hook up the CompositionTarget.Rendering event and will change the frames accordingly.

In the constructor of this control we’ll pass a parameter - fps (frames per second). When having it we can calculate the interval between the frames.

protected ImageSequenceControl(int frames, double fps)

: this()

{

this.frames = frames;

averageInterval = TimeSpan.TicksPerSecond / fps;

}

And here is the CompositionTarget.Rendering handler.

//Raised before drawing of every frame.

privatevoid CompositionTarget_Rendering(object sender, EventArgs e)

{

long now = DateTime.Now.Ticks;

//Since we run on custom fps, we need to check if it's time to draw new frame.

if (now - lastTick < averageInterval)

return;

if (AutoReverse && now < pauseStart + pauseSec)

return;

//We've finished the frames and may start again.

if (frame == frames)

{

if (AutoReverse)

{

Randomise();

pauseStart = now;

}

frame = startFrame;

}

if (AutoReverse)

{

//Managing the opacity to make the effect of disapearing when reaching the last frames.

double ratio = (double)(frame - startFrame) / (frames - startFrame);

image.Opacity = .5 - 2 * (.5 - ratio) * (.5 - ratio);

}

//Show the next frame.

image.Source = images[frame - 1];

frame += 1;

lastTick = now;

}

The actual Image information (url sources) is implemented in the sub-classes like SmokeControl.

RE: Smoke effect

Re: Smoke effect

Very cool effect and it is great that you are willing to share it with the community like this. One questions I had was do you have any sample source code doing this in VB.NET? I'm a VB.NET user and I love to see tutorials in this language as opposed to C#. For example a tutorial like this one - that explains conditions in VB.NET is very helpful.

Re: Smoke effect

Thanks for sharing this. The smoke effect is very good, and very similar to how smoke moves in real life. Is it possible to change the way the smoke moves by increasing the number of frames per second? Or would it end up looking unnatural?