Skip to content

BabylonJS - Basic Elements

Babylon.js provides the fundamental building blocks for creating any 3D scene. Understanding these core components – the engine, scene, camera, lights, and meshes – is the first step towards building interactive 3D web applications and games.

Let’s build a simple scene step-by-step to see these elements in action.

Every Babylon.js application needs an HTML file. Inside this file, you need a <canvas> element, which is the drawing surface where Babylon.js will render the 3D scene. You also need to include the Babylon.js library, typically via a CDN link or from your project’s node_modules if using NPM/Yarn.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Babylon.js Basic Scene</title>
<!-- Include Babylon.js Core Library -->
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; }
#renderCanvas { width: 100%; height: 100%; touch-action: none; /* Recommended for pointer events */ }
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<!-- Your JavaScript code will go here -->
<script type="text/javascript">
// Babylon.js code will be added in the next steps
</script>
</body>
</html>

The Engine is the central orchestrator in Babylon.js. It’s responsible for communicating with the browser’s rendering capabilities (WebGL/WebGPU) and drawing your scene onto the canvas. You create an engine instance by passing it the canvas element.

// Get the canvas element
const canvas = document.getElementById("renderCanvas");
// Create the Babylon.js engine
const engine = new BABYLON.Engine(canvas, true); // true enables anti-aliasing
// The BABYLON object contains all core Babylon.js classes and functions.

A Scene acts as a container for everything you want to render: meshes, lights, cameras, materials, etc. You create a scene and associate it with the engine.

// Create a function to encapsulate scene creation
const createScene = function () {
// Create a new scene
const scene = new BABYLON.Scene(engine);
// Set the background color (optional)
scene.clearColor = new BABYLON.Color4(0.1, 0.1, 0.2, 1.0); // Dark blue background
// --- We will add cameras, lights, and meshes here later ---
return scene;
};
// Call the createScene function
const scene = createScene();

Simply creating the engine and scene isn’t enough to display anything. You need to tell the engine to continuously render the scene. This is done using the engine.runRenderLoop. This function takes a callback that executes repeatedly (ideally 60 times per second), and inside this callback, you call scene.render().

// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
scene.render();
});
// Handle browser window resizing
window.addEventListener("resize", function () {
engine.resize();
});

At this point, if you run the HTML file, you’ll see a blank canvas with the dark blue background color we set. We haven’t added anything to the scene yet.

You can’t see anything in a 3D world without a camera to view it from and light to illuminate it. Let’s add a simple camera and light.

The ArcRotateCamera is great for beginners. It orbits around a target point and can be easily controlled with the mouse or touch.

The HemisphericLight provides basic ambient illumination, simulating light coming from the sky.

// Inside the createScene function:
// Create an ArcRotateCamera
// Parameters: name, alpha (rotation around Y), beta (rotation around X), radius (distance), target (focus point), scene
const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 10, BABYLON.Vector3.Zero(), scene);
// Attach the camera to the canvas, enabling user input (mouse/touch)
camera.attachControl(canvas, true);
// Create a basic light
// Parameters: name, direction (upwards vector), scene
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
// Adjust light intensity (optional)
light.intensity = 0.7;

Meshes are the visible 3D objects in your scene. Babylon.js provides the MeshBuilder class to easily create various standard shapes.

// Inside the createScene function (after camera and light):
// Create a sphere
// Parameters: name, options (diameter, segments, etc.), scene
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);
// Position the sphere upwards
sphere.position.y = 1;
// Create a ground plane
// Parameters: name, options (width, height, subdivisions, etc.), scene
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 6, height: 6 }, scene);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Babylon.js Basic Scene</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; }
#renderCanvas { width: 100%; height: 100%; touch-action: none; }
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="text/javascript">
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.1, 0.1, 0.2, 1.0);
const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 10, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);
sphere.position.y = 1;
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 6, height: 6 }, scene);
return scene;
};
const scene = createScene();
engine.runRenderLoop(function () {
scene.render();
});
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>

Running this code will display a 3D scene containing a white sphere resting on a white ground plane, illuminated by ambient light against a dark blue background. You can click and drag to rotate the view around the sphere, and use the mouse wheel (or pinch gesture) to zoom in and out.

Here’s a quick reference for creating some common shapes using MeshBuilder:

ShapeSyntax Example
BoxBABYLON.MeshBuilder.CreateBox(“box”, { size: 2 }, scene);
SphereBABYLON.MeshBuilder.CreateSphere(“sphere”, { diameter: 2, segments: 32 }, scene);
PlaneBABYLON.MeshBuilder.CreatePlane(“plane”, { width: 5, height: 5 }, scene);
GroundBABYLON.MeshBuilder.CreateGround(“ground”, { width: 10, height: 10 }, scene);
CylinderBABYLON.MeshBuilder.CreateCylinder(“cylinder”, { height: 3, diameterTop: 1, diameterBottom: 1.5, tessellation: 24 }, scene);
TorusBABYLON.MeshBuilder.CreateTorus(“torus”, { diameter: 5, thickness: 1, tessellation: 32 }, scene);
KnotBABYLON.MeshBuilder.CreateTorusKnot(“knot”, { radius: 2, tube: 0.5, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, scene);
Linesconst points = [ new BABYLON.Vector3(-5, 0, 0), new BABYLON.Vector3(5, 0, 0) ];
BABYLON.MeshBuilder.CreateLines(“lines”, { points: points }, scene);
Ground From Height MapBABYLON.MeshBuilder.CreateGroundFromHeightMap(“groundMap”, “url/to/heightMap.png”, { width: 100, height: 100, subdivisions: 50, minHeight: 0, maxHeight: 10 }, scene);

Transformations: Position, Rotation, Scaling

Section titled “Transformations: Position, Rotation, Scaling”

Once you have a mesh, you’ll often want to move, rotate, or resize it. Meshes have position, rotation (or rotationQuaternion), and scaling properties, which are all Vector3 objects (except rotationQuaternion).

  • Position: Changes the mesh’s location in 3D space (X, Y, Z coordinates). mesh.position = new BABYLON.Vector3(x, y, z); or modify components like mesh.position.x += 1;.
  • Rotation: Rotates the mesh around the X, Y, and Z axes. Measured in radians. mesh.rotation = new BABYLON.Vector3(radiansX, radiansY, radiansZ); or mesh.rotation.y += Math.PI / 4; (rotate 45 degrees around Y). Using Quaternions (mesh.rotationQuaternion) is often preferred for complex rotations to avoid gimbal lock.
  • Scaling: Resizes the mesh along the X, Y, and Z axes. A value of 1 means original size. mesh.scaling = new BABYLON.Vector3(scaleX, scaleY, scaleZ); e.g., mesh.scaling = new BABYLON.Vector3(2, 1, 1); (doubles width).
// Example Transformations
const box = BABYLON.MeshBuilder.CreateBox("myBox", { size: 1 }, scene);
// Move the box
box.position = new BABYLON.Vector3(2, 0.5, 3);
// Rotate the box 45 degrees around the Y axis
box.rotation.y = Math.PI / 4;
// Make the box twice as wide
box.scaling.x = 2;

Parenting allows you to link meshes together in a hierarchy. When you transform a parent mesh (move, rotate, scale), all its child meshes transform relative to the parent. This is incredibly useful for creating complex objects like robots (arm parented to torso, hand parented to arm) or solar systems (planets parented to sun).

// Create a parent box
const parentBox = BABYLON.MeshBuilder.CreateBox("parent", { size: 1 }, scene);
parentBox.position.x = -2;
// Create a child sphere
const childSphere = BABYLON.MeshBuilder.CreateSphere("child", { diameter: 0.5 }, scene);
// Set the parent
childSphere.parent = parentBox;
// Position the child RELATIVE to the parent's origin
childSphere.position.y = 1; // Places sphere 1 unit above the parent box's center
// Now, if you move or rotate parentBox, childSphere will move/rotate with it.
// parentBox.rotation.y = Math.PI / 2;

This demo shows a smaller box parented to a larger box. The larger box is scaled, and the child inherits this scaling relative to its own position.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Babylon.js - Parenting Demo</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; }
#renderCanvas { width: 100%; height: 100%; touch-action: none; }
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="text/javascript">
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.2, 0.4, 0.2, 1.0); // Greenish background
const camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 3, 15, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 1.0;
// Parent Box (larger, scaled)
const boxParent = BABYLON.MeshBuilder.CreateBox("BoxParent", { size: 2.0 }, scene);
boxParent.position = new BABYLON.Vector3(0, 1, 0);
boxParent.scaling = new BABYLON.Vector3(1.5, 0.5, 1.0); // Scaled: wider, shorter
// Child Box (smaller)
const boxChild = BABYLON.MeshBuilder.CreateBox("BoxChild", { size: 0.8 }, scene);
boxChild.parent = boxParent; // Assign parent
boxChild.position.x = 1.5; // Position relative to parent's center
boxChild.position.y = 1.0; // Position relative to parent's center
// Add simple materials for color
const parentMat = new BABYLON.StandardMaterial("parentMat", scene);
parentMat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0); // Blue
boxParent.material = parentMat;
const childMat = new BABYLON.StandardMaterial("childMat", scene);
childMat.diffuseColor = new BABYLON.Color3(1.0, 0.5, 0.5); // Red
boxChild.material = childMat;
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, scene);
// Animate parent rotation
scene.onBeforeRenderObservable.add(() => {
boxParent.rotation.y += 0.01;
});
return scene;
};
const scene = createScene();
engine.runRenderLoop(function () { scene.render(); });
window.addEventListener("resize", function () { engine.resize(); });
</script>
</body>
</html>

This demo shows a blue, flattened rectangular box rotating slowly around its vertical axis. Attached to its side is a smaller red cube, which rotates along with the parent blue box, maintaining its relative position.

Beyond basic background color, you can control the overall environment of your scene using fog, ambient color, and skyboxes or environment textures for realistic lighting and backgrounds.

As seen before, scene.clearColor sets the solid background color.

// Set background to light gray
scene.clearColor = new BABYLON.Color4(0.8, 0.8, 0.8, 1.0);
// Or use predefined colors
scene.clearColor = BABYLON.Color4.FromColor3(BABYLON.Color3.Teal());

scene.ambientColor defines a global ambient light color that affects materials (specifically StandardMaterial’s ambientColor property). It provides a base level of illumination, preventing areas untouched by direct light from being completely black. PBR materials handle ambient light differently, often through environment textures.

// Add a subtle ambient light
scene.ambientColor = new BABYLON.Color3(0.1, 0.1, 0.1);

Fog can add depth and atmosphere by making distant objects fade into a specific color. Babylon.js supports several fog modes:

  • BABYLON.Scene.FOGMODE_NONE: No fog (default).
  • BABYLON.Scene.FOGMODE_EXP: Fog density increases exponentially with distance.
  • BABYLON.Scene.FOGMODE_EXP2: Similar to EXP, but density increases faster.
  • BABYLON.Scene.FOGMODE_LINEAR: Fog increases linearly between a start and end distance.
// Enable linear fog
scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR;
scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85); // Fog color (e.g., light grayish yellow)
scene.fogStart = 20.0; // Distance where fog starts
scene.fogEnd = 60.0; // Distance where fog is at maximum density
// For exponential fog, use density instead of start/end:
// scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
// scene.fogDensity = 0.01;

A Skybox is a large cube surrounding your scene, textured with images of a sky or environment. This creates a realistic background. More importantly, modern rendering (especially PBR) uses cube textures (often .hdr or .env files processed from HDR images) as scene.environmentTexture. This texture provides both the background and realistic Image-Based Lighting (IBL) and reflections for materials.

Creating a simple skybox manually:

// Create a large box for the skybox
const skybox = BABYLON.MeshBuilder.CreateBox("skyBox", { size: 1000.0 }, scene);
// Create a skybox material
const skyboxMaterial = new BABYLON.StandardMaterial("skyBoxMat", scene);
skyboxMaterial.backFaceCulling = false; // See the texture from inside the box
// Load a cube texture (requires 6 images: _px, _nx, _py, _ny, _pz, _nz)
// Or a single .env or .dds file
skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/skybox", scene);
skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
// Make the skybox unaffected by scene lighting
skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
skyboxMaterial.disableLighting = true;
// Apply the material
skybox.material = skyboxMaterial;
// Ensure skybox is behind everything else
skybox.infiniteDistance = true;

Using an environment texture (modern approach, better for PBR):

// Load an environment texture (e.g., a pre-filtered .env file)
const environmentTex = BABYLON.CubeTexture.CreateFromPrefilteredData("textures/environment.env", scene);
scene.environmentTexture = environmentTex;
// Optional: Create a skybox mesh based on the environment texture
scene.createDefaultSkybox(environmentTex, true, 1000); // true uses the texture for the skybox, 1000 is size

Imagine modifying the previous basic scene. Add fog using scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR with appropriate start/end distances and color. Then, instead of scene.clearColor, create a skybox using scene.createDefaultSkybox and a suitable .env environment texture file. The sphere and ground would now appear against a realistic sky background, and if you used PBR materials, they would reflect the environment realistically. Distant parts of the ground would fade into the fog color.