godotengine / godot

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

WebXR resulting in black screen on some platforms #53402

Closed Sch1nken closed 3 years ago

Sch1nken commented 3 years ago

Godot version

3.3.4.stable

System information

Android 10, Pico Neo 3, Firefox Reality 81.*, HTML5/WebXR

Issue description

When starting a WebXR Session that is exported by Godot, the HMD screen becomes black and nothing is happening (apart from controller tracking, not inputs are working). When trying various other WebXR demos online, this does not happen.

Using a PC HMD (Valve Index with SteamVR and Desktop Firefox in this case) the demo works as expected.

I've noticed that when I flick my HMD (and thus the "camera") quite fast while starting the VR session, the black screen becomes translucent in some parts and reveals the 3D scene. You can even see that the controllers are being tracked.

I have not been able to remotely debug the Firefox Reality App since it's apparently too old (Version 81.*).

https://user-images.githubusercontent.com/11414422/135902881-b5363926-094e-4dbc-ba8f-6f53e9b03c1b.mp4

Steps to reproduce

Minimal reproduction project

https://gitlab.com/snopek-games/toy-racer-xr

Sch1nken commented 3 years ago

I just tested with 3.4beta5. Same symptoms.

dsnopek commented 3 years ago

@Sch1nken Thanks for the report!

Does this happen for you with older versions, like Godot 3.3.1 for example? I just want to figure out if this is a regression, or if it's a problem we've always had with this particular platform (I don't know that anyone has tried a Pico Neo before).

One way to quickly test would be to try this version on my site:

https://bit.ly/godot-webxr-04

It's using a relatively old version (a pre-release of 3.3.0) but it would at least help to start answering this first question.

If you could get remote debugging working that would absolutely be the most useful thing! Unfortunately, I don't have a Pico Neo or even know anyone who has one, so it's hard to know where to start.

Thanks again! :-)

Sch1nken commented 3 years ago

I admit the Pico Neo devices are pretty niche in the western market (I got mine from directly from china because I don't want to use a Oculus Quest(2) for several reasons ;)).

The provided example shows the same black screen (and black spots when moving my head).

I'll see if I can build firefox reality for the pico neo (if there even is an open source project available). ADB did not help much with the issue, this seemed to be the only useful bit of information: InputMethodManager: b/117267690: Display ID mismatch found. ViewRootImpl displayId=15 InputMethodManager displayId=0. Use the right InputMethodManager instance to avoid performance overhead.: org.mozilla.vrbrowser

Though searching for InputMethodManager gives very few results (most of them being related to flutter and the on-screen keyboard on regular android devices).

If you have any further ideas regarding debugging just let me know so I can give them a try. What somehow works is OS.alert(). Is there a "catch all"-like construct in Godot? Or can I redirect stdout/stderr to maybe on-screen text?

dsnopek commented 3 years ago

Thanks for trying that!

If you have any further ideas regarding debugging just let me know so I can give them a try.

The only other idea that comes to mind right now is trying a simpler example. The Toy Racer XR project is pretty simple, but it supports both AR and VR, and can run also run natively on the Quest, etc, etc.

The project that gets created by following "Setting up the basics" section in my tutorial is pretty much the simplest thing that could possibly work. If you haven't tried that yet, I'd be interested to see if maybe that works, because maybe I'm just doing something weird in the Toy Racer demo.

Is there a "catch all"-like construct in Godot? Or can I redirect stdout/stderr to maybe on-screen text?

Not that I know of. The stdout/stderr from Godot goes into the browser console, which can be tricky to access on a standalone headset. Also, it'd be very useful to see not just Godot's output, but also any errors or exceptions from the browser, which would definitely only appear in the browser console.

I'll let you know if I have any other ideas for things to try...

Sch1nken commented 3 years ago

Thanks so far.

I'm onto doing a minimal test with your linked tutorial. Will report back.

Edit: Forgot to submit, but managed to remote debug using an older Firefox Developer release.

This is the console log from firefox reality. All these messages appeared before even "entering vr" though.


OpenGL ES 2.0 Renderer: Mozilla index.js:339:16
OpenGL ES Batching: ON index.js:339:16
 index.js:339:16
**ERROR**: No library set for this platform index.js:354:18
   At: modules/gdnative/gdnative.cpp:291:initialize() - No library set for this platform index.js:354:18
**ERROR**:  does not have a library for the current platform. index.js:354:18
   At: modules/gdnative/nativescript/nativescript.cpp:1459:init_library() - Condition "lib_path.length() == 0" is true. index.js:354:18
**ERROR**:  does not have a library for the current platform. index.js:354:18
   At: modules/gdnative/nativescript/nativescript.cpp:1459:init_library() - Condition "lib_path.length() == 0" is true. index.js:354:18
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
XRWebGLLayer doesn't support no alpha value. Alpha will be enabled. index.js:9:297605
XRWebGLLayer doesn't support separate depth or stencil buffers. They will be enabled together. index.js:9:297605
XRWebGLLayer antialiasing is not supported.Antialiasing will be disabled. index.js:9:297605```

Edit: I updated the log (since I had a stray OS.alert in there that threw extra errors).
dsnopek commented 3 years ago

This is the console log from firefox reality. All these messages appeared before even "entering vr" though.

Oh, awesome!

Which version of Toy Racer XR did those messages come from?

The first 3 errors are expected and harmless - they're due to the code for running the game natively on the Quest, and this is WebXR. :-)

But this one is possibly a clue:

**SCRIPT ERROR**: Invalid type in function 'alert' in base '_OS'. Cannot convert argument 1 from Nil to String. index.js:354:18
   At: res://autoload/VR.gdc:73:setup() - Invalid type in function 'alert' in base '_OS'. Cannot convert argument 1 from Nil to String. index.js:354:18

I want to try to relate that to an actual line in the source code. Looking at the most recent version of res://autoload/VR.gd, the only use of OS.alert() is in the callback for the 'session_failed' signal. But the error message makes me think it's trying to point to line 73, which seems unrelated, at least in the most recent version.

It might be worth trying the most recent version of the demo with this patch:

diff --git a/autoload/XR.gd b/autoload/XR.gd
index 86f922b..a3129a3 100644
--- a/autoload/XR.gd
+++ b/autoload/XR.gd
@@ -132,5 +132,7 @@ func _webxr_session_ended():
        emit_signal("webxr_session_ended")

 func _webxr_session_failed(message):
+       if message == null:
+               message = 'Unknown'
        OS.alert("Failed to initialize VR: " + str(message))
        emit_signal("webxr_session_ended")

That won't necessarily get it working, but maybe it could stop it failing catastrophically. :-)

Sch1nken commented 3 years ago

Ugh. This is awkward now. I didn't even check to see if there are any other branches than the master one.

It works without issues on the develop branch, without any changes at all.

So I guess this can be closed and was just some setup error in the master version?

PS: The alert was something I added (I edited my older post but probably too late for you to notice) to debug some lines.

Sch1nken commented 3 years ago

For completeness sake, this is the output of the working (develop branch) build:


OpenGL ES 2.0 Renderer: Mozilla index.js:339:16
OpenGL ES Batching: ON index.js:339:16
 index.js:339:16
**ERROR**: No library set for this platform index.js:354:18
   At: modules/gdnative/gdnative.cpp:291:initialize() - No library set for this platform index.js:354:18
**ERROR**:  does not have a library for the current platform. index.js:354:18
   At: modules/gdnative/nativescript/nativescript.cpp:1459:init_library() - Condition "lib_path.length() == 0" is true. index.js:354:18
**ERROR**:  does not have a library for the current platform. index.js:354:18
   At: modules/gdnative/nativescript/nativescript.cpp:1459:init_library() - Condition "lib_path.length() == 0" is true. index.js:354:18
**ERROR**: Cannot get path of node as it is not in a scene tree. index.js:354:18
   At: scene/main/node.cpp:1642:get_path() - Condition "!is_inside_tree()" is true. Returned: NodePath() index.js:354:18
**ERROR**: (Node not found: "Viewport" (relative to "").) index.js:354:18
   At: scene/main/node.cpp:1372:get_node() - Condition "!node" is true. Returned: 0L index.js:354:18
**ERROR**: ViewportTexture: Path to node is invalid. index.js:354:18
   At: scene/main/viewport.cpp:69:setup_local_to_scene() - Condition "!vpn" is true. index.js:354:18
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_X level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Y level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_POSITIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
WebGL warning: generateMipmap: Tex image TEXTURE_CUBE_MAP_NEGATIVE_Z level 0 is incurring lazy initialization. index.js:9:224479
XRWebGLLayer doesn't support no alpha value. Alpha will be enabled. index.js:9:297605
XRWebGLLayer doesn't support separate depth or stencil buffers. They will be enabled together. index.js:9:297605
XRWebGLLayer antialiasing is not supported.Antialiasing will be disabled. index.js:9:297605```
dsnopek commented 3 years ago

Ack, I guess I forgot that I hadn't merged the develop branch into master! I'm not sure why I was holding off. I just did it now, so there aren't any differences anymore, which will hopefully prevent any confusion in the future.

In any case, I'm really glad that it's working now! I'm also very happy that it was some bug in Toy Racer XR and not a problem in Godot's WebXR support. :-)

Also, I just downloaded Firefox Reality to my Oculus Quest 2, and when I opened an older version of Toy Racer XR it also gave a black screen! So, it appears the bug wasn't specific to the Pico Neo, but Firefox Reality (I have tested the desktop Firefox in the past, and it worked fine).

I have a suspicion that this is the commit that fixed it, but I haven't tested:

https://gitlab.com/snopek-games/toy-racer-xr/-/commit/8b0815eeeedb1072275c52248242a90923ac911f

This was a fix for AR in some situations, which manifested itself in a similar way: a sort of semi-translucent color would be overlaid on the viewport - but in this case, maybe it's just black covering the viewport?

Anyway, thanks for trying out WebXR and your persistence in working out the problem. :-) I'm going to close this issue now.

marc-weber1 commented 2 years ago

May need to reopen unless this is being fixed for the Godot 4 alpha, since I still have this issue on 3.4.2 stable: image

Calinou commented 2 years ago

@marc-weber1 Please upload a minimal reproduction project to make this easier to troubleshoot.

Also, please test this on 3.4.4 as only the latest patch release of a given minor release series receives support.

dsnopek commented 2 years ago

@marc-weber1 Assuming you're trying my Toy Racer XR demo, the errors you show are expected and harmless. That demo can also run natively on the Quest, and it's just failing to load the Oculus Mobile plugin.

The original issue here ended up being a bug on the demo's 'master' branch that got fixed in the 'develop' branch. Unless you can show that this is an issue in the WebXR support in Godot itself (ideally, with a minimal reproduce project like Calinou mentions above), it might be more appropriate to make an issue on the repo for the demo project: https://gitlab.com/snopek-games/toy-racer-xr

If you need more assistance, feel free to ping me on Discord or RocketChat!