Godot version:
3.2 master (15425b45)
OS/device including version:
Any OS, GLES3
Issue description:
While testing conversions from Particles2D to CPUParticles2D, I noticed a few things which do not get properly converted or do not work the same way once converted in the CPU variant. Similar issues exist for Particles -> CPUParticles (3D), so it's worth reviewing all 4 nodes systematically to fix or document inconsistencies.
FLAG_DISABLE_Z flag. PR #29683
(CPU -- GPU)

(GPU -- CPU)
lifetime is used or missing as a factor in the randomness code, and a fix similar to c13ac398f might be needed. PR #29696
(CPU -- GPU)

(GPU -- CPU)

(CPU -- GPU)
Will add more as I find them.
Test project: particles.zip
Note: The "Direction_Mask" Particles2D in the original demo, and kept in this example, seems to be kind of broken, as it will work some times and fail at other times. Disabling the "Disable Z" flag on the Particles2D seem to make it work more reliably, but I suspect some uninitialized variable or other issue.
I made a test project for Particles2D & CPUParticles2D based on the 2d/particles official demo:
particles.zip
In the cpuparticles.tscn scene, all particle effects have been duplicated the duplicate converted to CPUParticles2D using the editor plugin feature. It illustrates some of the bugs outside above and some more, especially when you start playing with the various directional acceleration properties which often do nothing for CPUParticles2D.
I have found a couple while working on https://github.com/godotengine/godot/pull/29700
These are 3D
[x] Depth draw order lifetime reversed for CPUParticles (same as https://github.com/godotengine/godot/issues/29440) (Will be addressed in #29700)
[x] Depth draw order view_depth doesn't match Particles (will be addressed in #29700)
[x] Default velocity is 1 in CPUParticles while it is 0 in Particles (Junior Job: just change 1 to 0 here) PR #29958
A few from the test case (2D):
[ ] Emission mask not maintained when converting to CPUParticles2D
[ ] Visibility rect not drawn in CPUParticles2D (start by copying from here https://github.com/godotengine/godot/blob/f410e7a8a9b14fd9f5c210afcc9e3519e9ce246d/scene/2d/particles_2d.cpp#L297-L300) )
Visibility rect not drawn in CPUParticles2D (start by copying from here)
Regarding the visibility rect, @JFonS told me that the property was not added to CPUParticles* as it's computed automatically. But maybe we still want to draw the computed rect?
Edit: Actually, CPUParticles also doesn't have its visibility AABB drawn and it can't be selected.
@akien-mga The Particles2D sphere is actually just a projected 3D sphere (so you're correct about that). In a way, it makes sense as the UI says under "Flags": "Disable Z" and if you had to "disable Z" you would of course use orthogonal projection.
The CPUParticles2D sphere is a non-uniform density circle as it is created by normalizing uniformly distributed random points in a square. This means that the "diagonal regions" have a point density of sqrt(2) times that of the "cardinal regions". That can be fixed by using trigonometric functions at the cost of some performance
(i.e. t = 2 * PI * Math::randf(); x = r * cos(t); y = r * sin(t);).
Of course, it is not up to me to decide what is important to you (or anyone else), so take this more as a description of the status quo than a recommendation.
Would prefer a uniform distribution in a circle, like @simonpuchert supplied an algorithm for :+1:
Would prefer a uniform distribution in a circle, like @simonpuchert supplied an algorithm for 馃憤
That code creates a circle outline, we have decided to go with the sphere for CPUParticles2D to match the behaviour of Particles2D. We have discussed adding a circle option and a square option later. But for now, it makes the most sense for the two types of particles to have the same behaviour.
But for now, it makes the most sense for the two types of particles to have the same behaviour.
Sorry about that, what i meant that it would be nice to have uniform circle distribution of particles, for both particles2d and cpuparticles2d! It would also be nice to have the old circle outline and this sphere as options also. Maybe also rect outline? I think several options here is a good thing, since particles need to be unique and highly customizable :) I could open a new issue with feature request?
If you want a similar "algorithm" for the projected sphere, it would be
s = Math::randf();
t = 2*PI*Math::randf();
rad = r*sqrt(1-s^2);
x = rad*cos(t); y = rad*sin(t);
and a 3D sphere would be
s = Math::randf();
t = 2*PI*Math::randf();
rad = r*sqrt(1-s^2);
x = rad*cos(t); y = rad*sin(t); z = r*s;
An easy way to understand how it works is to look at the Lambert equal-area cylindrical projection.
Again, I'm not here to say what you should do, but if you want a uniform distribution on a sphere this is one way to accomplish it.
By the way, scene/3d/cpu_particles.cpp also uses the "normalized cube" method, so it produces the same non-uniform-density sphere.
It might also make sense to track this one #40807 here, because the behavior is different in GPU particles.
Most helpful comment
@akien-mga The Particles2D sphere is actually just a projected 3D sphere (so you're correct about that). In a way, it makes sense as the UI says under "Flags": "Disable Z" and if you had to "disable Z" you would of course use orthogonal projection.
The CPUParticles2D sphere is a non-uniform density circle as it is created by normalizing uniformly distributed random points in a square. This means that the "diagonal regions" have a point density of sqrt(2) times that of the "cardinal regions". That can be fixed by using trigonometric functions at the cost of some performance
(i.e. t = 2 * PI * Math::randf(); x = r * cos(t); y = r * sin(t);).
Of course, it is not up to me to decide what is important to you (or anyone else), so take this more as a description of the status quo than a recommendation.