Babylon.js Getting Started — Build Your First 3D Scene in the Browser
Babylon.js is a powerful, open-source 3D engine that runs in your browser. This tutorial teaches you the core building blocks — engine, scene, camera, lights, meshes, materials, and the render loop — so you can create your first interactive 3D scene from scratch.
What You’ll Learn
By the end of this tutorial, you’ll set up a Babylon.js engine and scene, add and position 3D objects (boxes, spheres, cylinders, toruses), control an orbiting camera, light your scene with multiple light types, apply colors and materials, and run the render loop to create real-time 3D graphics in a browser.
Why 3D in the Browser Matters
Websites used to be flat. Text, images, buttons — all on a 2D plane. But modern applications are increasingly three-dimensional: product viewers that let you rotate a car in 360°, architectural walkthroughs of buildings before they’re built, data visualizations that show complex relationships in 3D space, and interactive games that run without downloads.
Babylon.js makes all of this possible using WebGL and WebGPU — technologies built into every modern browser. No plugins, no installations. Your users just open a URL and see 3D.
Real-world use: Durga Antivirus Pro uses Babylon.js for its 3D threat visualization dashboard. When a network attack is detected, it renders the affected systems as 3D nodes with glowing connections, letting security analysts see the attack path in real time rather than reading through log files.
Where This Fits in Your Learning Path
flowchart LR
A["JavaScript & Web Basics"] --> B["**Babylon.js Getting Started**"]
B --> C["Materials & Textures"]
C --> D["Animation & Physics"]
D --> E["GUI & Interaction"]
E --> F["Importing & Assets"]
style B fill:#f97316,stroke:#c2410c,color:#fff
style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
style F fill:#22c55e,stroke:#16a34a,color:#22c55e
What is a 3D Engine?
Imagine you’re a film director. You need:
- A stage (Scene) — where everything happens
- A camera — how the audience sees the scene
- Lights — so the audience can see the actors
- Actors (Meshes) — the 3D objects in the scene
- A camera crew (Render Loop) — capturing each frame 60 times per second
Babylon.js provides all of these. Your job is to arrange them.
The Engine and Scene
The Engine connects your code to the GPU. It handles rendering, window resizing, and WebGL context creation. You create one engine per canvas.
The Scene is a container for everything visual. Think of it as a folder that holds all your 3D objects, lights, and cameras.
const canvas = document.getElementById('renderCanvas')
const engine = new BABYLON.Engine(canvas, true, {
preserveDrawingBuffer: true,
stencil: true,
})
const scene = new BABYLON.Scene(engine)
scene.clearColor = new BABYLON.Color3(0.08, 0.08, 0.12) // dark background
Why stencil: true? You need it for shadows and advanced effects later. Enable it now even if you don’t use it immediately — it’s hard to add later.
Why preserveDrawingBuffer: true? Required for taking screenshots of your canvas. Turn it off for performance in production if you don’t need screenshots.
Cameras — How the User Sees the Scene
A camera defines the viewpoint. Without one, you’d see nothing. Babylon.js offers several types.
ArcRotateCamera (the most useful for beginners): This camera orbits around a target point. Drag to rotate, scroll to zoom. Think of it like a camera on a crane that always points at the center of the action.
const camera = new BABYLON.ArcRotateCamera(
'camera1',
-Math.PI / 2, // alpha — horizontal angle (left/right)
Math.PI / 3, // beta — vertical angle (up/down)
10, // radius — distance from target
new BABYLON.Vector3(0, 2, 0), // target — what it looks at
scene
)
camera.attachControl(canvas, true) // enable mouse/touch control
Camera types at a glance:
| Camera | Best For | Controls |
|---|---|---|
ArcRotateCamera | Orbiting a model | Drag to rotate, scroll to zoom |
FreeCamera | First-person walkthrough | WASD + mouse look |
UniversalCamera | Cross-platform games | WASD + gamepad + touch |
Lights — Without Light, Everything is Black
In 3D rendering, objects reflect light. Without light sources, everything appears black regardless of color.
// HemisphericLight — ambient light from sky/ground
const hemi = new BABYLON.HemisphericLight(
'hemi', new BABYLON.Vector3(0, 1, 0), scene
)
hemi.intensity = 0.7
// DirectionalLight — simulates sunlight (parallel rays)
const dirLight = new BABYLON.DirectionalLight(
'dirLight', new BABYLON.Vector3(-1, -2, -1), scene
)
dirLight.position = new BABYLON.Vector3(2, 8, 4)
dirLight.intensity = 0.8Light types:
| Light | Analogy | Use For |
|---|---|---|
HemisphericLight | Overcast sky | Base ambient lighting (cheap) |
DirectionalLight | Sun | Strong directional shadows |
PointLight | Light bulb | Omni-directional local light |
SpotLight | Flashlight | Cone-shaped beam |
Meshes — The 3D Objects
Meshes are the actors on your stage. Babylon.js includes built-in shapes you can create with a single function call:
// Box — like a dice or crate
const box = BABYLON.MeshBuilder.CreateBox('box', { size: 2 }, scene)
box.position.set(-2.5, 1, 0)
// Sphere — like a ball
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {
diameter: 1.8, segments: 32
}, scene)
sphere.position.set(2.5, 0.9, 0)
// Cylinder — like a can
const cylinder = BABYLON.MeshBuilder.CreateCylinder('cyl', {
height: 1.8, diameter: 1.2
}, scene)
cylinder.position.set(0, 0.9, 2.5)
// Torus — like a donut
const torus = BABYLON.MeshBuilder.CreateTorus('torus', {
diameter: 1.6, thickness: 0.4
}, scene)
torus.position.set(0, 1.5, -2.5)What does segments: 32 mean on a sphere? It controls how many polygons the sphere is made of. More segments = smoother but more GPU work. 32 is a good balance. For a stylized low-poly look, use 8-12.
Moving and Rotating Meshes
Every mesh has position, rotation, and scaling — all using Vector3 (x, y, z):
// Position — where it is in 3D space
box.position = new BABYLON.Vector3(2, 1, 0)
sphere.position.y = 1
// Rotation — in radians, not degrees!
sphere.rotation.y += 0.01 // spin in render loop
// Scaling — stretch or shrink
cylinder.scaling = new BABYLON.Vector3(1, 2, 1) // stretched vertically
Degrees vs Radians: Babylon.js uses radians for rotation. Convert degrees to radians:
const radians = BABYLON.Tools.ToRadians(45) // 45 degrees
sphere.rotation.y = radiansMaterials — Giving Objects Color
A material defines how a surface looks — its color, shininess, and transparency:
const boxMat = new BABYLON.StandardMaterial('boxMat', scene)
boxMat.diffuseColor = new BABYLON.Color3(0.9, 0.2, 0.2) // red
boxMat.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3) // shine highlights
boxMat.specularPower = 32 // how tight the shine is
box.material = boxMatWhat is specularColor? It controls the color of shiny highlights. A red ball with white specular has white highlights. Black specular = matte surface, no shine.
The Render Loop — Making It Run
3D scenes don’t just sit there. They need to be rendered continuously — typically 60 times per second. This is called the render loop:
engine.runRenderLoop(() => {
// Animate things here
sphere.rotation.y += 0.01
torus.rotation.z += 0.008
box.rotation.x += 0.005
box.rotation.y += 0.005
scene.render() // MUST call this every frame
})
// Handle window resize
window.addEventListener('resize', () => engine.resize())Why do we need a loop? Unlike a static image, a 3D scene can change every frame — objects rotate, cameras move, animations play. The render loop tells Babylon.js “capture a new frame now.”
Common Mistakes Beginners Make
1. Forgetting camera.attachControl(canvas)
The camera won’t respond to mouse or touch input. You’ll be stuck looking at the same angle.
2. Not Calling scene.render() in the Loop
The most common cause of a blank or frozen scene. Without scene.render(), Babylon.js never draws anything.
3. Creating Meshes Without the Scene Parameter
// Wrong — mesh is created but not added to any scene
const box = BABYLON.MeshBuilder.CreateBox('box', { size: 2 })
// Correct — pass scene as the last argument
const box = BABYLON.MeshBuilder.CreateBox('box', { size: 2 }, scene)4. Forgetting Lights
Everything will be black. Add at least one HemisphericLight.
5. Using Degrees Instead of Radians
// Wrong — rotation will be unexpectedly tiny
sphere.rotation.y = 45
// Correct
sphere.rotation.y = BABYLON.Tools.ToRadians(45)6. Not Adding the Babylon.js Script
<!-- Must be included before your code -->
<script src="https://cdn.babylonjs.com/babylon.js"></script>Practice Questions
What does
engine.runRenderLoop()do? It calls a function every frame (typically 60 fps) to update and render the scene. You must callscene.render()inside it.Why does everything appear black if you don’t add lights? 3D rendering simulates light reflection. Without light sources, no light reaches the camera, so all surfaces appear black regardless of color.
What is the difference between
ArcRotateCameraandFreeCamera?ArcRotateCameraorbits around a fixed target — good for inspecting objects.FreeCameramoves freely through the scene like a first-person game.What does the
segmentsparameter do onCreateSphere? It controls polygon resolution. Higher values (64+) produce smoother spheres but use more GPU power. Default 32 is a good balance.How do you convert degrees to radians in Babylon.js? Use
BABYLON.Tools.ToRadians(degrees).
Challenge
Create a 3D scene with:
- A ground plane
- Five different mesh types (box, sphere, cylinder, torus, torus knot) arranged in a circle
- Each mesh has a different color and rotates at a different speed
- An
ArcRotateCamerafor orbit control - Both a
HemisphericLightand aDirectionalLight - A UI panel that shows the name of whichever mesh the user clicks
FAQ
Try It Yourself: 3D Scene Explorer
Run this complete HTML page to explore cameras, lights, and meshes interactively.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Babylon.js — 3D Scene Explorer</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; font-family: system-ui, sans-serif; }
#renderCanvas { width: 100%; height: 100%; display: block; }
#ui {
position: absolute; top: 16px; left: 16px;
background: rgba(0,0,0,0.75); color: #fff;
padding: 16px 20px; border-radius: 8px; font-size: 14px;
backdrop-filter: blur(4px); user-select: none;
display: flex; flex-direction: column; gap: 10px; min-width: 200px;
}
#ui label { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
#ui input[type="range"] { width: 100px; }
#ui button {
background: #4a6cf7; color: #fff; border: none;
padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 13px;
}
#ui button:hover { background: #5f7cf7; }
#ui select { background: #222; color: #fff; border: 1px solid #555; padding: 4px 8px; border-radius: 4px; font-size: 13px; }
#ui hr { border: none; border-top: 1px solid #444; margin: 4px 0; }
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<div id="ui">
<strong>3D Scene Explorer</strong>
<label>Camera <select id="cameraSelect"><option value="orbit">ArcRotate</option><option value="free">Free</option></select></label>
<label>Light X <input type="range" id="lightX" min="-10" max="10" step="0.1" value="2" /></label>
<label>Light Y <input type="range" id="lightY" min="0" max="20" step="0.1" value="8" /></label>
<label>Intensity <input type="range" id="lightIntensity" min="0" max="2" step="0.05" value="0.8" /></label>
<hr />
<button id="wireframeToggle">Toggle Wireframe</button>
<button id="resetCamera">Reset Camera</button>
</div>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script>
const canvas = document.getElementById('renderCanvas')
const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true })
const scene = new BABYLON.Scene(engine)
scene.clearColor = new BABYLON.Color3(0.08, 0.08, 0.12)
const orbitCam = new BABYLON.ArcRotateCamera('orbitCam', -Math.PI / 2, Math.PI / 3, 12, new BABYLON.Vector3(0, 1.5, 0), scene)
orbitCam.lowerRadiusLimit = 3; orbitCam.upperRadiusLimit = 25
const freeCam = new BABYLON.FreeCamera('freeCam', new BABYLON.Vector3(0, 4, -12), scene)
freeCam.setTarget(BABYLON.Vector3.Zero()); freeCam.speed = 0.15
scene.activeCamera = orbitCam; orbitCam.attachControl(canvas, true)
const hemi = new BABYLON.HemisphericLight('hemi', new BABYLON.Vector3(0, 1, 0), scene)
hemi.intensity = 0.3; hemi.diffuse = new BABYLON.Color3(0.8, 0.9, 1)
const dirLight = new BABYLON.DirectionalLight('dirLight', new BABYLON.Vector3(-1, -1, -0.5), scene)
dirLight.position = new BABYLON.Vector3(2, 8, 4); dirLight.intensity = 0.8
const ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 20, height: 20 }, scene)
const groundMat = new BABYLON.StandardMaterial('groundMat', scene)
groundMat.diffuseColor = new BABYLON.Color3(0.25, 0.25, 0.3); groundMat.specularColor = new BABYLON.Color3(0, 0, 0)
ground.material = groundMat
const box = BABYLON.MeshBuilder.CreateBox('box', { size: 1.8 }, scene)
box.position.set(-2.5, 0.9, 0)
const boxMat = new BABYLON.StandardMaterial('boxMat', scene)
boxMat.diffuseColor = new BABYLON.Color3(0.9, 0.2, 0.2); boxMat.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3); boxMat.specularPower = 32
box.material = boxMat
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 1.8, segments: 32 }, scene)
sphere.position.set(2.5, 0.9, 0)
const sphereMat = new BABYLON.StandardMaterial('sphereMat', scene)
sphereMat.diffuseColor = new BABYLON.Color3(0.2, 0.5, 0.9); sphereMat.specularColor = new BABYLON.Color3(0.5, 0.5, 0.5); sphereMat.specularPower = 64
sphere.material = sphereMat
const cyl = BABYLON.MeshBuilder.CreateCylinder('cyl', { height: 1.8, diameter: 1.2 }, scene)
cyl.position.set(0, 0.9, 2.5)
const cylMat = new BABYLON.StandardMaterial('cylMat', scene)
cylMat.diffuseColor = new BABYLON.Color3(0.1, 0.8, 0.3); cylMat.specularColor = new BABYLON.Color3(0.2, 0.2, 0.2)
cyl.material = cylMat
const torus = BABYLON.MeshBuilder.CreateTorus('torus', { diameter: 1.6, thickness: 0.4, tessellation: 32 }, scene)
torus.position.set(0, 1.5, -2.5); torus.rotation.x = Math.PI / 2
const torusMat = new BABYLON.StandardMaterial('torusMat', scene)
torusMat.diffuseColor = new BABYLON.Color3(0.9, 0.6, 0.1); torusMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4)
torus.material = torusMat
document.getElementById('cameraSelect').addEventListener('change', () => {
const c = scene.activeCamera; if (c) c.detachControl()
scene.activeCamera = document.getElementById('cameraSelect').value === 'orbit' ? orbitCam : freeCam
scene.activeCamera.attachControl(canvas, true)
})
document.getElementById('lightX').addEventListener('input', () => { dirLight.position.x = parseFloat(document.getElementById('lightX').value) })
document.getElementById('lightY').addEventListener('input', () => { dirLight.position.y = parseFloat(document.getElementById('lightY').value) })
document.getElementById('lightIntensity').addEventListener('input', () => { dirLight.intensity = parseFloat(document.getElementById('lightIntensity').value) })
document.getElementById('wireframeToggle').addEventListener('click', () => { [box, sphere, cyl, torus].forEach(m => { m.material.wireframe = !m.material.wireframe }) })
document.getElementById('resetCamera').addEventListener('click', () => { orbitCam.alpha = -Math.PI / 2; orbitCam.beta = Math.PI / 3; orbitCam.radius = 12; orbitCam.target = new BABYLON.Vector3(0, 1.5, 0) })
engine.runRenderLoop(() => {
sphere.rotation.y += 0.01; torus.rotation.z += 0.008; box.rotation.x += 0.005; box.rotation.y += 0.005
scene.render()
})
window.addEventListener('resize', () => engine.resize())
</script>
</body>
</html>What to expect: Four 3D objects (box, sphere, cylinder, torus) on a ground plane, each with a different color, all slowly rotating. Use the panel to switch cameras, adjust the directional light, toggle wireframe mode, or reset the camera view.
What’s Next
| Tutorial | What You’ll Learn |
|---|---|
| Materials & Textures | PBR materials, texture maps, environment lighting |
| Animation & Physics | Keyframe animation, Havok physics engine |
| GUI & Interaction | 2D UI overlays, mesh picking, ActionManager |
| Importing & Assets | glTF/GLB import, asset containers, optimization |
Related topics: JavaScript basics, WebGL fundamentals.
What’s Next
Congratulations on completing this Babylonjs Getting Started tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro