Skip to content

Allow moving meshes without motion vectors#105437

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Ansraer:teleport_spatial_nodes
Apr 25, 2025
Merged

Allow moving meshes without motion vectors#105437
Repiteo merged 1 commit intogodotengine:masterfrom
Ansraer:teleport_spatial_nodes

Conversation

@Ansraer
Copy link
Copy Markdown
Contributor

@Ansraer Ansraer commented Apr 15, 2025

This PR makes it possible to translate meshes without writing their movement to the movement buffer.

Right now, this PR integrates with the physics_interpolation feature to handle the propagation of "teleports" through the scene. To teleport something, the user simply has to update the transform and then call reset_physics_interpolation.

Alternatively the user can use the optional "teleport" parameter when calling manually calling the RenderingServer's bound transform method.

Video Example
EditorRecordingCompressed.mp4

@Ansraer Ansraer requested review from a team as code owners April 15, 2025 20:06
@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch from 5d70223 to f70bd7e Compare April 15, 2025 20:10
@TokisanGames
Copy link
Copy Markdown
Contributor

This works very well to resolve issues with FSR 1, 2.2, and TAA on Terrain3D. All three look good without any artifact issues. Motion vectors are sane. At least this is the case on my RTX 3070.
Thank you very much!

@mrjustaguy
Copy link
Copy Markdown
Contributor

FSR 1 has no temporal components, it's purely spatial.

@lawnjelly
Copy link
Copy Markdown
Member

Given the now confusing naming, an option we could also consider longterm is adding an alias teleport() function instead of reset_physics_interpolation() (and perhaps deprecate the old function name but leave it available for compatibility).

teleport() was always my preference for terminology (and is used in smoothing addon).

Although that would be for separate proposal, as it has implications for docs etc.

Bear in mind also that this PR will need some rejigging after #104269, (or vice versa if this is merged first).

@Ansraer
Copy link
Copy Markdown
Contributor Author

Ansraer commented Apr 16, 2025

Given the now confusing naming, an option we could also consider longterm is adding an alias teleport() function instead of reset_physics_interpolation() (and perhaps deprecate the old function name but leave it available for compatibility).

I thought about that but decided it was out of scope of this PR since it would require me to propagate the teleport through the scene tree, something which right now reset_physics_interpolation() does for me.

I suppose an optional teleport parameter could be added to Node3D's exposed transform functions, similar to what this PR is doing internally right now.
Implementation wise the transform functions would just have to call reset_physics_interpolation() (maybe renamed to reset_interpolation()) after updating the transform if the new parameter is true.

teleport() was always my preference for terminology (and is used in smoothing addon).

Yeah, I also called the optional parameter "teleport" in this PR.

Bear in mind also that this PR will need some rejigging after #104269, (or vice versa if this is merged first).

Yeah. I considered building this PR on top of yours for a while, but in the end decided to stick to master. This is a significantly smaller change than your interpolation refactor, so I am hoping to get it merged quickly.

@lawnjelly
Copy link
Copy Markdown
Member

lawnjelly commented Apr 16, 2025

I thought about that but decided it was out of scope of this PR since it would require me to propagate the teleport through the scene tree, something which right now reset_physics_interpolation() does for me.

Agree is out of scope, but just to clarify my suggestion was to rename the existing reset_physics_interpolation() functionality to teleport(), rather than add in extra machinery.

I suppose an optional teleport parameter could be added to Node3D's exposed transform functions, similar to what this PR is doing internally right now.

We did consider this at the time, but a separate function was preferred in general (with the idea that it would rarely be used), and it had the benefit of being backward compatible. I tended to think this made sense from an efficiency point of view too, as set_transform() is used a lot, and there's no sense in sending an extra bool all the time if it isn't needed.

If you aren't rebasing on top of #104269, you can probably use the existing instance_reset_physics_interpolation() function, making a lot of the changes here unnecessary I think.

If this is the intention long term, I could remove the depreciation of instance_reset_physics_interpolation() in #104269 .. although I suspect it would be better to just create an equivalent server function instance_teleport(RID), something like that.

Actually it occurs to me there is one special scenario we may not have thought of (when used in conjunction with physics interpolation):

If a user has turned off physics interpolation for a branch, the resets may not be propagated currently. We may want to alter this so that the reset (for motion vectors) still gets sent to the server. This is something that can be fixed up after #104269 though.

@TokisanGames
Copy link
Copy Markdown
Contributor

TokisanGames commented Apr 16, 2025

To make this PR and Physics Interpolation work in Terrain3D, we are currently doing this:

	RS->instance_set_transform(mesh_array[instance], t, true); // added true for this PR
	RS->instance_reset_physics_interpolation(mesh_array[instance]);

They are both called right after we reposition the clipmap terrain. It would make sense to me to have one function call reset motion vectors for both PI and TAA/FSR. I think a name like reset_motion_vectors is clearer than teleport, but ultimately don't care as long as I have a clear, documented way to reset them, which has now been provided.

@lawnjelly
Copy link
Copy Markdown
Member

Although we don't always future proof, the problem with using specific names like reset_physics_interpolation and reset_motion_vectors is that it doesn't take account that typically several systems need to get reset on a teleport.

The user should ideally have one function to call that does it all.

Consider that e.g. spatial audio should also be interpolated eventually, just to give an example. Granted that's a different server, but this collision of functionality has already occurred within VisualServer, and it's a fair bet it may happen again.

@Ansraer
Copy link
Copy Markdown
Contributor Author

Ansraer commented Apr 16, 2025

Although we don't always future proof, the problem with using specific names like reset_physics_interpolation and reset_motion_vectors is that it doesn't take account that typically several systems need to get reset on a teleport.

If a user has turned off physics interpolation for a branch, the resets may not be propagated currently. We may want to alter this so that the reset (for motion vectors) still gets sent to the server. This is something that can be fixed up after #104269 though.

I am convinced that we will need a generic reset_interpolation at some point in the future. However, implementing that might be tricky. If this function is always called after the property that should be reset has already been changed I am no certain if we can guarantee that none of the other threads has already reacted to this change and interpolated it before receiving the reset command. Ahh, the joys of multithreading.

If you aren't rebasing on top of #104269, you can probably use the existing instance_reset_physics_interpolation() function, making a lot of the changes here unnecessary I think.

Honestly not really. Most of the changes here are the plumbing needed to expose the optional parameter, something I would have done anyways since being able to turn on teleportation while setting the transform is essential imo.

You are correct that if I had patched that function I could have left VisualInstance3D as it is, but since I already have the teleport parameter I might as well use it. Performance is the same and code readability is better when we are explicit about setting transform with teleport enabled.

However, just for completeness sake I will add teleportation to instance_reset_physics_interpolation(). It is not really needed since imo the proper way is to already enable teleportation when setting the transform, but as long as that method exists it should behave as users expect it to. Feel free to purge it in the future.

@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch from 6750f70 to b4fe882 Compare April 16, 2025 11:21
@AThousandShips AThousandShips changed the title [4.x] Allow moving meshes without motion vectors Allow moving meshes without motion vectors Apr 16, 2025
@AThousandShips AThousandShips added this to the 4.x milestone Apr 16, 2025
@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch 3 times, most recently from 5cbc661 to b3f79f0 Compare April 16, 2025 14:49
@Ansraer
Copy link
Copy Markdown
Contributor Author

Ansraer commented Apr 16, 2025

This PR was just discussed in the weekly rendering meeting. While the overall idea and design was approved, there was some argument about the exposed API.

As of right now, the PR exposes the following function:

RS::instance_set_transform_teleport(instance, global_transform)

However, the team pointed out that in the future we might wish to reset stuff other than the transform of mashes, and thus something along the lines of

RS::instance_set_transform(instance, global_transform)
RS::instance_reset_interpolation(instance)

might be more future proof.

However, we couldn't agree on what the new instance_reset_interpolation() function should actually be called. reset might imply that it completely resets an instance to it's initial state, while teleport means "to instantly move an object from one location in space to another", which imo is only an appropriate name as long as we are only resetting transforms.

I am open to suggestions for a better name. @lawnjelly do you have any suggestions?

@mrjustaguy
Copy link
Copy Markdown
Contributor

FSR 1 will not produce MV issues because it doesn't use them (it's a purely Spatial Upscaler & Sharpener), so no need to spend your time testing FSR 1

@Ansraer
Copy link
Copy Markdown
Contributor Author

Ansraer commented Apr 17, 2025

I'm getting this error message now w/ FSR2 enabled.
Huh, that is interesting. I don't think I changed anything that should mess with that. Made some more minor changes, if you have some time I would appreciate it if you could try again, maybe I already fixed that.

If the issue still exists just report back and I will look into it some more once I am home. Looking at my PR on a phone I can't see how I could be causing this with the current version.

@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch from b885238 to 49fd711 Compare April 17, 2025 17:40
@TokisanGames
Copy link
Copy Markdown
Contributor

TokisanGames commented Apr 17, 2025

FSR 1 will not produce MV issues because it doesn't use them (it's a purely Spatial Upscaler & Sharpener), so no need to spend your time testing FSR 1

The quoted error was new and related to FSR. I was confirming that the error appeared only when FSR2 was enabled, and not in other modes: disabled, FSR1, etc. Nothing to do with MV in this case.

I don't think I changed anything that should mess with that.

I tested more and found:

Copy link
Copy Markdown
Member

@lawnjelly lawnjelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better imo.

This should work fine and I can rejig calling instance_teleport when rebasing the SceneTreeFTI PR.

Probably needs a double check by a member of the 4.x rendering team as I'm not so active there, just to check that logic meets their needs with the motion vectors.

Imo the most important aspect to get right was always the server API function / s, because once set, these are difficult to change without changing backward compat. It is easy to fix bugs / make adjustments in the server later.

@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch from 49fd711 to 77b2427 Compare April 18, 2025 08:09
Copy link
Copy Markdown
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@Bonkahe
Copy link
Copy Markdown
Contributor

Bonkahe commented Apr 25, 2025

Tested on my terrain implementation as well and all artifacts are gone, works like a charm!

@Ansraer Ansraer force-pushed the teleport_spatial_nodes branch from 77b2427 to a4a5f4e Compare April 25, 2025 12:25
@Ansraer Ansraer requested a review from AThousandShips April 25, 2025 13:53
@Repiteo Repiteo merged commit 8954125 into godotengine:master Apr 25, 2025
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Apr 25, 2025

Thanks!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terrain flickering issues with TAA/FSR/Motion blur

10 participants