godotengine / godot

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

GPUParticles3D flickers frozen particle at world origin (0, 0, 0) when shader material has y-billboard set #72650

Closed kraybit closed 1 year ago

kraybit commented 1 year ago

Godot version

v4.0.beta17.mono.official [c40020513]

System information

Windows 10

Issue description

With certain settings, GPUParticles3D intermittently shows a particle at world origin with zero velocity.

These settings in GPUParticles3D caused this behavior:

Quirks

gpu_particles_ybillboard_bug

Steps to reproduce

At world origin (0, 0, 0) there's intermittently a particle with zero velocity.

Minimal reproduction project

gpu_particles_ybillboard_bug.zip

QbieShay commented 1 year ago

Could you re-test with apply_scale flag enabled?

kraybit commented 1 year ago

If the Keep Scale flag is enabled (In the shader material), then the bug disappears!

image Enabling Keep Scale fixes bug

Does this flag have any other side-effects? Also, I couldn't find any apply_scale flag?

Calinou commented 1 year ago

I could reproduce a similar issue with the Particle Billboard mode here: https://github.com/godotengine/godot/issues/49767#issuecomment-1440500413

https://github.com/godotengine/godot-demo-projects/pull/849 also has a stray rain particle in the world origin that remains visible for a long time because of this.

QbieShay commented 1 year ago

oop sorry @kraybit . Yes, it was keep scale not apply scale :D

@Calinou particles use scale 0 to try and make particles invisible, but if keep scale is off then a new matrix is generated based on the camera matrix and the instance_custom.x as a rotation value, so the particles that should be "dead" are instead displayed at the origin (at least this is how it worked in 3.x)

Calinou commented 1 year ago

@Calinou particles use scale 0 to try and make particles invisible, but if keep scale is off then a new matrix is generated based on the camera matrix and the instance_custom.x as a rotation value, so the particles that should be "dead" are instead displayed at the origin (at least this is how it worked in 3.x)

Interesting, I thought their position would be changed to -INF, -INF, -INF (effectively ensuring they're outside the view frustum). This is what the Hide On Contact collision mode does. Should we make it scale particles to 0, 0, 0 instead of moving them?

QbieShay commented 1 year ago

I think that's what happens already, but if you don't enable scale in billboards you still see them. The inf solution sounds better

ecmjohnson commented 1 year ago

The inf solution is much cleaner (2 line change vs. 12) and doesn't have a performance impact on the billboarded materials since they don't need to even check anything