Hello folks,
Akien told me I had to open an issue related to this at GodotCon...
So here we are!
Godot version:
Beta 4 of 3.1
Issue description:
When tweening the amount of particles on screen, the engine fps drops to about 1 fps for several instants before being able to catch up to the required amount of particles on screen.
Steps to reproduce:
extends Control
const AMOUNTS = [256, 1e6]
var start = AMOUNTS[0]
var end = AMOUNTS[1]
func _ready():
tween_particles()
func tween_particles():
$Tween.interpolate_property($Particles2D, "amount",
start, end, 5, Tween.TRANS_SINE , Tween.EASE_IN_OUT)
$Tween.start()
func _on_Tween_tween_completed(__,__):
if ($Particles2D.get("amount")>AMOUNTS[0]):
start = AMOUNTS[1]
end = AMOUNTS[0]
else:
start = AMOUNTS[0]
end = AMOUNTS[1]
tween_particles()
Minimal reproduction project:
tween-particles.zip
Possible fixes:
What is your graphics card and OS, incidentally?
OS: Windows 10 Home
Graphics Card: NVIDIA GeForce GTX 970
Setting the "amount" property of a Particle node completely deletes all the particle buffers and creates new ones. By tweening this property you are creating and deleting huge buffers every frame so the performance hit is expected.
I would set the amount of particles to the maximum value and tween a uniform in a particle shader that controls the amount of visible particles. You can find a similar workaround in https://github.com/godotengine/godot/issues/16352#issuecomment-452987479.
@JFonS I don't remember what we said at GodotCon exactly, but didn't we discuss maybe doing this behind the scenes, by always allocating a po2 buffer, and only resize if the amount exceeds the current po2 size?
@akien-mga I would rather make it explicit, have separate properties for buffer size and particles amount. In many cases the amount of particles will not change over time and it will most likely not be a po2 amount, so we will be wasting resources for no reason.
I think having a "capacity-like" property that grows with the amount of particles but doesn't decrease automatically is a good compromise. This should be implemented with #16352 in mind, so users can set the maximum amount of particles beforehand and then change the amount of particles without resetting the simulation nor having the performance hit of buffer allocation.
I will assign this issue to me and try to get this done for 3.2
Most helpful comment
@akien-mga I would rather make it explicit, have separate properties for buffer size and particles amount. In many cases the amount of particles will not change over time and it will most likely not be a po2 amount, so we will be wasting resources for no reason.
I think having a "capacity-like" property that grows with the amount of particles but doesn't decrease automatically is a good compromise. This should be implemented with #16352 in mind, so users can set the maximum amount of particles beforehand and then change the amount of particles without resetting the simulation nor having the performance hit of buffer allocation.
I will assign this issue to me and try to get this done for 3.2