Hello WebVR community!
The Chrome team has been a little quiet on the WebVR front recently, and I apologize for that and thank you for your patience. We’ve been heads down and working hard to deliver the best experience we can for developers as soon as we can. Several things have happened recently that will affect what we’re delivering and how. As such, we wanted to give developers an update.
First off, if you haven’t heard already, Microsoft has announced that they are working on WebVR support in Edge. This means that even wider support for WebVR apps across new and exciting hardware! It’s a huge deal for web developers, and reiterates the fact that the best way to reach the widest number of customers in VR will be via the web.
Microsoft also approached the WebVR community group with some very legitimate concerns about how their VR/AR platform would interact with the API as it exists today. Chief among these concerns was the fact that some hardware and APIs provide very carefully calibrated projection matrices for each eye per-frame that should be used for rendering. If those projection matrices are not used the scene may appear distorted or not align correctly with the real world, leading to user discomfort of varying degrees. Computing the projection matrix from the field of view as WebGL has done to date was simply not sufficient.
To address this concern and some others that were raised, as well as ensuring the API can evolve to encompass even more hardware features in the future, we’re making some changes to the WebVR spec prior to launch. I’ve been affectionately referring to this new version of the spec as “WebVR 1.1”, but in reality it’s just going to launch as “WebVR”. You can see the changes in the updated spec, but for those of you who would rather not analyse source diffs the TL;DR is:
- VRDisplay.getFrameData() has been added. It populates a VRFrameData object with a pose and left and right eye’s projection and view matrices. To ensure that content renders correctly on all WebVR-enabled platforms the projection matrices must be used directly and using the view matrices or transform based off of them is highly recommended.
- Your application will be responsible for allocating and providing the VRFrameData object. This allows you to more intelligently handle the object lifetime and avoid creating unnecessary garbage to collect.
- VRDisplay.getPose() and VREyeParameters.fieldOfView are now deprecated. They will stick around in Chrome’s implementation for a while after we ship so that existing content doesn’t break immediately, but they may also be left off of other browser’s implementations at their discretion. Apps should use getFrameData() (which includes the same pose that getPose returns) and the projection matrices it provides instead. If your app still needs the field of view it’s recommended that you derive it from the projection matrix. We’ll make sure the algorithms to do so are in an easy to reference location.
- VRDisplay.depthNear and VRDisplay.depthFar will now be used to compute the projection matrices returned by getFrameData(). Previously these field’s uses were vaguely defined (they were originally meant to support positional timewarp) but with this change they’ll become a much more important part of the API.
- VRDisplay.submitFrame() will no longer accept a pose. This was more of an aspirational feature than one that had a practical current use and caused a fair amount of confusion amongst developers. Since not all platforms can support it it’s best to not suggest that it’s available. WebVR will assume that all submitted frames were rendered with the data supplied in the last call to getFrameData(). (Which is how basically every WebVR app works already anyway.)
- VRDisplay.getImmediatePose() has been removed. I don’t think anyone actually used this outside of unit tests. In fact, I’ve already taken it out of the desktop experimental build and nobody seems to have noticed.
We realize that making any code updates for compatibility is a chore, and apologize for the inconvenience. I hope that you’ll agree, though, that wider hardware compatibility in the long term is definitely worth a bit of pain now, before the API has officially launched. We encourage developers to update your code and give us any feedback you have on the new structure of the API.
(I’m also personally curious to know how important compatibility with the previous API is to the community. Let me know if you have strong opinions on the subject!)
There’s actually a lot more than we want to do to expose even more features of the various VR platforms, but we’ve settled on the above changes to maximize compatibility while minimizing API churn. Rest assured we’ve got no shortage of ideas for an eventual WebVR 2.0!
We’ve got a whole pile of sample code and library updates to go along with the new spec changes.
- A migration guide is available to walk you through the basic steps needed to update your code.
- All of the WebVR Samples have been updated to demonstrate proper use of the new API.
- A shim library is available that “upgrades” implementations of the previous WebVR API to the new one, which should be handy while the browser catch up. (The WebVR samples are using it now.)
- Three.js has been updated with support for the new spec.
- The WebVR polyfill will be updated very soon to reflect the new API as well.
For what it’s worth, I found that I was able to update the WebVR samples in a few minutes apiece, and in many cases the resulting code was notably cleaner!
I definitely view these changes as a positive thing for the WebVR ecosystem, but they are also coming fairly late in the process, and as a result we’re seeing the need to change our plans regarding launching in Chrome to allow for the new API to “bake” for a bit. In short, we plan to make WebVR available first as an Origin Trial. If you’re not familiar with the concept, it’s a way for Chrome to make experimental APIs available by default on domains that include an experimental feature token in the header. The tokens are issued freely and automatically from a short sign up form, and all that’s expected from the origins that use it is to provide some feedback on the feature (bug reports, feature requests, etc.)
(If you’re not planning on putting WebVR content in front of users you’ll still be able to turn on WebVR without a token via about:flags for development or local testing.)
We feel this is the right call for WebVR in Chrome at this point because the new API changes have yet to be tested in the wild and we want to ensure the community has ample time to alert us to any shortcomings or oversights. At the same time we know that the community has been chomping at the bit to get WebVR more widely available. Starting as an Origin Trial gives us the best of both worlds by allowing early adopters to make WebVR content available by default on their sites without locking us into any spec guffaws that we might miss in a rush to push through API changes at the last second.
I’m still in the process of bringing up experimental builds with the new API, but I’ll be sure to let everyone know once they’re available!
One final thing that I’m eager to update the community about is Chrome’s policy when it comes to using WebVR on non-HTTPS domains. I need to apologize for this one, because after some initial miscommunication behind the scenes and a public, “Oh, hold on, we spoke too soon,” we left things in a state of limbo for over a month. I definitely could have done a better job of communicating while we worked out the details with Chrome’s security team. I simply wanted to ensure that whatever we said next on the subject was clear, accurate, and reliable. I’m sorry to leave you all hanging!
The good news is that we are going to stick with the policy that we announced last time: WebVR will be allowed on all HTTP domains with a persistent overlay to alert users to the non-secure origin. That includes HTTPS content embedded on HTTP domains. This policy is the result of careful consideration on the part of Chrome’s security team, and I’d like to thank them for their collaboration and patience while we forge paths into this new and uncharted territory for the Web.
From the last round of emails I know that there were several questions about the behavior and appearance of the security overlay. I’ve put together a simple demo to show the general direction that we’re leaning at this point. Try it with a WebVR experimental build on desktop or with any mobile device and Cardboard. It’s not meant to represent the final UX, we’ve still got some usability testing and refinement to do, but it should give you a decent idea of where we’re headed.
It’s worth noting that this policy does not mean that you don’t need to bother with HTTPS for your WebVR apps. Hosting your content on a secure origin should be considered a baseline requirement for anything that you intend to share with the web at large. What this policy enables is a simpler development cycle, learning curve, and troubleshooting process. Security is still critical, it can just be step 2 now instead of step 0 for new projects. Looking for resources on getting started with HTTPS? Check out Google Developer’s Security and Identity docs.
As HTTPS becomes more prevalent and frictionless, and as the development process on secure origins becomes even easier, the Chrome team does intend to continue to deprecate powerful APIs in non-secure contexts, and eventually may lean toward requiring HTTPS for all new APIs. We don’t have a timeline for deprecating WebVR specifically (might be years down the road) but please be aware that eventually APIs such as WebVR and Fullscreen may only be available over secure contexts.
So, as you can see we’ve been incredibly busy and aren’t slowing down any time soon! Thank you for being such an awesome community and for throwing so much of your incredible talent at an API that’s still undergoing some growing pains. Bringing VR to the web is just a teensy bit of a crazy endeavor, but the passion, skill, and creativity that we see from the community assures us that it will be well worth the effort!