https://github.com/immersive-web/cardboard-vr-display
A JavaScript implementation of a WebVR 1.1 VRDisplay
https://github.com/immersive-web/cardboard-vr-display
cardboard polyfill virtualreality vr vrdisplay webvr
Last synced: about 1 year ago
JSON representation
A JavaScript implementation of a WebVR 1.1 VRDisplay
- Host: GitHub
- URL: https://github.com/immersive-web/cardboard-vr-display
- Owner: immersive-web
- License: apache-2.0
- Created: 2017-10-12T22:35:23.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2021-05-06T20:53:28.000Z (about 5 years ago)
- Last Synced: 2025-03-29T17:12:04.495Z (about 1 year ago)
- Topics: cardboard, polyfill, virtualreality, vr, vrdisplay, webvr
- Language: JavaScript
- Homepage: https://immersive-web.github.io/cardboard-vr-display
- Size: 12.5 MB
- Stars: 93
- Watchers: 54
- Forks: 43
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cardboard-vr-display
[](https://travis-ci.org/immersive-web/cardboard-vr-display)
[](https://www.npmjs.org/package/cardboard-vr-display)
A JavaScript implementation of a [WebVR 1.1 VRDisplay][VRDisplay]. This is the magic
behind rendering distorted stereoscopic views for browsers that do not support the [WebVR API]
with the [webvr-polyfill].
Unless you're building a WebVR wrapper, you probably want to use [webvr-polyfill] directly
rather than this. This component **does not** polyfill interfaces like `VRFrameData` and
`navigator.getVRDisplays`, and up to the consumer, although trivial (see examples).
## How It Works
As of [1.0.4](https://github.com/immersive-web/cardboard-vr-display/tree/v1.0.4), `CardboardVRDisplay` uses [RelativeOrientationSensor] for orientation tracking,
falling back to [DeviceMotionEvents] using [sensor fusion and pose prediction][fusion].
[RelativeOrientationSensor] is a new API ([read more about the new Sensors on the web][sensors])
first implemented in Chrome M63. This API uses the new [Feature Policy] specification which allows
developers to selectively enable or disable browser features.
It can also render in stereo mode, and includes mesh-based
lens distortion. This display also includes user interface elements in VR mode
to make the VR experience more intuitive, including:
* A gear icon to select your VR viewer.
* A back button to exit VR mode.
* An interstitial which only appears in portrait orientation, requesting you switch
into landscape orientation (if [orientation lock][ol] is not available).
### iframes
By default, main frames and same-origin iframes have access to Sensor APIs,
but cross-origin iframes must specify feature policy and allow `gyroscope` and
`accelerometer` features. If your experience is attempting to use the native
[WebXR Device API] in an iframe, you'll have to specify that feature as well ([WebXR's
feature name may change](https://github.com/immersive-web/webxr/issues/308)). All of these features require HTTPS to function, except for `localhost`, where HTTP is allowed.
```html
```
While `devicemotion` is a fallback for Sensors, eventually `devicemotion` will be behind the same
Feature Policy as Sensors and it is encouraged to adhere to these policies in the meantime.
If the Feature Policy for Sensors is denied, `CardboardVRDisplay` will **not** always attempt
to fall back to `devicemotion`. Using Feature Policies now will guarantee a more future-proof experience.
#### Caveats
* On iOS, cross-origin iframes do not have access to the `devicemotion` events.
The `CardboardVRDisplay` however does respond to events passed in from a parent
frame via `postMessage`. See the [iframe example][iframe-example] to see how
the events must be formatted.
* Chrome M63 supports Sensors, although not the corresponding Feature Policy [until Chrome M65][sensors-main-frame].
This results in Chrome M63/M64 only supporting Sensors in main frames, and these browsers
will fall back to using devicemotion if in iframes.
* Using Sensors in a cross-origin iframe [requires the frame to be in focus](https://www.w3.org/TR/generic-sensor/#focused-area). In builds of Chrome prior to M69, this logic is [erroneously reversed](https://bugs.chromium.org/p/chromium/issues/detail?id=849501). If loading content via cross-origin iframe, you can disable Sensors, triggering the `devicemotion` fallback with this [hacky workaround](https://github.com/immersive-web/cardboard-vr-display/blob/c196e15a8c7ccf594fe6a5044fbdcb51cc2eff91/examples/index.html#L117-L124). More info in [#27](https://github.com/immersive-web/cardboard-vr-display/issues/27).
### Magic Window
It is possible to have a magic window using a VRDisplay that isn't 100% width/height of the window, and can jump into fullscreen WebVR. See the [magic window][magicwindow-example] for usage.
## Installation
```
$ npm install --save cardboard-vr-display
```
## Browser Support
Should support most modern browsers (IE11 is missing a few, for example) and requires [ES5](https://kangax.github.io/compat-table/es5/) JavaScript support. If you want to support a non-ES5 browser, or browser lacking some DOM globals, you must use a transformation or provide polyfills to support older environments.
Globals required:
* [`Promise`](https://caniuse.com/#feat=promises)
* [`CustomEvent`](https://caniuse.com/#feat=customevent)
* [`requestAnimationFrame`](https://caniuse.com/#feat=requestanimationframe)
Additionally, WebGL support, [`devicemotion`](https://caniuse.com/#feat=deviceorientation) events, and common browser globals (`window`, `navigator`, `document`) are also required in the environment.
## Usage
`cardboard-vr-display` exposes a constructor for a `CardboardVRDisplay` that takes
a single options configuration, detailed below. Check out [running the demo](#running-the-demo)
to try the different options.
```js
import CardboardVRDisplay from 'cardboard-vr-display';
// Default options
const options = {
// Optionally inject custom Viewer parameters as an option. Each item
// in the array must be an object with the following properties; here is
// an example of the built in CardboardV2 viewer:
//
// {
// id: 'CardboardV2',
// label: 'Cardboard I/O 2015',
// fov: 60,
// interLensDistance: 0.064,
// baselineLensDistance: 0.035,
// screenLensDistance: 0.039,
// distortionCoefficients: [0.34, 0.55],
// inverseCoefficients: [-0.33836704, -0.18162185, 0.862655, -1.2462051,
// 1.0560602, -0.58208317, 0.21609078, -0.05444823, 0.009177956,
// -9.904169E-4, 6.183535E-5, -1.6981803E-6]
// }
// Added in 1.0.12.
ADDITIONAL_VIEWERS: [],
// Select the viewer by ID. If unspecified, defaults to 'CardboardV1'.
// Added in 1.0.12.
DEFAULT_VIEWER: '',
// By default, on mobile, a wakelock is necessary to prevent the device's screen
// from turning off without user input. Disable if you're keeping the screen awake through
// other means on mobile. A wakelock is never used on desktop.
// Added in 1.0.3.
MOBILE_WAKE_LOCK: true,
// Whether or not CardboardVRDisplay is in debug mode. Logs extra
// messages. Added in 1.0.2.
DEBUG: false,
// The URL to JSON of DPDB information. By default, uses the data
// from https://github.com/WebVRRocks/webvr-polyfill-dpdb; if left
// falsy, then no attempt is made.
// Added in 1.0.1
DPDB_URL: 'https://dpdb.webvr.rocks/dpdb.json',
// Complementary filter coefficient. 0 for accelerometer, 1 for gyro.
K_FILTER: 0.98,
// How far into the future to predict during fast motion (in seconds).
PREDICTION_TIME_S: 0.040,
// Flag to disabled the UI in VR Mode.
CARDBOARD_UI_DISABLED: false,
// Flag to disable the instructions to rotate your device.
ROTATE_INSTRUCTIONS_DISABLED: false,
// Enable yaw panning only, disabling roll and pitch. This can be useful
// for panoramas with nothing interesting above or below.
YAW_ONLY: false,
// Scales the recommended buffer size reported by WebVR, which can improve
// performance.
// UPDATE(2016-05-03): Setting this to 0.5 by default since 1.0 does not
// perform well on many mobile devices.
BUFFER_SCALE: 0.5,
// Allow VRDisplay.submitFrame to change gl bindings, which is more
// efficient if the application code will re-bind its resources on the
// next frame anyway. This has been seen to cause rendering glitches with
// THREE.js.
// Dirty bindings include: gl.FRAMEBUFFER_BINDING, gl.CURRENT_PROGRAM,
// gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING,
// and gl.TEXTURE_BINDING_2D for texture unit 0.
DIRTY_SUBMIT_FRAME_BINDINGS: false,
};
const display = new CardboardVRDisplay(options);
function MockVRFrameData () {
this.leftViewMatrix = new Float32Array(16);
this.rightViewMatrix = new Float32Array(16);
this.leftProjectionMatrix = new Float32Array(16);
this.rightProjectionMatrix = new Float32Array(16);
this.pose = null;
};
const frame = new (window.VRFrameData || MockVRFrameData)();
display.isConnected; // true
display.getFrameData(frame);
frame.rightViewMatrix; // Float32Array
frame.pose; // { orientation, position }
```
## Development
* `npm install`: installs the dependencies.
* `npm run build`: builds the distributable.
* `npm run watch`: watches `src/` for changes and rebuilds on change.
### Releasing a new version
For maintainers only, to cut a new release for npm, use the [npm version] command. The `preversion`, `version` and `postversion` npm scripts will run tests, build, add built files and tag to git, push to github, and publish the new npm version.
`npm version `
## Running The Demo
View the [example] to see a demo running the CardboardVRDisplay. This executes
a minimal WebVR 1.1 polyfill and parses query params to inject configuration parameters.
View some premade links at [index.html]. For example, to set the buffer scale to 1.0
and limit rotation to yaw, go to [https://immersive-web.github.io/cardboard-vr-display/examples/index.html?YAW_ONLY=true&BUFFER_SCALE=1.0].
View all config options at `src/options.js`.
## License
This program is free software for both commercial and non-commercial use,
distributed under the [Apache 2.0 License](LICENSE).
[VRDisplay]: https://immersive-web.github.io/webvr/spec/1.1/#interface-vrdisplay
[WebVR API]: https://immersive-web.github.io/webvr/spec/1.1/
[WebXR Device API]: https://immersive-web.github.io/webxr/spec/latest/
[webvr-polyfill]: https://github.com/immersive-web/webvr-polyfill
[example]: https://immersive-web.github.io/cardboard-vr-display/examples
[iframe-example]: examples/iframe.html
[magicwindow-example]: examples/magicwindow.html
[index.html]: https://immersive-web.github.io/cardboard-vr-display
[fusion]: http://smus.com/sensor-fusion-prediction-webvr/
[ol]: https://www.w3.org/TR/screen-orientation/
[sensors]: https://developers.google.com/web/updates/2017/09/sensors-for-the-web
[DeviceMotionEvents]: https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent
[RelativeOrientationSensor]: https://www.w3.org/TR/orientation-sensor/#relativeorientationsensor-model
[Feature Policy]: https://wicg.github.io/feature-policy/
[sensors-main-frame]: https://developers.google.com/web/updates/2017/09/sensors-for-the-web#feature_policy_integration