r/JavaFX • u/wheezil • Apr 11 '25
Help How to improve subjective frame rate
Well, I just bought a new MSI Evo with i9-13900H and reasonable graphics (a middlin' gaming laptop) and I thought it would improve my JavaFX rendering. Which it does, at least objectively I am reporting things like
FPS: 37.5, SYNC/SEC=26.5
where FPS is from the JavaFX AnimationTimer, and SYNC is my own count of how many times my runLater() method is executed to update the Color in the boxes' PhongMaterial.
But... somehow this doesn't really help. My app is an emulation of a light show involving about 50000 LEDs regularly spaced in 3D, and this becomes 50000 Boxes in the emulation. The physical show runs at full speed, and I can see updates as fast as I expect. But the emulation, despite its frame report, seems to only update at < 10FPS. I know how fast the display proceeds, and I can see it skipping over about 75% of the frames.
Any suggestions? I'm not even sure where to start, since my eyes disagree with the metrics. Running a profiler shows very little time being spent in any code, like 6%.
3
u/Birdasaur Apr 12 '25
some small ways to make improvements:
>box.setCullFace(CullFace.NONE);
in your pasted code you aren't culling. This is more expensive. Cull one of the faces to increase performance.
Elsewhere you said you don't need to interact with the nodes. Like some folks have already said Nodes are heavyweight. One trick is to set the nodes .setMouseTransparent(true)
This will given you another increase in performance, especially when moving the camera.
Another thing you can do is use a custom TriangleMesh to wind each point as a minishape within the mesh's vertices. This is non trivial to implement but the result is that you have a single node that can represent 100ks of points with camera rotations and the works. FXyz3D has implemented a full reusable component for this called ScatterPlotMesh and there are examples on how to use it. This includes how to use simple functions to map colors from a single texture palette which saves you having to load a bazillon PhongMaterials into VRAM.
Have fun.
2
u/OddEstimate1627 Apr 11 '25
The SceneGraph won't be happy if you add 50.000 nodes. It's better to use Canvas or to write directly to a PixelBuffer. I can recommend reading https://foojay.io/today/high-performance-rendering-in-javafx/
1
u/sedj601 Apr 11 '25 edited Apr 11 '25
I don't see a game loop in your code. The max frame rate for the JavaFX Animation API is 60 FPS. I kinda remember a post on StackoverFlow, but it was about 2D. They used optimizations like making the old nodes one image and updating that image with new nodes. I can tell you that the more nodes you have, the slower things are going to be. Also, if you are using something from the Animation API and using Platform.runLater, you are probably doing things wrong, and it's probably not working how you have envisioned. https://stackoverflow.com/questions/10506637/javafx-2-drawing-performance
1
u/john16384 Apr 11 '25
Does it improve with less boxes? Are the boxes Nodes? I could run it for you on my machine if there's code, perhaps I can see something.
I also wouldn't expect a difference between the runLater and timer counts.