-
-
Notifications
You must be signed in to change notification settings - Fork 22.9k
Description
Tested versions
Reproducable in 4.4.1. and v4.5.beta3.official
System information
Godot v4.4.1.stable - Linux Mint 21.3 (Virginia) on X11 - X11 display driver, Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce 930MX (nvidia; 570.169) - Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz (8 threads)
Issue description
A multimesh is created in RenderingServer and the positions of the multimesh instances are updated in a compute shader. This part is working fine, I can update mesh locations in the compute shader and they are being drawn correctly.
I try getting the location of individual meshes so e.g. the camera can follow one planet as a test:
var EarthPosition=RenderingServer.multimesh_instance_get_transform(planet_Multimesh,4)
look_at(EarthPosition.origin)
In the MVP a position is just retrieved and printed when the space bar is pressed.
The camera is stuck looking at the starting position of that planet, which of course has moved away due to the compute shader. It looks like multimesh_instance_get_transform is retrieving a CPU copy of the buffer.
While a more complete indirect multimesh might allow draw calls to use a SSBO directly, I have used the multimesh buffer as this appears to be the only way to do multiple draw calls using GPU created data.
MrCDK confirmed on forum that:
servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp does not update if cached buffer is still present. But there does not seem to be any use case for instance_get_transform() if the instance positions have not been changed outside the GPU. I suspect the same is true for get_color and get_custom.
Forum post with link to Godot source
A quick fix would be to change MeshStorage::_multimesh_make_local
and remove :
if (multimesh->data_cache.size() > 0) {
return; //already local
}
But it would possibly be better to retrieve the individual instance data when needed to reduce transfers.
Steps to reproduce
Create Multimesh
Get Multimesh buffer RID and use it as a storage buffer for a compute shader to update mesh positions on GPU.
Retrieve a mesh instance transform using RenderingServer.multimesh_instance_get_transform