godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.93k stars 21.15k forks source link

CPUParticles2D emitter glitches with global coordinates when far away from the world origin #81390

Open oeleo1 opened 1 year ago

oeleo1 commented 1 year ago

Godot version

all versions, tested on 3.6beta2, 3.5.2-stable

System information

Windows 10 Pro, 64 bit

Issue description

When the position of a CPUParticles2D node is beyong a limit, the emitter behaves erroneously when the Local Coords box is unchecked, i.e. when we're using global coordinates.

In this reported case, a sphere emitter emits the particles in vertical stripes (Figure 1) when position.x is beyond pow(2, 22), instead of emitting them with the expected uniform distribution (Figure 2).

It was hard to pinpoint the reason triggering the issue but eventually it boiled down to the position of the node combined with the global coordinates setting.

I understand that we're playing on thin ice with floats here, but this clearly seems to be a bug since once emitted in stripes, the particles are moving smoothly on X, so it is not a precision issue, but a math overflow/truncation of some sort.

Figure 1 - bad stripes

Figure 2 - good normal

Steps to reproduce

Comment / uncomment the statement in Main related to positioning the particles node on X and check the output.

Minimal reproduction project

cpup_stripes.zip

Calinou commented 1 year ago

In this reported case, a sphere emitter emits the particles in vertical stripes (Figure 1) when position.x is beyond pow(2, 22), instead of emitting them with the expected uniform distribution (Figure 2).

pow(2, 22) is 4,194,304, which is very far away from the origin when using single-precision coordinates.

It may be possible to improve this somewhat, but there's only so much we can do when individual pixels (in 2D) can barely be represented in terms of precision.

oeleo1 commented 1 year ago

Indeed. Thanks for the pointer. But switching to local coordinates works well when the particles node is positioned far away from the origin. Which is why I think that there may be a lingering bug in the emitter logic.

lawnjelly commented 1 year ago

It looks as though the stripes are created at the beginning of the explosion, where the differences between particles is small relative to the offset from the origin. So it does seem possible this is just down to lack of float precision, I'm not sure this can be discounted.

That said I'm not familiar with the emission code.