Other VR displays

For the case of the other VR displays, like Samsung Gear VR and HTC Vive, they normally have the browsers in it, and that browser does matter for choosing WebVR / WebXR API. You can check the browsers that support WebVR API at webvr.rocks#browsers.

What about WebXR? According to MDN, Android Chrome after version 79 is the only browser that supports WebXR API at the moment. But I’ve found out that Oculus browser 7.0 and later also support WebXR by default (Link).

That means, when you choose to use only WebXR API, you can cover all the Android devices with Chrome, Samsung Gear VR, and Google Daydream. And with polyfill, iOS with Google Cardboard can be handled also.

If you want more browsers to be covered, like Firefox Reality, you can consider using the WebVR API. But be sure that many browsers may remove support for the WebVR API soon.

For a hint, three.js removed WebVR support at r112 and using only WebXR API from that point, while A-Frame still supports WebVR (it also has a dependency on webvr-polyfill).

Browser compatibility

If you’re supporting only the Chrome browser, things might be better. But if not, you have to consider a few things more.

One is device motion calibration. You can see that if you check A-Frame’s Hello WebVR demo in Android Samsung Browser, everything is on your backside after you enter VR. Also, Chrome’s native WebXR makes sure that you always see the front, which is -z direction of your scene whenever you enter VR, but that isn’t guaranteed in any other browsers.

So, if you don’t want browsers to do their own thing but if you want some consistent behavior, you have to calibrate the matrix value you got from WebVR / WebXR API. As this problem is dedicated to the yaw, which is y-axis rotation, you can add some offsets to it to settle this issue. Basically, grab the first matrix value from the API, and make sure that the front. If not, add some yaw values to make it look front. See below gist for implementation.

Full source at: Link

Don’t be confused by how it first uses (0, 0, 1) as camera direction and compares it to (0, 0, -1). The first vector (0, 0, 1) is in camera space and (0, 0, -1) is in object space.

iOS compatibility

Okay, here’s another hard part. Unfortunately, iOS can’t show VR content properly, even in the Chrome browser. The main issue is that they don’t provide native Fullscreen API and they’ve disabled permission for a device motion after iOS 12.2.

For Fullscreen API, the polyfill, either webvr or webxr, provides a good remedy for it by making canvas size fit viewport size. But, the address bar still appears and the user must scroll to get rid of it. And as iOS also lacks an orientation locking method, it really is almost impossible to show VR content on the web smoothly and properly at the moment.

For device motion permission, it was totally user-dependent until version 13. So the developers should show some modals like below.

Users had to enable motion & orientation by themselves until iOS13

With the arrival of iOS 13, permission querying is now possible. It still needs to be triggered by user action like click, but least you can grant permission programmatically. You can do such as below.

Polyfills

You might have to consider polyfills as iOS and Android except for Chrome lacks support for the VR. There’re some things you have to consider when using polyfills.

WebVR vs WebXR

Suppose you’re supporting both APIs, you might wonder which polyfill you have to use. WebXR API is definitely a more recent one, but webvr-polyfill has an advantage that it has a smaller file size.

I think webxr-polyfill is better, even if you ain’t use the AR feature. When it comes to controllers, WebXR has better XRInputSource API while WebVR has to use the Gamepad API. Needless to say that webxr-polyfill is more actively maintained.

Viewer parameters

Normally, viewers like HTC Vive or Samsung Gear VR have their own properties inside. So basically we don’t have to consider that anyway after we submit our WebGL frame rendered.

But in the case of Google Cardboard, you have to consider that. There’re really lots of vendors that provide their own cardboards with different properties like FOV, distortion coefficient. To support those custom properties, normally there’s QR code containing property values at the bottom of the cardboard.

If you open Android Chrome version 79+ and enter any WebXR enabled page, you can notice that it has a nice native selector and QR code reader for choosing cardboard display parameters.