Vladimir Vukićević

I Make Fun Stuff

Updated Firefox VR Builds

I’d like to announce the third Firefox Nightly build with experimental VR support. Download links:

This build includes a number of fixes to CSS VR rendering, as well as some API additions and changes:

  • Fixed CSS rendering (see below for more information)
  • Support for DK2 via 0.4.1 SDK (extended mode only)
  • Experimental auto-positioning on MacOS X — when going fullscreen, the window should move itself to the Rift automatically
  • hmd.setFieldOfView() now takes zNear and zFar arguments
  • New API call: hmd.getRecommendedEyeRenderRect() returns the suggested render dimensions for a given eye; useful for WebGL rendering (see below)

The DK2 Rift must be in Extended Desktop mode. You will also need to rotate the Rift’s display to landscape. If tracking doesn’t seem to be working, stop the Oculus service using the Configuration Tool first, then launch Firefox.

CSS Rendering

Many issues with CSS rendering were fixed in this release. As part of this, the coordinate space when in fullscreen VR is different than normal CSS. When in fullscreen VR mode, the 0,0,0 coordinate location refers to the center of the viewport (and not the top left as is regular in CSS). Additionally, the zNear/zFar values specified to setFieldOfView control the near and far clipping planes.

The coordinate units are also not rationalized with CSS coordinates. The browser applies a per-eye transform in meters (~ 0.032 meters left/right, or 3.2cm) before rendering the scene; tthus the coordinate space ends up being ~1px = ~1m in real space, which is not correct. This will be fixed in the next release.

Here’s a simple example of showing 4 CSS images on all sides around the viewer, along with some text. The source includes copious comments about what’s being done and why.

Known issues:

  • The Y axis is flipped in the resulting rendering. (Workaround: add a rotateZ() to the camera transform div)
  • The initial view doesn’t face the same direction as CSS (Workaround: add a rotateY() to the camera transform div)
  • Manual application of the HMD orientation/position is required.
  • Very large CSS elements (>1000px in width/height) may not be rendered properly
  • Units are not consistent when in VR mode


NOTE: This API will likely change (and become simpler) in the next release.

getRecommendedEyeRenderRect will return the rectangle into which each eye should be rendered, and the best resolution for the given field of view settings. To create an appropriately sized canvas, the size computation should be:

var leftRect = hmd.getRecommendedEyeRenderRect("left");
var rightRect = hmd.getRecommendedEyeRenderRect("right");
var width = leftRect.x + Math.max(leftRect.width + rightRect.x) + rightRect.width;
var height = Math.max(leftRect.y, rightRect.y) + Math.max(leftRect.height, leftRect.height);

In practice, leftRect.x will be 0, and the y coordinates will both be 0, so this can be simplified to:

var width = leftRect.width + rightRect.width;
var height = Math.max(leftRect.height, rightRect.height);

Each eye should be rendered into the leftRect and rightRect coordinates. This API will change in the next release to make it simpler to obtain the appropriate render sizes and viewports.

Comments and Issues

As before, issues are welcome via GitHub issues on my gecko-dev repo. Additionally, discussion is welcome on the web-vr-discuss mailing list.