Quick answer: Modify node.process_material instance, not the asset. Use .duplicate() for per-emitter variation.
Set custom uniform on the asset; all emitters change. Or modify per-emitter; only one updates because they shared the asset.
The Fix
# Per-emitter uniform
@onready var p: GPUParticles2D = $Emitter
func _ready():
var mat = p.process_material.duplicate()
p.process_material = mat
mat.set_shader_parameter("wind_speed", 5.0)
Duplicate creates a unique material instance. set_shader_parameter then targets only this emitter.
Verifying
Set uniform per-emitter. Each one’s wind speed differs. Without duplicate: all share asset.
“Duplicate. Per-instance uniforms.”
Related Issues
For shader uniform array, see array. For shader instance uniform, see instance uniform.
Duplicate. Set per instance.