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

Vulkan: "Uniforms were never supplied for set(3)" error causing very noticeable artifacts #77759

Closed
firebelley opened this issue Jun 2, 2023 · 7 comments · Fixed by #79849
Closed

Comments

@firebelley
Copy link

firebelley commented Jun 2, 2023

Godot version

v4.0.3.stable.mono.official [5222a99]

System information

Windows 11, Forward+, Nvidia 3070 latest driver

Issue description

When instancing many GPUParticles2D, occasionally the following error will be printed to the debugger console:

E 0:15:35:0980   compute_list_dispatch: Uniforms were never supplied for set (3) at the time of drawing, which are required by the pipeline
  <C++ Error>    Method/function failed.
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:8007 @ compute_list_dispatch()

Massive artifacts coincide with this error. See example below:

example.mp4

I am having difficulty recreating the exact conditions for this error. It seems to happen when many GPU particles are added to the tree at around the same time.

Steps to reproduce

  1. Instance many particles at once.

I realize this isn't helpful. I'm going to do more investigation to see if I can get more accurate reproduction steps.

Minimal reproduction project

N/A yet

@AThousandShips
Copy link
Member

This error involves the material for clarity, that's set 3, unsure what happens here but could be some kind of race condition or timing issue, how are you instancing them?

@firebelley
Copy link
Author

I am using a handful of materials. I'm using a material for unshaded lighting for the bullets, a material for particles animation for all the particles you see in the video, and a material for additive light blending again for the bullets.

I'm not instancing them in any particularly unorthodox way. I use ResourcePreloaders to store references to the relevant scenes and then I instantiate them and add them to the tree. The materials are all assigned in their respective scenes, they're not being assigned via code.

I've been running a couple of experiments to try to reproduce but with no luck. Sometimes this issue doesn't happen. I don't know what information to provide to be helpful.

@Mortichar
Copy link

I'm running into this same issue after following this tutorial: https://www.youtube.com/watch?v=D7XSL0zBOwI

Godot 4.1 dev 3
Forward+ NVIDIA 1070 Ti

I'm using a PackedScene with a single GPUParticles2D with a process material that is local to the scene. The instancing is done a couple times a second on average with just:

var new_death_effect: DeathEffect = death_effect.instantiate()
new_death_effect.global_position = global_position
new_death_effect.sprite_tex = $Sprite2D.texture
$"/root/Main/".add_child(new_death_effect)

And the entire contents of death_effect.gd:

extends GPUParticles2D
class_name DeathEffect

@export var sprite_tex: Texture

@onready var timer: float = 0.0

# Called when the node enters the scene tree for the first time.
func _ready():
	var player = $"/root/Main/Player/"
	if player != null:
		var direction = (global_position - player.global_position).normalized()
		process_material.set_shader_parameter("direction",
			Vector3(direction.x, direction.y, 0.0))
	else:
		process_material.set_shader_parameter("spread", 180.0)
	process_material.set_shader_parameter("emission_box_extents",
		Vector3(sprite_tex.get_width() / 2.0, sprite_tex.get_height() / 2.0, 1.0))
	process_material.set_shader_parameter("sprite", sprite_tex)
	
	amount = sprite_tex.get_width() * sprite_tex.get_height()
	
	one_shot = true
	emitting = true

func _process(_delta):
	if not emitting:
		queue_free()

To make the shader I simply created a new ParticleProcessMaterial and then converted it. I added:

		vec2 particle_position = TRANSFORM[3].xy;
		vec2 texture_size = vec2(textureSize(sprite, 0));
		COLOR = texture(sprite, (particle_position / texture_size) + vec2(0.5, 0.5));
		if (COLOR.a == 0.0) {
			ACTIVE = false;
		}

to the end of start, and I replaced all of the COLOR assignment in process with:

	COLOR.a -= 1.0 / LIFETIME * DELTA;

@MyrTheMoth
Copy link

MyrTheMoth commented Jun 18, 2023

I'm having the same issue, for me it doesn't happen during creation, but during deletion of any node with a particle, I can create thousands upon thousands of particle instances, where it's more likely the game will slow down to a crawl without the error ocurring, but while deleting nodes with particles, regardless of it being a few or many, the error can happen randomly at any time, I don't know how to help debug this either.

I'm on 4.0.3 Stable, using GPUParticles3D on Forward+, this is how I'm doing it myself:

Script on my Instanced Particles, I let them wait for a while before deleting so that they can finish their animations, they are deleted either when not visible or when they impact:

extends GPUParticles2D

func _process(delta: float) -> void:
        
	if !visible:
		if $RemoveTimer.time_left == 0:
			$RemoveTimer.start(lifetime)

func player_impact() -> void:
	emitting = true
	if $RemoveTimer.time_left == 0:
		$RemoveTimer.start(lifetime)

func _on_remove_timer_timeout() -> void:
	if emitting:
		emitting = false
		if $RemoveTimer.time_left == 0:
			$RemoveTimer.start(lifetime)
	else:
		call_deferred("queue_free")

And this is how I instance them:

const PlayerImpact := preload("res://scenes/entities/effects/PlayerImpact.tscn")

func player_impact() -> void:
	var impact_instance = PlayerImpact.instantiate()
	get_parent().call_deferred("add_child", impact_instance)
	impact_instance.set_deferred("global_position", global_position)
	impact_instance.call_deferred("player_impact")

@YuriSizov
Copy link
Contributor

YuriSizov commented Jul 24, 2023

It's likely that #79849 fixed this issue, but we can't say for sure without an MRP. So please give it a test (either by compiling master yourself or waiting for 4.2 dev 2 later this week).

@felbecker
Copy link

As far as I can tell this is not fixed by #79849 and in particular still happening in 4.2 dev 4.

For me it seems to happen when freeing nodes with GPUParticles2D, as others reported. The visual glitches happen for other currently emitting GPUParticles2D seemingly unrelated to the deleted ones.

@AThousandShips
Copy link
Member

AThousandShips commented Sep 9, 2023

Can you provide an MRP?

  • A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the .godot folder in the archive (but keep project.godot).
  • Drag and drop a ZIP archive to upload it. Do not select another field until the project is done uploading.
  • Note for C# users: If your issue is not Mono-specific, please upload a minimal reproduction project written in GDScript or VisualScript. This will make it easier for contributors to reproduce the issue locally as not everyone has a Mono setup available.

If so please open a new issue with the MRP

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

Successfully merging a pull request may close this issue.

7 participants