Smoke Simulations in Rust using Bevy
- HariharanI recently came across an excellent book by Daniel Shiffman called Nature of Code where he discusses the mathematics and code behind simulating natural phenomena. There is this one particular chapter about Particle Systems that intrigued me where he introduces a very compelling smoke simulation using a very basic physics engine and some particles, all written from scratch! I knew I had to give it a try.
I have been experimenting with Rust lately and this felt like a perfect project to oxidize some iron. There are some interesting game engines written in Rust with even Godot having support for Rust but I wanted something simple yet not too abstract and I felt like Bevy checked those boxes.
Bevy is a shiny new game engine that is still under active development where breaking API changes are not uncommon. There is a thriving community behind the engine but the documentation is still a work in progress. Although, Bevy does have an official guide that helps you get started. You can check out awesome-bevy for some more resources if you are interested.
Bevy is built around ECS (Entity Component System). You define entities, attach components to them which are affected by systems. To produce the smoke effect, the first step was to create the particles. So I created a system called spawn_things
which creates a new particle every 10ms.
The timer here is a resource in Bevy and resources are used to represent globally unique data. The performance of this block can be further improved by moving the texture_handle into a resource but I was already getting a decent framerate so I didn’t bother.
To get the fuzzy appearance, each particle is essentially a sprite with a texture that has a transparent background which produces a really cool blend effect when the particles overlap.
The Lifetime
component is used to adjust the fading effect.
The kill_particles
system decreases the lifetime and the particles' alpha value every frame which produces the fading effect.
To update the position, in each frame, for all particles, we add acceleration to the velocity and velocity to the position. That’s the physics loop, as simple as that!
The intensity of the smoke can be adjusted by adjusting the timer in CreateTimer
. You can also add wind effects by adjusting the Acceleration
.
The entire code can be found here. Feel free to experiment and create new effects for fire and smoke. Cheers!