粒子系统的性能

Rol*_*and 4 javafx particles

情况

我使用以下技术使用JavaFX创建了粒子系统:

每个粒子都是一个ImageView,其中包含一个具有径向渐变的Image:

在此处输入图片说明

粒子处理循环是一个AnimationTimer,其中粒子列表是通过列表的stream()。parallel()方法处理的,它实际上使整个系统得到了提升。像这样:

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();

    }
};
Run Code Online (Sandbox Code Playgroud)

粒子的颜色在其生命周期内通过ColorAdjust进行更改。我使用火色进行测试,其中包含1700个粒子:

在此处输入图片说明

我学到了什么:

  • 不使用parallel()较慢
  • 与透明结合使用Circle比使用ImageView慢得多
  • 使用混合模式非常慢
  • 使用PixelWriter更改图像颜色实在太慢了。问题出现了:ColorAdjust如何更改颜色(通过d3d和硬件)?我尚未在JavaFX源代码中找到该机制。

在性能方面,是否有更好的方法在JavaFX中实现粒子系统(其他Node类型,Thread等)?

如果有人想玩弄,我可以发布一些代码。

非常感谢您的专业知识!


编辑:由于被问到,您可以从此要点中获得完整的代码,该代码将节点用作带有色彩调整的粒子。顺便说一句,即使您预先渲染图像并且不使用色彩调节,性能仍然很低。

但是,这个问题更多是理论上的问题,因此没有必要深入研究代码。

Rol*_*and 5

我想我可以为自己的问题添加答案。但是我希望其他有更多经验的人可以分享他们的知识,因为我想出的只是玩弄的结果:

在Canvas上绘画而不是使用JavaFX ImageView节点令人惊讶地导致速度提高至少10倍。这基本上就是我所做的:

  • 用梯度预先计算图像,即取决于粒子的寿命,图像的颜色和大小
  • 在动画计时器中获取预先计算的图像并将其绘制在画布上

如果有人感兴趣,您可以从此摘要中获取完整的代码。只需单击“下载Zip”,然后将zip的代码放在JavaFX项目的“应用程序”包中,然后启动Main类。问题中代码的区别是在Particle.java类中。在问题中,将粒子用作节点并在动画计时器中移动,但是在此答案中,仅将数据用于在动画计时器中的画布上绘制图像,而节点本身并未放置在场景中。

您可以使用Settings类来指定分辨率,每帧新粒子的数量等。

此屏幕快照以60fps的速度以全高清分辨率在屏幕上显示了3个排斥器和25400个粒子:

在此处输入图片说明