Godot: Particles2D freezes the game during a few frames when emitting is set to true

Created on 4 Mar 2018  路  30Comments  路  Source: godotengine/godot

Godot version: 3.0.2 stable

OS/device including version:
Ubuntu 17.10 with AMD R5

Issue description:
Setting emitting = true on a Particles2D node that was never emitting before, freezes the game for a couple of frames.
Affects release builds too.

Steps to reproduce:
Set emitting = true for the first time on a non emitting Particles2D node while the game is running.

Minimal reproduction project:
particles-emit-bug.zip

archived bug rendering

Most helpful comment

If the game needs an extra loading time, it will be fine, but a full pause for the first time a particle is emitted is really bad.

All 30 comments

Can麓t replicate in Win 7 compiled from master at 3/03/18. Particles works well, no frames skipped.
particlesubuntubug

This particles has 5 frames of preprocessing, do the test of set preprocessing to 0 and see what happend (but 5 preprocessing frames should not stop a single render frame until the scene becomes huge....)

Ok... preprocess is in seconds... so if your system is not powerful it can skip frames (5 seconds of preprocessing take time to do, and makes no sense in a particle system that loops in 2 seconds)

Preprocessing is in 5 because I was testing it but I think there is an issue about preprocess not working, zero does the same and looks worse on web exports.

And some users seem to be experiencing that on add_child too of scenes with a Particles2D node, not only on emission change.

Ok. In win 7 i have not problems. Maybe related to godot-ubuntu or maybe related to gles3 compatibilities... In theory particles in godot 3 are gpu processed. Any gles3 menssage on startup?

No error messages, and is on the first time the particles are emitted, maybe the texture/material resource loading is doing something here.

Particles texture should load at the beggining of the scene, if there any freeze should be at start... There is more freezes with instancing other kinds of resources/objects?

Well... with no textures is the same, with no particles material there is a barely noticeable effect, I do not know what is doing the particles emit process to cause that...

Are you test recent build? There are a lot of changes...i'm looking for any commit that can do a regesion, but first is good to try master, Can you compile master?

The same with master, and I think it is an old thing but I always thought it was related to audio, it can be reproduced with shots (instancing) and coins (emitting toggle) in the 2D platformer demos.

I've actually noticed this in my project as well. I'm running Godot 3.0.2 on MacOS Sierra 10.12.6. I haven't had the opportunity to try it on Windows, but I will as soon as I can.

In my usage, I am instancing a "bullet" that has a Particles2D node as a child of it. When that bullet is instanced for the first time, I noticed a few frames of visible stuttering/freeze. Every additional instance of the bullet (and particles) has no stutter/freeze.

Also, the particles in my case are emitting by default when they are instanced.

Note: I think this has been around since the 3.0 release.

Seems like particle material, beeing a resource, is not loaded until particles2D is instanced (make sense with the new redesign) but anyway, a simple material for a particle should not freeze nothing. A test that can be done is make a preload with the particle materials in _init() and see if this aliviate the issue. If preloads fix that, well, then we know that problem is with particles material.

I'm not sure I follow. Do you have a simple code example that I can try out?

Simply save the particles material like a .tres file and write in the script:

func _init():
 var xxxxxx = preload("res://xxx/particlesmaterial.tres")

(change x with var name and path)

Do that, not in the script of the bullet... make this in the script of the main node, for preloading in the level charge

Thanks! I gave this a try and unfortunately, it looks like the issue is still there. Assuming, that the preload and assignment to the variable is all that was necessary in the level script.

In the bullet I'm just using the same .tres file that I am preloading in the level. Can you think of any other ideas of what may be causing it?

As I mentioned before, I have tried without texture and without material (where should not work) and the emiting effect is the same, the problem seems to be in Particles2D or VisualServer (which toggles the emitting status).

Tested on Windows 10, same hardware and got the same, this is the profiler when I grabbed a coin in the Platformer 2D demo:

framestuttering

Something is happening on idle time when particle starts emitting.

I can also reproduce the bug using the 2D platformer demo and picking up a coin. It's present in my own project too ^_^

Godot version: 3.0.2 stable

OS/device including version:
Windows 10

particle bug

Using the 2D particle demo, there is noticeable skipping for me.

I had all other particles emitting apart from the explosion and used a button to set emitting = true during runtime.

This only seems to happen the first time emitting is set to true.

I've noticed something similar, but it's not limited to particles. Whenever a material (in my case SpatialMaterial) becomes _visible to the camera for the first time_, there's very short freeze. It only seems to happen once for each material.
Preloading doesn't make any difference, and it's not about instancing. It happens even if the node has already been in the scene tree for a while - as soon as it moves into the camera view for the first time (or the material becomes visible in some other way), there is that short freeze. Sometimes it's so tiny that you don't notice it, but sometimes it freezes for half a second, which is really distracting in the middle of game. I noticed this both for particle effects and simple meshes. Additional nodes sharing the same materials don't have this issue and everything runs smoothly otherwise.

@ProbDenis: I am seeing the same thing for meshes (SpatialMaterial, not some of my custom shaders).

https://i.imgur.com/whxHUNd.jpg

Big freeze is me turning 180 so that some Chinese lanterns become visible.

Issue went away after I moved the lanterns around so they are visible on game start.

Sounds like shader compilation kicking in when new materials are displayed.

'Idle time' in profiler is generally totally not helpful, it would be nice if such things as shader compilation were noted as such.

Also, isn't there an issue about shader compilation maybe getting done at game start or am I misremembering something? Because those big big stutters are BAD for smooth gameplay :(

So it is when some visual node AABB enters the camera?, this should happen with other things as well.

Idle time can not be too helpful but may indicate that something is locking the main thread.

On android this is a several seconds pause.

I'm not on Android so it's not THAT bad but on a Radeon 6630M, this dropped my fps from 25-30 to single digits for a frame or so.

This is more or less normal in OpenGL, because shader compilation happens behind the scenes as soon as the shader is used.

The typical workaround is to make the shaders of all (or most) the materials visible on the first frame (even though they are behind an object), so stalls dont happen later.

From Godot, what could eventually be done is shader caching. This will solve the problem by caching all the shaders that the game uses, but the first time the game is run it will have to generate them anyway (so the solution mentioned above still applies). This happens because OpenGL shader binary that you can obtain for caching is GPU specific.

With Vulkan, this should be easier to solve, as shaders can be pre-compiled using SPIR-V.

If the game needs an extra loading time, it will be fine, but a full pause for the first time a particle is emitted is really bad.

@reduz Is there a good pattern that we can use to work around this? I'm quite unfamiliar, so I'm not sure how to resolve it.

This will be fixed in 3.2, where Vulkan/Shader Caching can be used.

Well, Vulkan won't be an option for mobile and web for a couple of years, I guess that CPU particles will be the only workaround for this.

Good discussion on here, but closing as it is a duplicate of https://github.com/godotengine/godot/issues/13954

Was this page helpful?
0 / 5 - 0 ratings