Godot version:
v3.2.dev.calinou.2293c612e
OS/device including version:
Windows 10
Issue description:
Particle spread doesn't seem to behave correctly when particle direction is along the y-axis.
Expected behaviour (spreads uniformly): https://i.imgur.com/20kSIsO.mp4
Observed behaviour: https://i.imgur.com/vmc4KDv.mp4
I also just noticed that the particles always move along the y-axis with any combination of X and Y != 0 with given Vec3(X,Y,0) for particle direction.
Steps to reproduce:
Create a (GPU) particles node. Set direction to Vec3(0,1,0) and spread to 45 degrees.
This is _relatively_ easy to fix. Here are the responsible code lines: https://github.com/godotengine/godot/blob/d897131ac555de84afe9ca6845abf87c26957895/scene/resources/particles_material.cpp#L315-L320
What happens here is that direction vector is converted to two angle floats, rotated based on spread and converted to vector again. The problem is with the initial conversion. It probably doesn't get angle from vector correctly (3D maths are hard >_>).
So yeah, this is a maths problem about figuring out the correct formula. This can be solved even without compiling Godot - just convert the ParticlesMaterial to shader material and tinker with the resulted shader (it has the same code).
EDIT:
Also this
ReproductionProject.zip
This is not going to be an easy fix. Euler angles are not easy to deal with in 3D, which is why everyone used quaternions and matrices. Properly implementing a direction in 3D will likely involve a lot of difficult math.
I'm not much of an expert so I might be wrong, but I believe that the math works as intended. The spread says that it is applied to the X/Z plane and the Y/Z plane.
When you set the Direction to (0, 1, 0) it becomes more obvious that spread isn't applied to the X/Y plane.
To get a better idea, set the Flatness, to 1, which will restrict the particles to the X/Z plane, and you only see the spread in that plane.
It fails to work for X-axis too.
Whenever Z=0, it has issues.
The spread says that it is applied to the X/Z plane and the Y/Z plane
The behavior matches the docs, but kind of surprising until you find this detail in the tooltip.
Intuitively I expect the spread to form a cone extending from the direction vector.
Most helpful comment
I'm not much of an expert so I might be wrong, but I believe that the math works as intended. The spread says that it is applied to the X/Z plane and the Y/Z plane.
When you set the Direction to (0, 1, 0) it becomes more obvious that spread isn't applied to the X/Y plane.
To get a better idea, set the Flatness, to 1, which will restrict the particles to the X/Z plane, and you only see the spread in that plane.