Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Particles Constantly Causing Lag Spikes Under VERY Specific Circumstances #45613

Open
Pixelmusement opened this issue Jan 31, 2021 · 9 comments

Comments

@Pixelmusement
Copy link

Godot version: 3.2.3.stable.official (Steam Release)

OS/device including version:
Windows 10 Pro 19041.423
CPU: AMD FX-8350 4 GHz
GPU: GeForce GTX 1070 - 8 GB VRAM
RAM: 16 GB
Using an HDD, not SSD, for Storage

TL;DR Issue description:
Instancing a particle system is causing lag spikes under specific combinations of window/fullscreen and vertical sync settings when using the Multi-Threaded Thread Model. This does not seem related to the shader caching issue that's been reported with particle systems previously.

Issue description:
I ran into a lag spike issue with particles in Godot which is NOT related to the one most people run into. Typically, the way lag spikes happen with particles is someone creates an instance of them and if the particles are not already properly loaded and cached, there's an initial lag spike, but then no more lag spikes following.

However, I was encountering lag spikes with EVERY particle system I instanced, even when the same one was already in the scene and running! First I had to trace the problem down to the particle system because it was a complex object causing the issues, once I did I tried everything I could think of to eliminate the lag spikes to no avail, even going so far as to create files and preload EVERY part of that particle system. Besides, once it was instanced, running and visible in the scene, creating new instances should not have caused more lag spikes.

Then just out of curiosity I tried running my game windowed instead of full screen and the lag spikes disappeared...

So... I performed a LOT more testing to narrow this down and hit the following conclusions regarding instancing particle systems:
Full Screen Exclusive + No VSync = Fine
Full Screen Exclusive + VSync = Lag Spikes
Full Screen Exclusive + Compositor VSync = Lag Spikes
Full Screen Borderless + No VSync = Fine
Full Screen Borderless + VSync = Lag Spikes
Full Screen Borderless + Compositor VSync = Odd shearing, but otherwise Fine
Windowed + No VSync = Fine
Windowed + VSync = Lag Spikes
Windowed + Compositor VSync = Fine

And I was about to write this off as completely unsolvable for a vertical synced full screen... until I tried one more setting... as all of the above was done with the Thread Model set to Multi-Threaded...

Full Screen Exclusive + Compositor VSync + Single-Threaded Safe = Fine

And yeah, as you can tell, my system is one of the ones which has been hit hard by the Desktop Window Manager changes from Win10 Anniversary onward, so the new Compositor-based VSync option absolutely helped on my end, but it appears sticking with the Single-Threaded thread model is important too... at least, for now. I also understand that compositor-based VSync still has issues for some people so I plan to expose this setting as a user option once I get that far in my project.

@Zireael07
Copy link
Contributor

Without a minimum project (probably just the particles causing the problem) it's likely no one will be able to help and/or fix...

@Calinou
Copy link
Member

Calinou commented Jan 31, 2021

Is this 2D or 3D? Can you reproduce the issue when using CPUParticles instead of the GPU-based Particles?

So... I performed a LOT more testing to narrow this down and hit the following conclusions regarding instancing particle systems:
Full Screen Exclusive + No VSync = Fine

Godot currently doesn't support exclusive fullscreen: #41746

@Pixelmusement
Copy link
Author

Pixelmusement commented Jan 31, 2021

Is this 2D or 3D? Can you reproduce the issue when using CPUParticles instead of the GPU-based Particles?

So... I performed a LOT more testing to narrow this down and hit the following conclusions regarding instancing particle systems:
Full Screen Exclusive + No VSync = Fine

Godot currently doesn't support exclusive fullscreen: #41746

Curious that it has a different effect compared to using borderless with the window size set to the screen size... :o

But to answer the question I'm making a 3D game so I have no idea if this also happens in 2D. I did however try using CPUParticles and got the same lag spikes.

@Calinou
Copy link
Member

Calinou commented Jan 31, 2021

Curious that it has a different effect compared to using borderless with the window size set to the screen size... :o

This is because Windows 10 has special handling for borderless windows that span the whole screen.

But to answer the question I'm making a 3D game so I have no idea if this also happens in 2D. I did however try using CPUParticles and got the same lag spikes.

Does it happen if you switch to the GLES2 renderer then use CPUParticles? (GPU particles aren't supported in GLES2.)

@Pixelmusement
Copy link
Author

Pixelmusement commented Jan 31, 2021

Does it happen if you switch to the GLES2 renderer then use CPUParticles? (GPU particles aren't supported in GLES2.)

Well... my game absolutely won't work right in GLES2, but as suggested I spent a solid half hour making a separate test project to demonstrate the problem:

ParticleLagTest.zip

Just press spacebar to make particle emitters randomly appear. Even with the profiler going there are serious spikes every single time I press the spacebar and I can visually see the cylinder moving back and forth skip a frame. If I go back to Single-Safe from Multi-Threaded the lag spikes go away, and yes, using GLES2 and CPUParticles solves the issue as well, BUT, using CPUParticles with GLES3 does not.

@Calinou
Copy link
Member

Calinou commented Nov 19, 2022

@Pixelmusement Can you (or anyone else) still reproduce this bug in Godot 3.5.1 or any later release?

@Pixelmusement
Copy link
Author

@Pixelmusement Can you (or anyone else) still reproduce this bug in Godot 3.5.1 or any later release?

Quick test of the ParticleLagTest project in v3.5.1.stable.official [6fed1ff] as well as the current active 3.5.x stable branch build on Steam v3.5.stable.official [991bb6a] shows that this is still a problem in both instances with the thread model set to "Multi-Threaded", but is working fine with "Single-Safe".

The initial shader compilation for the particles still causes a HUGE lag spike the first time with synchronous shader caching as well, but that's kinda expected at this point. Switching to async caching is doing its job here and prevents the initial shader compilation lag spike, but either way, the lag spikes from multi-threaded are still a problem.

Now that I know how to use the Profiler though, one curious thing I can point out is that these lag spikes are apparently coming from "Script Functions", and that the spike is caused by the script function taking up the EXACT same amount of time as a normal vertical-synced frame, almost as though TWO vertical syncs are happening. If I disable vertical sync and leave multi-threaded set, the problem also goes away, but then that ramps GPU usage to 100% which is incredibly unnecessary in terms of power consumption.

So presently, the situation is:

Vertical Sync + Single-Safe Model = Fine
Vertical Sync + Multi-Threaded Model = Lag Spikes
No Vertical Sync + Any Thread Model = Fine (but 100% GPU usage)

@Calinou
Copy link
Member

Calinou commented Nov 20, 2022

If I disable vertical sync and leave multi-threaded set, the problem also goes away, but then that ramps GPU usage to 100% which is incredibly unnecessary in terms of power consumption.

You can set a FPS limit by setting Debug > FPS > Force FPS above 0 in the project settings. It works in exported projects too.

@Pixelmusement
Copy link
Author

Pixelmusement commented Nov 20, 2022

You can set a FPS limit by setting Debug > FPS > Force FPS above 0 in the project settings. It works in exported projects too.

Interestingly, the problem does not come back doing this, which further confirms that it's definitely a combination of vertical sync, with the thread model set to multi-threaded, and instancing a particle system, which causes the lag spikes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants