Situation
I created a particle system with JavaFX using the following technique:
Each particle is an ImageView which contains an Image with a radial gradient:
The particle handling loop is an AnimationTimer in which the list of particles is handled via the list's stream().parallel() method, it actually gives the whole system a boost. Something like this:
loop = new AnimationTimer() {
@Override
public void handle(long now) {
addParticle();
// apply force: gravity
allParticles.stream().parallel().forEach(Particle::applyForceGravity);
// move particle
allParticles.stream().parallel().forEach(Particle::move);
// update position in fx scene
allParticles.forEach(Particle::display);
// remove all particles that aren't visible anymore
removeDeadParticles();
}
};
The particle's color changes via ColorAdjust during its lifecycle. I used fire colors for testing, something like this which contains 1700 particles:
What I've learned:
Question
Is there a better way to implement a particle system in JavaFX (other Node types, Thread, etc) in regards to performance?
I can post some code if anyone wants to toy around.
Thank you very much for the expertise!
Edit: Since it was asked, you can get the full code which uses nodes as particles with coloradjust from this gist. Btw, even if you pre-render the images and don't use coloradjust, the performance is low.
However, the question is more of a theoretical kind, so digging through the code isn't really necessary.
I think I can add an answer to my own question. But I hope someone else with more experience can share their knowledge, because what I came up with was just the result of toying around:
Painting on a Canvas instead of using JavaFX ImageView nodes surprisingly resulted in a factor of at least 10x speed increase. This is basically what I did:
If anyone is interested, you can get the full code from this gist. Just click "Download Zip" and put the code of the zip in an "application" package of a JavaFX project and start the Main class. The difference to the code in the question is in the Particle.java class. In the question the particles are used as nodes and moved in the animation timer, but in this answer only the data is used for drawing an image on a canvas in the animation timer, the node itself isn't put on the scene.
You can use the Settings class in order to specify resolution, number of new particles per frame, etc.
This screenshot shows 3 repellers and 25400 particles on the screen in Full-HD resolution, running at 60fps:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With