MozillaReality / unity-webxr-export

INACTIVE - Assets for creating WebXR-enabled Unity3D projects.
https://mixedreality.mozilla.org/unity-webxr-export/Build/
Apache License 2.0
626 stars 127 forks source link

All Black Rendering when using Metachromium Browser #377

Closed JaredMonkey closed 4 years ago

JaredMonkey commented 4 years ago

I tried to use Metachromium ( https://webaverse.com/guides.html http://metachromium.com/ ) with SteamVR to run the example located at https://mixedreality.mozilla.org/unity-webxr-export/Build/

And I see all black in the headset when I enter XR.

image

image

avaer commented 4 years ago

What does this look like in Chrome?

joshmarinacci commented 4 years ago

Does this special browser support the WebXR api?

avaer commented 4 years ago

Yes it does, it is a fork of Chromium that runs other WebXR apps fine.

fernandojsg commented 4 years ago

@JaredMonkey can you paste the console output? I can see something at the top of the console is throwing an error but cant guess what.

avaer commented 4 years ago

I got it working but it required a framebuffer change, it looks like it's rendering to the default framebuffer instead of the WebXR one.

I hacked it to use the correct webxr framebuffer for rendering and that did the trick.

Any chance for an upstream fix?

XRManager.prototype.setGameInstance = function (gameInstance) {
    if (!this.gameInstance) {
      this.gameInstance = gameInstance;
      this.canvas = this.gameInstance.Module.canvas;
      this.resize();

      var thisXRMananger = this;

      this.ctx = this.gameInstance.Module.ctx;
      // XXX THIS
      this.ctx.bindFramebuffer = (oldBindFramebuffer => function bindFramebuffer(target, fbo) {
        if (!fbo && thisXRMananger.vrSession && thisXRMananger.vrSession.renderState.baseLayer) {
          fbo = thisXRMananger.vrSession.renderState.baseLayer.framebuffer;
          console.log('replaced', fbo);
        }

        return oldBindFramebuffer.call(this, target, fbo);
      })(this.ctx.bindFramebuffer);
avaer commented 4 years ago
card

The errors and framebuffer switch requirement are related to jumping from inline session to immersive-vr. Inline sessions cannot get the reference space so unity throws an alert, which is why inline sessions are disabled in my unity-webxr-export fork.

But hopping from inline session to immersive-vr is why the default framebuffer can apparently be used for webxr rendering in this exporter. Without hopping from inline to immersive-vr session we need to actually bind the correct webxr framebuffer per immersive-vr session flow, hence the part where we hijack the re-bind in my fork from the canvas framebuffer to the webxr one.

Here are the interesting parts of my fork: https://github.com/avaer/unity-webxr-export/pull/1/files#diff-2a8ccf63bdff1a93f74c420f7c0efab1L138

De-Panther commented 4 years ago

I think that the issue is that we use a style that stretch the canvas, and every frame we need to set the canvas size to the buffer size

this.canvas.width = glLayer.framebufferWidth;
this.canvas.height = glLayer.framebufferHeight;

My guess is that it somehow detach the FrameBuffer. We can remove the style size 100% from the canvas, and instead register to the resize event of the parent DOM Element. That might also solve the issue with Cardboard support.

But even after we'll solve this issue, there's the error of the inline session. https://www.w3.org/TR/webxr/#xrsessionmode-enum "A session mode of inline indicates that the session’s output will be shown as an element in the HTML document. inline session content MUST be displayed in mono (i.e., with a single view). It MAY allow for viewer tracking. User agents MUST allow inline sessions to be created."

We can check if inline session is supported when we check for the immersive sessions. And with that we can return the xrCompatible setting to when we detect compatible device.

@avaer Chrome 81 on desktop already supports inline session when using WebXR(define the headset in chrome flags and run using "--no-sandbox --test-type"), and it doesn't have the "decode audio" issue we see in the screenshot. Consider updating the Chromium source for Metassium.

Good catch regarding the sourcePose check.