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: MultiMesh
#91818
base: master
Are you sure you want to change the base?
Conversation
I ported more stuff like follow-up PRs, but I still didn't manage to make it fully work yet. Here is a test project godot-multimesh-test.zip with a simple script: extends MultiMeshInstance3D
const SPEED: float = 5.0
func _physics_process(delta: float) -> void:
for i in multimesh.instance_count:
multimesh.set_instance_transform(i, multimesh.get_instance_transform(i).translated(Vector3.UP * SPEED * (1 if i % 2 == 0 else -1) * delta))
print(multimesh.get_instance_transform(0).origin) It works when physics interpolation is disabled (and it moves the boxes up/down in visibly discrete steps as expected, at a low physics tick rate), but it doesn't work when physics interpolation is enabled (movement is stopped). The same script in Godot 3 does work correctly: godot-3-multimesh-test.zip Any help with finding what I missed is very welcome. |
I wasn't able to find the physical interpolation for MeshInstances was that forward ported? |
@fire It is not yet ported. As far as I understand, MultiMesh physics interpolation should work independently from the rest (and it is a big chunk of the work, so I chose to do it first). For example, the following code does work already with this PR: extends MultiMeshInstance3D
const SPEED: float = 5.0
var time: float = 0.0
func _physics_process(delta: float) -> void:
time += delta
for i in multimesh.instance_count:
multimesh.set_instance_transform(i, Transform3D(Basis(), time * Vector3.UP * SPEED * (1 if i % 2 == 0 else -1) * delta)) It is interpolated. So what seems to be broken in this PR currently (possibly as a side-effect) is Edit: The MultiMesh interpolation does work using the Forward+ and Mobile renderers, just not with Compatibility. Edit 2: It seems the buffer layout of a MultiMesh is different when using the Compatibility renderer, and the physics interpolation code is currently assuming the other layout. Edit 3: That's not exactly the issue; there is some compression/decompression that should take care of the difference already. However, there is an issue in the GLES3 MultiMesh cache (found with help from @clayjohn): godot/drivers/gles3/storage/mesh_storage.cpp Lines 1950 to 1951 in bdc0316
|
I can be a rubber ducky, if you want to explain how you think it's broken. One of my friends is dependent on the addon interpolation and we could probably devise a testing strategy. |
@fire Thanks, the issue has already been found and fixed by the PR linked just above. This PR is ready for review now. |
There is some probability of getting garbage data in the MultiMesh buffer on game start (e.g. in the MRP above with Forward+ and 5 physics ticks per second), probably due to |
Is there an identity init? Alternatively instead of interpolating pick one of the inputs. Like return the inputs. |
Ah I'll see if I can double check this in 3.x if I get a moment. 👍 |
Adds fixed timestep interpolation to multimeshes. Co-authored-by: lawnjelly <lawnjelly@gmail.com>
I've had a little look through and it looks mostly okay from what I could see (a few differences from 3.x but I'm sure @rburing has figured them out). To some extent this kind of thing you have to go for and then see what bugs come up that might have been missed. It probably needs a sensible review from someone on 4.x rendering team though, as architectural concerns are slightly different in 3.x (which is mostly maintenance) compared to 4.x (which is being rapidly iterated). In particular the wrapper for the multimeshes I find a bit ugly (with the underscores), I don't know if anyone can think of a more elegant way. |
@lawnjelly Thanks! I added a link to this PR in the notes for the rendering team meeting on 2024-05-23 along with two questions, which got the following answers:
I could probably parallelize |
Sure, interpolating on GPU is always an option. 👍 Kind of considerations I would be thinking:
At 60tps and 60fps, you are uploading 2x the data to save doing some small calculations on the CPU, it may be less clearcut. Also for games, sometimes a constant cost per frame (even if higher) is better than cost that changes wildly frame by frame.
It's hard to predict some of these things, and if you wanted to use GPU approach it might be good to start by doing some benchmark comparisons of both before committing, maybe GPU could be wildly faster and that might clinch it. |
I doubt Hermite interpolation is viable for physics, given its requirement on an additional variable (velocity) and the fact it needs one more frame of latency to do its work. At 30 Hz physics, the latency from linear physics interpolation is already significant, so Hermite would make it even higher for limited visual benefit. It can be viable for networking in MMOs and the like, but the physics interpolation system isn't designed to work for networking as it lacks any kind of buffering (it's only designed for client-side physics). For networking, a dedicated system should be created instead: godotengine/godot-proposals#7280 |
Adds physics interpolation support to multimeshes, based on @lawnjelly's
This is running at 5 physics ticks per second, interpolating position and color:
multimesh-interpolation.mp4
Test project: godot-multimesh-test.zip and Godot 3 version for comparison: godot-3-multimesh-test.zip
This is a sizable self-contained chunk of the interpolation work, so I put it in its own PR.
To-do:
This PR is sponsored by My Spare Time™.