godotengine / godot

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

ARVR image shakes when Multithreaded and ARVROrigin is attached to RigidBody #26900

Open wombatstampede opened 5 years ago

wombatstampede commented 5 years ago

Godot version: Godot 3.1RC1

OS/device including version: Windows 10, NVIDIA GT610

Issue description: If Thread Model "Multithreaded" is selected and the ARVR Origin is attached to a RigidBody/VehicleBody then this Body shakes back and forth in the left or right view. (Doesn't matter if GLES2 or GLES3.)

Imgur

Steps to reproduce: Attach a ARVROrigin and ARVRCamera to a RigidBody/Vehicle Body. Enable ThreadModel "Multithreading". Run the project and move the RigidBody.

Minimal reproduction project: You need NO VR Gear to test this: Attached is the Trucktown demo which is just modified to enable the ARVR view. --> Select the "Mini Van". Move the truck with cursor keys. truck_town_vr.zip

akien-mga commented 5 years ago

CC @BastiaanOlij

BastiaanOlij commented 5 years ago

I think this is caused by the physics engine updating the rigidbody position after we've already determined the global position of the camera. It's pretty scary that it's able to even updated it between rendering the left and right image. Does the same happen with a normal camera attached to the truck (so not using VR)? I wouldn't be surprised if the same issue shows.

@reduz I have no idea how Godot manages the updating positions in multi-threading mode. I know other engines solve things like this by updating the positions into separated buffers. So you have a buffer that holds the positions that are currently being rendered, and you have a buffer that the other threads can update the positions in. Then just before you start rendering you swap and reset the write buffer.

wombatstampede commented 5 years ago

This does not happen (here) with a normal camera attached to the truck.

(I`ll have to mention that my project where the issue came up seems also to run well in Singlethreading mode. But I wanted to mention this issue anyway.)

BastiaanOlij commented 5 years ago

@wombatstampede it'll be good to figure out what is causing it.

I haven't done much with multithreading, it gives me headaches on the GDNative implementations because OpenGL hates multiple threads and gladly crashes when something needs to be setup in the main thread but is only accessible in the render thread :)

The little mobile vr driver hasn't got this problem :)

BastiaanOlij commented 5 years ago

Just a small addition here, I've been playing around with a new project (space flight sim) and enabled multi tasking on it. Experienced similar results where the eyes seem to get out of sync in certain frames. I have no idea about the cause yet though, sticking with not running the renderer in a separate thread for now.

aaronfranke commented 4 years ago

RigidBodies have had glitchy behavior in Godot for a long time. Related: https://github.com/godotengine/godot/issues/22904

KoBeWi commented 3 years ago

Can anyone still reproduce this bug in Godot 3.2.3 or any later release?

m4nu3lf commented 1 year ago

Can anyone still reproduce this bug in Godot 3.2.3 or any later release?

I definitely can with 3.5-stable. It's quite a problem for me because I want, for performance reasons, to run multithreaded. I'll see if I can debug it further.

m4nu3lf commented 1 year ago

I think I have already found the root cause. The ARVROrigin is updating the world_origin during INTERNAL_PROCESS here. Inside the ARVRServer that immediately updates the internal value. That value is then read by the rendering thread here here.

There is no synchronization between these, and they can happen in any order, as _process() runs in parallel to the rendering server.

Now I need to test this hypothesis by making that thread-safe. I wonder how, though.

m4nu3lf commented 1 year ago

I can confirm that's the issue, as I fixed it locally. Does this affect Godot4 too? (I have no idea if it even applies).