GodotVR / godot_openvr

GDNative based Open VR module
MIT License
226 stars 34 forks source link

Switching between viewports causes strange behavior with ARVRInterface's initialize / uninitialize #66

Open kb173 opened 4 years ago

kb173 commented 4 years ago

We have two viewports on the screen in our game, with the ability to instance different player scenes into each of them. A VR player can be instanced into one of the viewports, which then makes it render a mirror of what the VR player sees.

This works fine when instancing the VR player into a viewport once. However, when I delete the VR player and instance a normal PC player into that viewport, the viewport remains stretched. Of course, I set arvr to false on that viewport when deleting the VR player, and I've also tried calling Viewport.set_size_override(false) and setting the viewport size to what it was before. Nothing helped... It seems like initializing the viewport does something unexpected to the viewport it's rendering to.

I have also experienced some strange FPS drops when often initializing and uninitializing the interface into different viewports.

Also, sometimes uninitializing the interface crashes the game with drivers/unix/net_socket_posix.cpp:190 - Socket error: 10054. This seems to be related with a heavy workload (low FPS) while uninitializing, but I'm not 100% sure.

This is happening on a machine with Windows 10, a GTX 2060 and an Oculus Rift, using Godot 3.1.1 with the build from https://github.com/GodotVR/godot-openvr-asset.

BastiaanOlij commented 4 years ago

Sorry for the very very late reply.

The viewport not returning to a normal viewport after ARVR is turned off sounds like an issue in Godot itself, it is supposed to adjust the size and everything automatically.

What do you mean by uninitialising and re-initialising? If you uninitialise the interface that shuts down openvr completely and is very wasteful. Or do you simply mean switching which viewport is set as the ARVR viewport?

You can't have more then one viewport set as the ARVR viewport at any given time so if removing the ARVR status on a viewport is causing issues that might result in problems.

kb173 commented 4 years ago

No worries!

Make sense - I'll report the viewport size issue to Godot.

I can see how it's wasteful, but I think it might still be sensible in our case: Our program is usually controlled traditionally with mouse and keyboard, VR is only turned on sometimes to view the landscape from VR. It's plausible to have long times between that where VR is turned off, so that's where we'd want to uninitialize the interface. Or should we leave the interface initialized and only remove all VR nodes and ARVR viewports?

If I recall correctly, uninitializing and initializing could actually drop the FPS permanently, and there was also the crash mentioned above that happened sometimes when calling uninitialize. Would a small example project be of use, or is uninitializing not really something we should do anyways?

milmarg commented 1 year ago

Hi. have you found any solutions? I'm having same issue. After switching arvr to false image gets distorted/stretched... :(

kb173 commented 1 year ago

@milmarg Unfortunately not... also, it seems like OpenXR in Godot 4.0 assumes even more strongly that VR is either consistently enabled since startup or consistently disabled (see https://docs.godotengine.org/en/latest/tutorials/xr/setting_up_xr.html#openxr). So it seems like the only workaround is to make a full restart for enabling/disabling VR as painless as possible (this is what we ended up doing).

AlnisS commented 3 months ago

I found a workaround: bumping the viewport's size around seems to fix it (desktop Windows, Android native, web). Running 3.5.1.

Here is my full exit vr method (verified working in 3.5.3 also):

func exit_vr():
    var interface = ARVRServer.find_interface("Native mobile")
    interface.uninitialize()
    get_viewport().arvr = false
    $"%Camera".current = true

    # hack to get 2D viewport to return to normal...
    var vs = get_viewport().size  # get the actual size
    get_viewport().size = vs - Vector2.ONE  # bump it (make something refresh?)
    get_viewport().size = vs  # restore it to the actual value

    vr_active = false