-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Vulkan: Shader compilation stutter when materials enter the view frustum for the first time (unless cached) #61233
Comments
What will be the solution to this problem on Vulkan? Will Ubershaders be implemented? A friend of mine working on a game in Godot 4 stumbled on this stuttering and was very confused about its nature until I pointed it out. I recall seeing some discussion about it, with the only one behind a ticket that comes to mind being godotengine/godot-proposals#4754, but I think that it has more specific usecases. Edit: oof, it didn't took so long to find an explaination that ubershaders aren't good enough: godotengine/godot-docs#6217 (comment) what now? |
GD4 Beta4 still stutters quite a bit on load with a lot of assets. You need to force precompilation of shaders. |
I think adding a true asynchronous shader compilation mode is the way to go – essentially mimicking dxvk-async behavior. It causes objects to be temporarily invisible until their shaders are compiled, but this is far preferable to stutter in 99% of situations. dxvk-async is effectively being used to "fix" AAA releases that suffer from shader compilation stutter, without having access to the game's source code. |
@Calinou why couldn't this be integrated with Ubershaders? I recall the dudes over at Dolphin having issues with plain asynchronous compilation, as some shaders depended on being shown right away. |
Primarily this will be solved with a combination of ubershaders (we already have the structure set up), pipeline caching, and asynchronous shader creation/compiling. In Vulkan, the story is much more complicated as pipeline creation is also super expensive. Right now we compile shaders which are quick to load from disk, but we still have to create pipelines in the first frame an object is used which is most likely where the reported stutter is coming from. We also have tools in place to use a more ubershader like approach (so we can quickly compile one variant of the shader/pipeline and then replace it with a more specialized variant later), but we need to make better use of them. |
@clayjohn is this planned by the stable release or will this require enough work to warrant being in 4.1? |
Hopefully we can do most of it in time for the stable release. |
Since VkGraphicsLibrary extension is available almost with every single gpu vendor, could that solution be considered for stuttering problem 🤔 |
Would be interesting to try and implement it since I've been doing multiple personal vulkan projects and I'd like to put it to use. |
The problem is still present in 4.1 (Mobile at least). |
Still an issue on desktop as well. Able to reproduce by clearing the cache shaders in my project's AppData/Roming folder and the NVIDIA cache folder, then restarting the game. Only happens the first time the game. |
Is it not possible for Godot 4.x to use the asynchronous compilation technique 3.5 does? I'm having huge stutters whenever I turn a light on or add a light to the scene (even when using preload()) and I'm not sure what the current workaround is. This happens when the game is run from Steam, so I'm not entirely sure why this would be happening. |
I don’t think that adding a light to the scene causes a pipeline compilation🤔 though someone more knowledgeable can correct me. Does the stutter happen every single time when you add a light? |
It happens the first time a new light is added or turned on, but then it's fine each time you do it after (as if it's become cached). |
It is cached. Pipeline caching was introduced in 4.1 on top of shader caching. You can find it in |
I can retrigger the stutter by deleting specific cache files in my graphics card settings folders. This resets the process of re-caching. When a new shader or post processing effect is enabled it happens then, too. When the game is launched on a version update, it happens though not as severe. Would need to test further to provide feedback there. I look longingly at Steam's "precompile vulkan shaders" message which comes up when I launch certain games through that platform. I'm wondering if there's something to be gleaned from that approach. |
Are lights considered shaders to be cached, though? I'm only having this issue with lights, I'm not even having trouble with changing materials it just seems to happen when lights are enabled or added to the scene enabled. |
The ubershader approach in 3.x had many issues that made it not ideal in my experience:
I would prefer looking at an easier way to create shader precompilation dialogs like this, which seems to be the more common trend in AAA games lately. Asynchronous shader compilation can be used as a fallback to prevent stutter (as a last resort), even if this means having certain objects be momentarily invisible1. Not displaying ubershaders prevents performance issues arising from their use.
This works by making users compile and upload shaders after they're done playing a game. It works because Steam has such a large network of users that you're almost guaranteed to be able to download a compiled shader that matches your OS, GPU and driver version (all 3 need to match exactly). If you see high CPU usage after exiting a game on Steam, that's why 🙂 It is possible for Godot games on Steam to use this approach if they are on Steam and use a Vulkan-based rendering method. Footnotes
|
Geaphics pipeline library could help with invisible meshes in async compilation by creating a fast linked pipeline first before doing final optimized version and by recycling pipeline stages as much as possible. But it would require first to have async compilation infrastructure in place if we want to take advantage of that extension. |
At least that’s my understanding that I got after writing GPL draft pr. |
Here's a clip someone sent me of them playing a game I'm beta testing through Steam (so it's built and run via Steam), you can see a huge lag when the flashlight goes on the first time and not subsequent times (the flashlight is already added to the scene on ready, this is enabling it): iasryu.2.mp4Here's another when a light is removed from the scene, and one after when a light behind the wall is instatiated (it's not seen in this clip): fvuxcv.mp4This seems like an issue with compilation stutter, is this expected behavior with lights being added to the scene/enabled? |
Shaders are compiled per lighting setup, or at least they were in gd3. The only reliable way we've found to reduce stutter is force precompilation. I linked instructions in my comment above. |
Essentially the 4.x version of this? https://github.com/Brandt-J/ShaderPrecompiler I think for the time being a built-in node or even an addon like this would be a good immediate solution so people can avoid as much stutter as possible out-of-the-box (as you mentioned in your comment, 99% of the stuttering #46330 (comment)) |
I forked Brandt-J's to 4.x: https://github.com/elvisish/ShaderPrecompiler4x It seems to work okay from what I can tell, but this should hopefully serve as a bandaid until something can be implemented in 4.x. |
Bugsquad note: This issue has been confirmed several times already. No need to confirm it further.
Godot version
4.0.alpha8
System information
Fedora 36, GeForce GTX 1080 (NVIDIA 510.68.02)
Issue description
A noticeable shader compilation stutter occurs when materials enter the view frustum for the first time (unless cached). This is more visible on lower-end CPUs/GPUs which take a longer time to compile shaders.
Labeling
regression
, as ubershaders make it possible to avoid the initial stutter (on cold cache) in 3.5 with GLES3.Steps to reproduce
.godot/shader_cache/
within the project folder).Minimal reproduction project
test_shader_compilation_stutter.zip
The text was updated successfully, but these errors were encountered: