Getting started with Babylon.js
Tags: webdev
Published: 2022-06-30 15:26:39

**Written by [Muyiwa Femi-Ige](https://blog.logrocket.com/author/muyiwafemiige/)✏️**

Building 3D graphics in a web browser has never been more straightforward. Join me on this journey as we show you how to create a basic scene using Babylon.js.

## Aim

This article aims to guide you on how to:

1.  Create a Vue component
2.  Create a Babylon class
3.  Render a scene on a canvas
4.  Create a 3D mesh

## Prerequisites

This article is a beginner-friendly tutorial as little hassle as possible. I would, however, suggest that you have a strong understanding of JavaScript to do this.

*   [Installations](#installations)
    *   [Installing Vue](#installing-vue)
    *   [Installing Babylon.js](#installing-babylonjs)
*   [Getting started](#getting-started)
    *   [Creating the Vue component (BabylonOne.vue)](#creating-vue-component)
    *   [Creating the Babylon class](#creating-babylon-class)
    *   [Rendering the scene in Vue](#rendering-scene-vue)
    *   [Modifying the CSS and adding a camera and hemispheric lighting](#modifying-the-css)
    *   [Explaining the code snippet](#explaining-code-snippet)

## Installations <name="installations">

### Installing Vue <name="installing-vue">

To begin, we will need Vue3 in our workspace. To do so, we type in the command below in our terminal:

```bash
npm install -g @vue/cli
```

(Note: you are required to have Node.js installed as you will need the node package manager as we move forward) 

Within the terminal, we use the command below to create a new project with the folder name **bb101**:

```bash
vue create bb101
```

After creating the project folder, we are prompted with a few choices to pick from. Do the following:

1.  First, we want to select the features we want manually, so we start by selecting that
2.  Then, we add TypeScript to the already present list of features we want
3.  Next, we select 3x (Vue 3) as the version of Vue.js to use in the project
4.  We select **No** as the response for the following two options by typing "n"
5.  We will go with the "ESLint with error prevention only" and "lint on save" as our additional lint feature for our linter
6.  To place the config for ESLint, we select the option "in dedicated config file" and select **No** for saving the preset for future projects

Now, we wait for a few moments to have these processes installed. Next, we change the directory in our terminal to that of the project we are working on using the command `cd bb101`, and we use `npm run serve` to run our Vue application. Once it compiles, we will have a localhost server to open in our browser. ![Localhost Server Compiled Example](https://blog.logrocket.com/wp-content/uploads/2022/06/localhost-server-compiled-example.png)

### Installing Babylon.js <a name="installing-babylonjs">

We need to install the Babylon package into our project. We will utilize several Babylon packages during this project, but for now, let’s start with the core package of Babylon. To do this, we use the following command in our terminal:

```bash
npm install @babylonjs/core
```

The command above will install babylon.js into the node module folder of our project. After the installation, we can proceed to the next step.

## Getting started <a name="getting-started">

### Creating the Vue component (BabylonOne.vue) <a name="creating-vue-component">

We begin by modifying the default helloworld.vue file in the component folder. We want to reuse the component but with the name BabylonOne rather than HelloWorld. 

In our newly named BabylonOne.vue file, we will clear out the default content in our HTML section (everything within the starting and closing div) and make a little change to the both the HTML section and script tag’s section by replacing them with the following:

```vue
><template>
<div>
 <h3>BabylonOne</h3>
 <canvas></canvas>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'BabylonOne',
mounted(){ //lifecycle hook
const canvas = document.querySelector("canvas")
 }
});
</script>
```

Changing the initial file name will trigger a warning as **HelloWorld** was the name used in the App.vue file. In the App.vue file, we will clear the content in the template tag and change the previous component name to BabylonOne (do this in every line **HelloWorld** is in). After we run the App in our terminal using `npm run serve` and within our browser, the result should be as below: ![Vue Component Result](https://blog.logrocket.com/wp-content/uploads/2022/06/vue-component-result.png)

### Creating the Babylon class <a name="creating-babylon-class">

In this section, we want to create a TypeScript class for Babylon. To do this, we will create a subfolder in the src folder called **BabylonOne**. 

In this folder, we will create a new TypeScript file called **BabylonScene**. Within this file, we will import **Scene** and **Engine** from our Babylon core package, and we will create a class called **BabylonScene**. 

Within this class, we will create a scene and engine variable and a constructor that we automatically call when creating an instance of the class. We need the constructor to grab the canvas element created in our Vue component. 

In our scene variable, we specify the type as **Scene** and engine variable of the type as **Engine**. Next, we add the engine variable to our constructor and set anti-aliasing to **True**. 

We will create a separate method outside the constructor and assign it to the scene variable for the **Scene** variable. Finally, we want to render our scene simultaneously as the engine runs. Thus, we will `use runRenderLoop` to do this. Below is an implementation of the above:

```typescript
import { Scene, Engine } from "@babylonjs/core"
export class BabylonScene {
  scene: Scene;
  engine: Engine;
  constructor(private canvas: HTMLCanvasElement) {
    this.engine = new Engine(this.canvas, true);
    this.scene = this.CreateScene();
    this.engine.runRenderLoop(() => {
      this.scene.render();
    });
  }
  CreateScene(): Scene {
    const scene = new Scene(this.engine);
    return scene;
  }
}
```

### Rendering the scene in Vue <a name="rendering-scene-vue">

To do this, we head back to the **BabylonOne** file and import the **BabylonScene** class from BabylonScene.ts file. Within the mounted, we call the BabylonScene class with the parameter “canvas”. Here is how the script tag looks at the moment:

```vue
<script lang="ts">
import { defineComponent } from 'vue';
import { BabylonScene } from '@/BabylonOne/BabylonScene';
export default defineComponent({
 name: 'BabylonOne',
 mounted(){ //lifecycle hook
  const canvas = document.querySelector("canvas")!;
  new BabylonScene(canvas)
 }
});
</script>
```

(Note: Add a single exclamation behind the closing bracket in the canvas variable) 

Once completed, we will test it in our terminal, and our result is as below: ![Terminal Test Scene](https://blog.logrocket.com/wp-content/uploads/2022/06/terminal-test-scene.png)

### Modifying the CSS and adding a camera and hemispheric lighting <a name="modifying-the-css">

We want the canvas size to be about 70–80 percent of the screen size. We want to create a canvas CSS with a width and height of 70 percent. Once we implement the above, our canvas will be as below: 

Now, we want to see things in our canvas — thus, we will add a camera, a light, and some 3D objects (a ground and a sphere ball). To do this, we add the code below to our CreateScene Method in the BabylonScene.ts file:

```typescript
const Camera = new FreeCamera("camera", new Vector3(0,1,-5), this.scene);
Camera.attachControl();
const light = new HemisphericLight("light", new Vector3(0,1,0), this.scene);
light.intensity = 0.5;
//3D Object
const ground = MeshBuilder.CreateGround("ground", {width: 10, height:10}, this.scene);
const sphereball = MeshBuilder.CreateSphere("sphereball", {diameter:1}, this.scene);
sphereball.position = new Vector3(0,1,0)
```

### Explaining the code snippet <a name="explaining-code-snippet">

When creating a camera variable, we assign its value as **FreeCamera** and define its name, starting position, and scene as **camera, new Vector3(0,1,-5)**, _this.scene_, respectively. To control the camera with our mouse, we use the `attachControl` method. 

For the camera to work, we need to add light to see the object in our environment. To achieve this, we will create a light variable and assign its value as **HemisphericLight**. We will add a name, starting position, and scene similar to the camera variable. 

Finally, we will add the intensity to adjust the brightness of the **HemisphericLight** (note that by default, the intensity is set to one, making the environment too bright). 

For the 3D object, we will create a ground and a sphere to represent a 3D object in our environment. To create a ground, we create a ground variable and assign the value `MeshBuilder.CreateGround` while setting the name, width and height, and scene. 

We also use the Meshbuilder method to create a spherical ball while setting the name, diameter, and scene. To modify the ball's position, we will use the position method and assign it to a starting position. 

After implementing the code above, we should have the result as below: ![Babylon 3D Mesh Example](https://blog.logrocket.com/wp-content/uploads/2022/06/babylon-3d-mesh-example.png)

## Conclusion

Babylon.js is a versatile 3D JavaScript library capable of doing anything imaginable with 3D. 

Babylon.js is a perfect 3D library with its only significant drawback being its package size. 

In this tutorial, we have shown you how to create a Vue component, a Babylon class, render a scene on a canvas and create a 3D mesh 

Thanks for reading and happy coding!

---

##Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try [LogRocket](https://files.readme.io/00591d0-687474703a2f2f692e696d6775722e636f6d2f6a3049327856572e706e67.png). 

[![sign up](https://files.readme.io/00591d0-687474703a2f2f692e696d6775722e636f6d2f6a3049327856572e706e67.png)](https://logrocket.com/signup/)

[LogRocket](https://files.readme.io/00591d0-687474703a2f2f692e696d6775722e636f6d2f6a3049327856572e706e67.png) is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - [Start monitoring for free](https://www2.logrocket.com/vue-performance-monitoring).