BabylonJS WebVR Hello World

In a few weeks, we have our next WebXR NL meetup . This evening we are going to put a couple of WebVR frameworks head to head: A-Frame, ThreeJS, and BabylonJS. Since I happen to have some experience with BabylonJS it is upon me to explain how to work with WebVR in BabylonJS. This post will be the first part, “Hello World”.

Basics

For this tutorial I use StackBlitz, but any other online or offline editor will work. In my case, I started a new TypeScript project in StackBlitz. This will give you an HTML file, a TS file, and a CSS file. The HTML file is the simplest. This contains only 1 element in the body of the HTML file: the Canvas element. All renderings will go to this canvas.

The CSS file is pretty straightforward as well. It makes sure the canvas element will file the entire screen.

Packages

To get BabylonJS to work we need to install a few packages. Of course BabylonJS itself, this packages also includes the TypeScript definitions.

BabylonJS needs a couple of packages, which you don’t need right away, but may become handy in the future. However, if you don’t add them, Babylon will complain.

  • Oimo => JavaScript 3D Physics engine
  • Cannon => JavaScript 3D Physics engine
  • Earcut => JavaScript triangulation library

With StackBlitz it very easy and fast to install them. Just enter the name in the ‘enter package name’. If you miss one StackBlitz will offer to install the missing package.

Main Class

I started by clearing the index.ts file with the exception of the import of the styles. I’ve added the import for BabylonJS as well. This will make sure the library is loaded and you can use it.

We need a TypeScript class for our app to run, I named it VRApp. Add an empty constructor and a function named ‘run()’. This is the basic outline of the class. After creating the class, instantiate it and call the run function.

Babylon works by having an Engine, that talks to the lower-level WebGL. You also need one or more BabylonJS Scenes. The Scene contains, for example, the geometry, lights, and camera that needs to be rendered. I created 2 private fields for these because there need to be available from different places in the class.

The engine itself is instantiated in the constructor of the VRApp class. You need to pass 2 parameters to the constructor of the BabylonJS Engine: a reference to the canvas and a bool to turn the antialiasing on. After that, we can instantiate a scene and pass it the engine. Right now, your code should like something like:

Next, we need to add a few things to the scene to render. We need a light to illuminate the scene. The first light I often create is a hemispheric light. This light has a direction. This is not the direction of the light itself, but the reflection of the light. The hemispheric light is used to create some ambient lighting in your scene. For ambient lighting in combination with other lights, you often point this up. In this case, I kept it at an angle to get some shading going.

Lighting alone won’t do anything. We need some geometry. For the ground, I create a Ground Mesh. This plane is optimized for the ground and can be used in more advanced scenarios like octrees if you wish in the future.

The rest of the scene will be made from a couple of cubes randomly scattered around. I created a simple for-loop in which I create a cube mesh and change its position to a random value.

Almost there. We need two more things. We need an implementation of the run function of the VRApp class. In this function, I provide the BabylonJS Engine I created in the beginning with a render loop. This function we provide to the engine is called every frame and is responsible for rendering the scene. This function can do more and probably will do more in the future, but for now, it only calls the render function of the scene.

At this point, you should see an error when running the application using StackBlitz.

<!-- raw HTML omitted -->

And the error is correct. We didn’t create a camera. In a ‘normal’ WebGL application you need to create a camera, and you can do that in our case as well. But you don’t have to. Creating a WebVR project from a WebGL project takes some effort: You need to configure everything; And render a special camera. To make it as easy as possible BabylonJS has a special method that creates all of these for you and converts your application to WebVR, createDefaultVRExperience. The function creates a default VRExperienceObject. This helper will add the VR-button to the UI, checks if WebVR is available and by default creates (or replaces) the device orientation camera for you. I’ve added the following to the end of the constructor of the VRApp class:

Result

The result of the tutorial should look something like this, the full code is in here as well:

You can open this code on StackBlitz and play with it yourself. Of course, there’s much more you can do with WebVR, but this is it for this tutorial. If you have any question feel free to add a comment or come to our meetup on the 12th of June in Eindhoven, The Netherlands.