Three.js: Android Chrome Dev supports WebVr v1.0 however presenting causes a promise error.

Created on 28 Jul 2016  路  15Comments  路  Source: mrdoob/three.js

Samsung S3 Android 4.3 Chrome Dev.

1) the video vr example http://threejs.org/examples/#webvr_video
2) Click Enter VR
3) Presenting triggers an error. Should it fallback to sending the canvas fullscreen here for cardboard device view ? In WebVR 1.0 it tries to use the new API for presenting to displays.

VREffect.js:221 Uncaught (in promise) DOMException: VRDisplay cannot present

Most helpful comment

I've reverted back to a few commits back, the refactor of the original CardboardEffect is actually broken.

The entire boiler plate and polyfill thing is bloaty and poorly scripted. It would be easier if it was a function part of the examples at least that can be imported directly.

I will try to import the distorter somehow directly into my Es6 project but it might be hard to implement and it uses raw functions. I can see what it's trying to do with the vertex distortion in a shader program although uses device specific data.

The mesh distortion is working again for now as stereo, it was only displaying on the left.

I've reverted back to the VrEffect at is keeps getting refactors. But do display checks duplicated outside of it so I can dispatch when displays are available and it can present. You have no idea when it has obtained displays, as in no events that is all.

I guess we should close this and Android might have native distortion working when WebVr is enabled by default.

All 15 comments

The display capabilities claims it can't present. So that is possibly a way to check ?

VRDisplay {
displayId: 1, 
displayName: "Google, Inc. Cardboard v1", 
isConnected: true, 
isPresenting: false, 
capabilities: {
    canPresent: false,
    hasExternalDisplay: false,
    hasOrientation: true,
    hasPosition: false,
   maxLayers: 0
},
stageParameters: null
}

See this ticket also. I'm not sure if anything can be done if Cardboard mode support has been dropped in Chrome anyway. The stable versions of Chrome and Firefox don't support WebVR 1.0 yet so use the canvas fullscreen mode.

There may be a requirement to check for the "canPresent" capability. On toji's demos there is a check and if its false the presentation button won't be enabled.

https://github.com/toji/webvr-samples/issues/32

According to the current implementation in Chrome Dev it can't present the Canvas like non WebVR 1.0 mode.

It has to use StereoEffect / CardboardEffect. It can still use VrControls however, the pose data is still fine there.

So either internally or externally check for "canPresent" on the VrDisplay or the presenting error will be returned in the promise

effect.isPresenting ? effect.exitPresent() : effect.requestPresent().then(function(display) {
                console.log("PRESENTING SUCCESS", display);
            }, function(error) {
                console.log("PRESENTING FAILED", error);
            });

I tried to fudge it to make it not WebVr1 capable but it breaks here when triggering fullscreen. This is not part of that spec.

eyeWidth = eyeParamsL.renderRect.width;
eyeHeight = eyeParamsL.renderRect.height;

It may change again and be able to present in some kind of Cardboard capable mode like sending the Canvas fullscreen instead. But not sure yet.

/ping @toji

I'm working on implementing presentation on Android, it's just been a bumpy road as we've worked on the transition to GoogleVR from the Cardboard SDK. Hoping to get something more useable out soon.

Code using WebVR should definitely plan on cases where canPresent is false, though. If/when we get it working on Tango devices I expect that will be the case, because you can get great 6DoF positions out of them but it's unlikely that you'll be using it in a headset.

Yes confirming that not a problem. I've implemented something for now to send events and toggle VR support if it can't present, it will hide the button with css.

I notice in your demos it won't add the VR button if it can't present.

I haven't managed yet to work on a fallback feature but it could use a Cardboard/Stereo effect and orientation controls for now like on IOS.

I checked webvr polyfill and it also suffers the same problem. It doesn't even support the depreciated api which is currently in Firefox / Chrome stable.

So in this case, in WebVR 1.0

effect.getVRDisplay().capabilities.canPresent

Is useful for detecting support.

I don't have access to a proper headset yet but I'm curious which event could be used for detecting that a display is connected or the displays have been updated after the page has loaded rather than beforehand ?

I have to set a timeout currently to wait for the display list then send an event.

There is interesting vr headset connected events though. Perhaps the VREffect needs this also for obtaining displays after page load.

window.addEventListener("vrdisplayconnected", this.onVREvent.bind(this), false);
window.addEventListener("vrdisplaydisconnected", this.onVREvent.bind(this), false);
window.addEventListener("vrdisplayactivated", this.onVREvent.bind(this), false);
window.addEventListener("vrdisplaydeactivated", this.onVREvent.bind(this), false);

Shall we close this for now or leave it up for information ?

Since Android Chrome 52.0.2743.91 WebVR 1.0 is now existent although not enabled by default. Firefox is still using the deprecated api so unaffected.

Confirming falling back to a cardboard / stereoeffect. After checking if the current display cannot present works around this for now.

@danrossi are you still using VREffect.js? I'm seeing this issue as canPresent is returning false on the capabilities of the VRDisplay, but this is not being tested against. isWebVR1 is hardcoded to true at the top of the file so it never falls through to attempt to use the requestFullScreen fallback.

@baseten I've had to do a dodgy work around. Because there is no event to alert availability of display lists I've had to set a timeout. It's here I check for if it can present and I have to also check externally for WebVR. Both of these could be placed into a second callback within VrEffect.

ie something like this might work

for ( var i = 0; i < displays.length; i ++ ) {

            if ( 'VRDisplay' in window && displays[ i ] instanceof VRDisplay ) {

                vrDisplay = displays[ i ];
                isWebVR1 = true;
                                canPresent = vrDisplay.capabilities.canPresent;
                break; // We keep the first we encounter

            } else if ( 'HMDVRDevice' in window && displays[ i ] instanceof HMDVRDevice ) {

                vrDisplay = displays[ i ];
                isWebVR1 = false;
                                canPresent = true;
                break; // We keep the first we encounter

            }

        }

        if ( vrDisplay === undefined || !canPresent ) {

            if ( onError ) onError( 'HMD not available' );

        }

                onDisplaysAvailable(vrDisplay, isWebVR1);

Within my setup I am doing something like this but not exactly.

this.effect = new THREE.VREffect(this.renderer, this.container, function() {
       if (this.distortion) {
        this.effect = new THREE.CardboardEffect(this.renderer);
    } else {
        this.effect = new THREE.StereoEffect(this.renderer);
    }
});

Then within a present error my feature is sending it will also fallback to the cardboard or stereoeffect.

I choose to try and use the raw functions directly. no bloaty polyfill which doesn't support non WebVR1 anyway although they have a much more advanced mobile orientation control.

If that seems good I might make a pull request ?

I prefer to use and subclass the event dispatcher that is already there though not callback methods.

I've done some extensive testing after making some changes required and it seems to be all fine. I've added a PR with the required event changes. It will detect if the display is presentable.

On the Windows browsers there is no display at all returned. So an event has been made for this.

On Android Firefox it's still non WebVR 1 so WebVR can be used. In Chrome Stable and Dev on Android it is WebVR1 and will detect the Cardboard display is not presentable.

Within the present event some fallback code can be placed.

@baseten my code changes above were not accepted.

But I have created a ported version here as a three.js module. I have also cleaned up the duplicated code. I've moved utils maths stuff out into static method and the non WebVR 1 fullscreen management also into an external "polyfill" utils function.

You can't fallback to fullscreen canvas for WebVR 1 as far as I can understand. The api changed ? The events are there to determine what to do next as far as UI is concerned.

It should be easier to read what it is doing now.

I haven't completed with a readme and moving over the original header comments where required into the maths utils part.

https://github.com/danrossi/three-vreffect

There is still no presenting support in webvr in Chrome on Android, no native distortion either.

It would be nice to have CardboardEffect added back in as a fallback for now until WebVR is enabled by default. I think it was removed prematurely ?

I've noticed some of the others have turned back to a shader program rather than modifying the mesh. But there is very bloaty lines of code to change params for each device.

Is this old cardboard effect code still valid ? The last recent change is now only rendering in one side.

It would be nice to have CardboardEffect added back in as a fallback for now until WebVR is enabled by default. I think it was removed prematurely ?

You may want to use https://github.com/borismus/webvr-boilerplate instead?

I've reverted back to a few commits back, the refactor of the original CardboardEffect is actually broken.

The entire boiler plate and polyfill thing is bloaty and poorly scripted. It would be easier if it was a function part of the examples at least that can be imported directly.

I will try to import the distorter somehow directly into my Es6 project but it might be hard to implement and it uses raw functions. I can see what it's trying to do with the vertex distortion in a shader program although uses device specific data.

The mesh distortion is working again for now as stereo, it was only displaying on the left.

I've reverted back to the VrEffect at is keeps getting refactors. But do display checks duplicated outside of it so I can dispatch when displays are available and it can present. You have no idea when it has obtained displays, as in no events that is all.

I guess we should close this and Android might have native distortion working when WebVr is enabled by default.

I'm seeing the same issue with displayName : ARCore VR Device on a Google Pixel with DayDream. This worked just a couple days ago, so I'm not sure what happened.

Was this page helpful?
0 / 5 - 0 ratings