Why is GPUParticles3D Initial Velocity causing my particle flame to 'hop'?

Godot Version

v4.3.stable.official [77dcf97d8] `

Question

I’m trying to create a burner effect for a space ship. I’m having trouble with the flame hopping back and forth and causing a lot of visual artifacts.

At first, I created a frame that with a particle length of 3 sec and an initial velocity of 1. This created a steady flame that looked good when my ship wasn’t moving, but had the issue that is your move the ship around that it left a very obvious trail of slowly vanishing particles. I tried changing the emission to space to local, but this creates an odd fixed flame that doesn’t look natural.

To get around this, I switched the particle space back to global, set the lifetime to .1 and the initial velocity to 15. This creates a similar looking flame, but now it’s hopping back and forth from the burner instead of steady like before. I’m guessing this is due to the particles being released in a burst and don’t know how to smooth it out so that it is consistent.

Is there a way to make this flame steady with a fast initial velocity?

flame_sputter

Edit:

Okay, I found that by unchecking Interpolate I was able to stop the flame hopping. But the particles are still clumped together. I get this weird segmented effect when I drag the particle system around in my game.

segmented_trail

The right thruster is my particle system as described above but with Interpolate unchecked, the lifetime set to .2 and the initial velocity set to 18. The left thruster is similar, but the lifetime is 3, the initial velocity is 1 and the particles are set to be local to the ship instead of in world space.

1 Like

Would a custom shader be out of the question? I think you could achieve a good effect by shifting the UV by a factor of the ship’s horizontal speed.

Something along these lines?

shader_type spatial;
render_mode blend_add, unshaded, fog_disabled;

uniform float speed_shift: hint_range(-1.0, 1.0, 0.01) = 0.0;
uniform float speed_curve: hint_range(0.0, 5.0, 0.1) = 2.0;
uniform sampler2D flame_texture: repeat_disable;

void fragment() {
	vec2 shifted_uv = vec2(UV.x - speed_shift * pow(UV.y, speed_curve), UV.y);
	ALBEDO = texture(flame_texture, shifted_uv).rgb;
}

I could maybe do something like that as a work around. But it would look flat and have clipping issues (your trail disappears when it gets to the far left or right of your plane).

It also doesn’t address the particle system. I feel GPUParticles3D ought to be able to render this sort of effect and my guess is that this clumping is a side effect of some kind of optimization that is batching the particles. I’m hoping there’s a way to turn it off.

Created a new issue for this.