Babylon is a JavaScript framework enabling developers to create 3D graphics with ease. Popular games such as Shell Shockers use this framework to create 3D games. It's shinier than ever, now that Version 4.0 just released!
I'll show you how to use Babylon to create a simple 3D environment. We'll go over creating an environment, adding objects to the environment, adding gravity, and adding collisions.
Setup
First, create an HTML,CSS,JS repl
Then, modify your index.html file. We're going to be adding the BablyonJS script tag, and our main.js file.
You may have noticed thetype="module" attribute on the main.js script tag. That means we're importing main.js as a JavaScript module. This means that we can use the import syntax to import other .js files inside of main.js. I like doing this because it makes the index.html file more readable. (you can learn more about JS Modules (ESM) here.
When you start the app, it should serve an empty page. Let's add the basic BabylonJS stuff now! 😄
Creating a Babylon Scene
Make sure you add the following to your main.js. I'll explain nit below
import { createGameScene } from "./gameScene.js";
window.addEventListener("DOMContentLoaded", start);
function start() {
let canvas = document.getElementById("canvas");
let engine = new BABYLON.Engine(canvas, true);
let scene = createGameScene(canvas, engine);
let sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene);
engine.runRenderLoop(function() {
scene.render();
});
window.addEventListener("resize", function() {
engine.resize()
});
};
Inside the start, function, we're creating a BABYLON engine. The engine 'translates' the BabylonJS API to canvas painting. For example, when you create a sphere with BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene);, it is responsible for actually drawing the sphere on the screen.
A scene contains all of our scene objects. Think of it as a room - it can contain lights, cameras, 3D objects and more
engine.runRenderLoop is a function that runs continuously. In this case, we want Babylon to continuously render the scene (scene.render())
You may notice that we're using the createGameScene function, and we're importing it from ./gameScene.js. So, create a gameScene.js file. Like the name says, we're going to be creating the game scene in this file. This is where we will be creating our lights, cameras, and our meshes (3D objects).
let createGameScene = function(canvas, engine) {
// Create scene
let scene = new BABYLON.Scene(engine);
// Create camera
let camera = new BABYLON.UniversalCamera("Camera", new BABYLON.Vector3(2, 2, 2), scene);
camera.attachControl(canvas, true);
camera.setTarget(BABYLON.Vector3.Zero());
// Create lights
let light = new BABYLON.HemisphericLight("myLight", new BABYLON.Vector3(1, 1, 0), scene);
return scene;
};
export {
createGameScene
};
First, we're creating a regular BABYLON scene. Whatever you put inside this scene will get rendered by the engine.
Then, we create a new UniversalCamera camera. BabylonJS automatically sets up your camera so you can look around with your mouse or move around with the arrow keys. Thecamera.attachControl()lets us interact with the canvas using our mouse. If we did not add that, then Babylon would not know when we would be moving our mouse.
If you're wondering what the export { createGameScene } is all about, it's a part of the ES6 Module syntax, also known as ECMAScript Modules (ESM). We don't have time to go over it in this post, but you can read about it here. In a nutshell, we're creating a reusable function that can be imported into any other file.
Anyways, we're getting results! :D But unfortunately, the canvas is not styled properly
Styling the Canvas
Let's create a style.css to fix the canvas styling
The next step is to call showLoadingScreen and hideLoadingScreen from main.js. Firstly, import the functions from loadingScreen.js
import { showLoadingScreen, hideLoadingScreen } from "./loadingScreen.js";
Now we have to show and hide the loading screen at the right times. Let's use showLoadingScreen() right after we create the Babylon engine.
let canvas = document.getElementById("canvas");
let engine = new BABYLON.Engine(canvas, true);
showLoadingScreen(canvas, engine);
...
We can't forget to hide the loading screen when everything has been loaded! I'm adding the code right after I create my sphere. Note that this will not hide the loading screen after you create the sphere. Babylon will automatically know when to hide the loading the screen.
Although we are able to move the sphere with the mouse, we still can't move the camera with the 'WASD' keys. Let's add some extra controls to the camera!
camera.keysUp is an array that contain key codes. (for example, 87 is a keycode for pressing 'W'). We're adding 87 to the array, which means the camera will move 'up' when 'W' is pressed
Other Camera Properties
You can also mess around with other properties of the camera! You can change the speed, inertia, or the field of view (FOV). You can view the whole list of properties on the Babylon documentation.
These are the values of fov, speed, and inertia I'm using. You can change them whenever you want!
Moving around is cool and all, but isn't it bothersome that we have to hold 'left click' if we want to look around? To fix this, we can use the Pointer Lock API. Think of it like this: when we click on the canvas, the mouse is 'locked' in the canvas. When this happens, moving your mouse doesn't move the cursor, but instead directly interacts with the canvas element.
I created a pointerLock.js file and added the following code
You might be curious why we are trying to access requestPointerLock, msRequestPointerLock, mozRequestPointerLock, and webkitRequestPointerLock. This is because browsers have slightly different implementations and it's not completely standardized yet.
Inside of main.js, be sure to actually import the createPointerLock function and use it. I called the method right after I created the scene.
import { createPointerLock } from "./pointerLock.js"
...
let scene = createGameScene(canvas, engine);
createPointerLock(scene);
Adding Some Ground
Players can't really move around if there is no ground. Let's create one!
Babylon's MeshBuilder lets us do this really easily. Near the end of your gameScene.js file, create the plane:
I used plane.rotate() to rotate the plane so it is completely flat
plane.position.y decreases the altitude of the plane so it is below the sphere
Gravity
Creating gravity is pretty straightforward. To add gravity, we have to do three things.
Choose a Physics engine
Enable gravity on the scene
Enable gravity on the sphere (you can add it to other objects as well!)
Choose a Physics Engine
CannonJS is a physics engine well supported by Babylon. In our case, the physics engine will calculate where the sphere falls and how the sphere will interact with the plane. We want the sphere to bounce.
To enable gravity in the scene, we just have to set the gravity property to a vector. For the purposes of this tutorial, think of a vector as an arrow pointing in a direction. In this case, the arrow represents the force of gravity. The force of gravity is pointing down, at -0.4 units.
After creating gravity, then we enable CannonJS. I put the following code right after I created the scene variable (in gameScene.js)
scene.gravity = new BABYLON.Vector3(0, -.4, 0);
scene.enablePhysics(scene.gravity, new BABYLON.CannonJSPlugin());
// Enable regular collisions as well
scene.collisionsEnabled = true;
scene.workerCollisions = true;
Enable gravity on the sphere
After enabling gravity on the sphere, it doesn't look like it does anything. This is because the gravity "doesn't have anything to push". Indeed, we want gravity to make the sphere fall, but we have to tell CannonJS that. We're going to tell CannonJS that we want the sphere to fall by creating a physics imposter from it.
A physics imposter is a simplified model of an object, or mesh. For example, we are simplifying the shape of our sphere mesh into a cube (BABYLON.PhysicsImposter.BoxImposter). The simpler shapes makes doing physics calculations a lot faster. If you've every played an action games, physics imposters are very similar to hitboxes.
With that said, lets create a physics imposter the sphere and plane.
let spherePhysicsImposter = new BABYLON.PhysicsImpostor(
sphere,
BABYLON.PhysicsImpostor.BoxImpostor,
{
mass: 1,
friction: 0.1,
restitution: .85
},
scene
);
let planePhysicsImposter = new BABYLON.PhysicsImpostor(
plane,
BABYLON.PhysicsImpostor.BoxImpostor,
{
mass: 0,
friction: 0.1,
restitution: .7
},
scene
);
We set the mass of the planePhysicsImposter to 0 because we do not want the plane to fall
Feel free to play with the mass, friction and restitution values
Below you can see the sphere bouncing on the plane. Pretty cool, eh?
So we have all the physics in place - wouldn't it be cool to interact with the scene directly? To do this, we can make the camera affected by gravity. Since we already have keyboard controls of the camera, we can simply walk around!
We first create an ellipsoid around the camera. You can think of this like the hitbox. It less collide with objects like the sphere. The ellipsoid has a height of 0.5 units and has a length and width of 1.5 units
If you don't seem to be moving, you may want to check camera.speed
If you want the camera to collide with the sphere, must enable collisions with the sphere
Now we have a player moving around the scene, with gravity enabled! We can collide with some meshes in the scene, like the sphere. How cool is that? Hopefully you found this BabylonJS introduction tutorial to be helpful! Tell me what you think and post a comment!
hey whoever created this, thanks for creating this because i am an avid programmer and like to script games but dont want to use unity, roblox studio or unreal engine while i find them too complicated. Thank for creating a tutorial. k bye
🎮 3D Games with BabylonJS: A Starter Guide
Babylon is a JavaScript framework enabling developers to create 3D graphics with ease. Popular games such as Shell Shockers use this framework to create 3D games. It's shinier than ever, now that Version 4.0 just released!
I'll show you how to use Babylon to create a simple 3D environment. We'll go over creating an environment, adding objects to the environment, adding gravity, and adding collisions.
Setup
First, create an
HTML,CSS,JS
replThen, modify your
index.html
file. We're going to be adding the BablyonJS script tag, and ourmain.js
file.You may have noticed the
type="module"
attribute on themain.js
script tag. That means we're importingmain.js
as a JavaScript module. This means that we can use theimport
syntax to import other.js
files inside ofmain.js
. I like doing this because it makes theindex.html
file more readable. (you can learn more about JS Modules (ESM) here.When you start the app, it should serve an empty page. Let's add the basic BabylonJS stuff now! 😄
Creating a Babylon Scene
Make sure you add the following to your
main.js
. I'll explain nit belowstart
, function, we're creating a BABYLON engine. Theengine
'translates' the BabylonJS API to canvas painting. For example, when you create a sphere withBABYLON.MeshBuilder.CreateSphere("sphere", {}, scene);
, it is responsible for actually drawing thesphere
on the screen.engine.runRenderLoop
is a function that runs continuously. In this case, we want Babylon to continuously render the scene (scene.render()
)You may notice that we're using the
createGameScene
function, and we're importing it from./gameScene.js
. So, create agameScene.js
file. Like the name says, we're going to be creating the game scene in this file. This is where we will be creating our lights, cameras, and our meshes (3D objects).scene
. Whatever you put inside this scene will get rendered by theengine
.UniversalCamera
camera. BabylonJS automatically sets up your camera so you can look around with your mouse or move around with the arrow keys. Thecamera.attachControl()
lets us interact with the canvas using our mouse. If we did not add that, then Babylon would not know when we would be moving our mouse.If you're wondering what the
export { createGameScene }
is all about, it's a part of the ES6 Module syntax, also known as ECMAScript Modules (ESM). We don't have time to go over it in this post, but you can read about it here. In a nutshell, we're creating a reusable function that can be imported into any other file.Anyways, we're getting results! :D But unfortunately, the canvas is not styled properly
Styling the Canvas
Let's create a
style.css
to fix the canvas stylingBe sure to add
<link rel="stylesheet" href="style.css">
to yourindex.html
And presto! Now the canvas fills up the entire screen!
View the code in this this repl
Loading Screen
Games usually have a loading screen. This improves the user experience since the user sees a loading bar rather than a blank page. Let's create one!
Inside of
loadingScreen.js
, addshowLoadingScreen
function creates a default loading screen. The words "Please Wait" is shown on ablack
background with a loading spinner.hideLoadingScreen
function simply hides the loading screenLearn more about loading screens and custom loading screens on the Babylon docs
The next step is to call
showLoadingScreen
andhideLoadingScreen
frommain.js
. Firstly, import the functions fromloadingScreen.js
Now we have to show and hide the loading screen at the right times. Let's use
showLoadingScreen()
right after we create the Babylonengine
.We can't forget to hide the loading screen when everything has been loaded! I'm adding the code right after I create my
sphere
. Note that this will not hide the loading screen after you create thesphere
. Babylon will automatically know when to hide the loading the screen.Now your loading screen should work! It will look something like this
View the code in this repl
Making the Camera Move
Although we are able to move the sphere with the mouse, we still can't move the camera with the 'WASD' keys. Let's add some extra controls to the camera!
Inside of my
gameScene.js
, I added:camera.keysUp
is an array that contain key codes. (for example,87
is a keycode for pressing 'W'). We're adding87
to the array, which means the camera will move 'up' when 'W' is pressedOther Camera Properties
You can also mess around with other properties of the camera! You can change the speed, inertia, or the field of view (FOV). You can view the whole list of properties on the Babylon documentation.
These are the values of
fov
,speed
, andinertia
I'm using. You can change them whenever you want!Now it works! Below, I set the
fov
to0.3
.View the code in this repl
Adding a Pointer Lock
Moving around is cool and all, but isn't it bothersome that we have to hold 'left click' if we want to look around? To fix this, we can use the Pointer Lock API. Think of it like this: when we click on the canvas, the mouse is 'locked' in the canvas. When this happens, moving your mouse doesn't move the cursor, but instead directly interacts with the
canvas
element.I created a
pointerLock.js
file and added the following codeYou might be curious why we are trying to access
requestPointerLock
,msRequestPointerLock
,mozRequestPointerLock
, andwebkitRequestPointerLock
. This is because browsers have slightly different implementations and it's not completely standardized yet.Inside of
main.js
, be sure to actually import thecreatePointerLock
function and use it. I called the method right after I created thescene
.Adding Some Ground
Players can't really move around if there is no ground. Let's create one!
Babylon's
MeshBuilder
lets us do this really easily. Near the end of yourgameScene.js
file, create theplane
:plane.rotate()
to rotate the plane so it is completely flatplane.position.y
decreases the altitude of the plane so it is below thesphere
Gravity
Creating gravity is pretty straightforward. To add gravity, we have to do three things.
scene
sphere
(you can add it to other objects as well!)Choose a Physics Engine
CannonJS is a physics engine well supported by Babylon. In our case, the physics engine will calculate where the sphere falls and how the sphere will interact with the
plane
. We want thesphere
to bounce.So, let's add our physics engine: CannonJS
Enable gravity on the
scene
To enable gravity in the
scene
, we just have to set thegravity
property to a vector. For the purposes of this tutorial, think of a vector as an arrow pointing in a direction. In this case, the arrow represents the force of gravity. The force of gravity is pointing down, at-0.4
units.After creating gravity, then we enable CannonJS. I put the following code right after I created the
scene
variable (ingameScene.js
)Enable gravity on the
sphere
After enabling gravity on the sphere, it doesn't look like it does anything. This is because the gravity "doesn't have anything to push". Indeed, we want gravity to make the sphere fall, but we have to tell CannonJS that. We're going to tell CannonJS that we want the
sphere
to fall by creating a physics imposter from it.A physics imposter is a simplified model of an object, or mesh. For example, we are simplifying the shape of our
sphere
mesh into a cube (BABYLON.PhysicsImposter.BoxImposter
). The simpler shapes makes doing physics calculations a lot faster. If you've every played an action games, physics imposters are very similar to hitboxes.With that said, lets create a physics imposter the
sphere
andplane
.planePhysicsImposter
to0
because we do not want theplane
to fallmass
,friction
andrestitution
valuesBelow you can see the
sphere
bouncing on theplane
. Pretty cool, eh?View the code in this repl.
Walking
So we have all the physics in place - wouldn't it be cool to interact with the scene directly? To do this, we can make the camera affected by gravity. Since we already have keyboard controls of the camera, we can simply walk around!
sphere
. The ellipsoid has a height of0.5
units and has a length and width of1.5
unitscamera.speed
If you want the
camera
to collide with thesphere
, must enable collisions with thesphere
As you can see, I can now walk around!
View the code in this repl
🚀
Now we have a player moving around the
scene
, with gravity enabled! We can collide with some meshes in thescene
, like thesphere
. How cool is that? Hopefully you found this BabylonJS introduction tutorial to be helpful! Tell me what you think and post a comment!hey whoever created this, thanks for creating this because i am an avid programmer and like to script games
but dont want to use unity, roblox studio or unreal engine while i find them too complicated. Thank for creating a tutorial.
k bye