Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physics interpolation breaks GPUParticles2D movement #92006

Open
cosparks opened this issue May 16, 2024 · 4 comments
Open

Physics interpolation breaks GPUParticles2D movement #92006

cosparks opened this issue May 16, 2024 · 4 comments

Comments

@cosparks
Copy link
Contributor

cosparks commented May 16, 2024

Tested versions

Reproducible in 4.3 beta and latest on master.

System information

Windows 10 - Vulkan Forward+

Issue description

Moving and rotating particle emitters whose particles use global coordinates seems to break particle interpolation. The particles will rotate with the emitter's transform instead of moving freely in global coordinate space.

With physics interpolation enabled:

output_video.mp4

With physics interpolation disabled:

output_video-0.mp4

Steps to reproduce

  1. Open minimal reproduction project.
  2. Press F5 to run the project.
  3. Use w and d keys to rotate the character, and press space to thrust.
  4. Notice how active particles will move when you change the direction of rotation.
  5. Go to settings, enable advanced settings and turn off physics interpolation.
  6. Notice that particles will move as normal while the character rotates.

Minimal reproduction project (MRP)

interpolation-issue-mrp.zip

@clayjohn
Copy link
Member

I'm not sure how physics interpolation works. But a hint for whoever picks this up. Particles using global coordinates ignore their transform and bake it into the particle positions in the particle shader. So if physics interpolation relies on moving the transform, it needs to ensure that it updates the transform used when calculating the particles

@cosparks
Copy link
Contributor Author

I just went and read through the PR for the 4.x port of godot 3.x's physics interpolation, and according to this comment, it was decided that particle behaviour was to be left for a follow-up PR. Maybe this is still something that should be fixed before 4.3 is released though?

Also found these comments in particles_storage.cpp relating to what @clayjohn mentioned above. Posting here for visibility:

// Affect 2D only.
if (particles->use_local_coords) {
    // In local mode, particle positions are calculated locally (relative to the node position)
    // and they're also drawn locally.
    // It works as expected, so we just pass an identity transform.
    RendererRD::MaterialStorage::store_transform(Transform3D(), copy_push_constant.inv_emission_transform);
} else {
    // In global mode, particle positions are calculated globally (relative to the canvas origin)
    // but they're drawn locally.
    // So, we need to pass the inverse of the emission transform to bring the
    // particles to local coordinates before drawing.
    Transform3D inv = particles->emission_transform.affine_inverse();
    RendererRD::MaterialStorage::store_transform(inv, copy_push_constant.inv_emission_transform);
}

@lawnjelly
Copy link
Member

lawnjelly commented May 22, 2024

Yes, it's less a bug, and more than particle physics interpolation is not implemented yet in 4.x at all.

Even in 3.6 only CPUParticles are supported so far for physics interpolation in 2D (GPUParticles is more tricky).

The simplest way to handle particles is to force them to update on the frame rather than physics tick (and this is the default in 3.x with physics interpolation in 2D). They must also be able to follow an interpolated target in this mode (else they will appear in front of the interpolated target and judder with the physics ticks).

Many problems come because particles were originally written with transforms specified in local space (even in global mode), whereas they are far easier to interpolate in true global space. (Or at least this is true in 3.x, I suspect there is some similarities in 4.x)

@lawnjelly
Copy link
Member

lawnjelly commented May 22, 2024

Here's a more minimal MRP, with the same effect in GPUParticles2D and CPUParticles2D.

2024-05-22.12-56-47.mp4

particles_2d_example.zip

Good news is the particles leading the target (i.e. being in front) doesn't seem a problem in 4.x (I'm not sure why, but it's a while since I worked on this).

The unwanted rotation is likely as above, that the coordinate system the particles vertices are specified in is not global space (i.e. the node xform is being applied), and the interpolated node rotations is affecting the particles. In 3.x if I remember right, there is a special mode added to prevent this called use_identity_transform, kind of like toplevel but without changing the parent. And the particles are defined in true global space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants