Skip to content
Learni
View all tutorials
Développement 3D

How to Create an Interactive 3D Scene with Babylon.js in 2026

18 minINTERMEDIATE
Lire en français

Introduction

Babylon.js is a powerful open-source 3D engine for the web. It enables immersive experiences directly in the browser without heavy installations. This intermediate tutorial guides you step-by-step through building a complete 3D scene including meshes, dynamic lighting, animations, and keyboard/mouse interactions. You will learn to properly structure your TypeScript code and leverage advanced engine features for smooth 60 FPS rendering.

Prerequisites

  • Basic knowledge of TypeScript and HTML5
  • Node.js 20+ and npm
  • A modern editor (VS Code recommended)
  • Recent browser supporting WebGL 2

Project Initialization

terminal
npm create vite@latest babylon-scene -- --template react-ts
cd babylon-scene
npm install babylonjs babylonjs-gui

Vite + React + TypeScript provides a fast development environment. Babylon.js and its GUI module are installed to handle both 3D rendering and user interfaces.

Creating the Engine and Scene

src/BabylonScene.tsx
import { Engine, Scene, ArcRotateCamera, Vector3, HemisphericLight } from 'babylonjs';
import { useEffect, useRef } from 'react';

export const BabylonScene = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current!;
    const engine = new Engine(canvas, true);
    const scene = new Scene(engine);

    const camera = new ArcRotateCamera('camera', Math.PI / 2, Math.PI / 3, 10, Vector3.Zero(), scene);
    camera.attachControl(canvas, true);

    const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene);

    engine.runRenderLoop(() => scene.render());
    window.addEventListener('resize', () => engine.resize());

    return () => engine.dispose();
  }, []);

  return <canvas ref={canvasRef} style={{ width: '100%', height: '100vh' }} />;
};

This code initializes the Babylon.js engine, creates a scene, and sets up an orbital camera. The runRenderLoop ensures 60 FPS rendering while resize handles window size changes.

Adding Basic Meshes

src/BabylonScene.tsx
import { MeshBuilder, StandardMaterial, Color3 } from 'babylonjs';

// Inside the useEffect, after creating the light
const sphere = MeshBuilder.CreateSphere('sphere', { diameter: 2 }, scene);
sphere.position.y = 1;

const ground = MeshBuilder.CreateGround('ground', { width: 10, height: 10 }, scene);

const material = new StandardMaterial('mat', scene);
material.diffuseColor = new Color3(0.2, 0.6, 0.9);
sphere.material = material;

MeshBuilder allows quick creation of primitives. A StandardMaterial is applied to the sphere to give it color and a realistic appearance.

Adding Lighting and Shadows

src/BabylonScene.tsx
import { DirectionalLight, ShadowGenerator } from 'babylonjs';

const dirLight = new DirectionalLight('dirLight', new Vector3(-1, -2, -1), scene);
dirLight.position = new Vector3(5, 10, 5);

const shadowGenerator = new ShadowGenerator(1024, dirLight);
shadowGenerator.addShadowCaster(sphere);
ground.receiveShadows = true;

A directional light with shadow generator adds realism. The sphere casts a shadow on the ground, an essential technique for intermediate scenes.

Animation with AnimationGroup

src/BabylonScene.tsx
import { Animation, AnimationGroup } from 'babylonjs';

const animGroup = new AnimationGroup('bounce');
const anim = new Animation('bounceAnim', 'position.y', 30, Animation.ANIMATIONTYPE_FLOAT);
const keys = [
  { frame: 0, value: 1 },
  { frame: 30, value: 3 },
  { frame: 60, value: 1 }
];
anim.setKeys(keys);
animGroup.addTargetedAnimation(anim, sphere);
animGroup.play(true);

AnimationGroup allows controlling multiple animations together. Here the sphere bounces in a loop, demonstrating Babylon.js frame-based animation system.

Adding Keyboard Interactions

src/BabylonScene.tsx
window.addEventListener('keydown', (evt) => {
  if (evt.key === 'r') {
    sphere.rotation.y += Math.PI / 2;
  }
  if (evt.key === ' ') {
    animGroup.play(true);
  }
});

Listening to keyboard events enables scene interaction. Pressing R rotates the sphere and the spacebar restarts the animation.

Best Practices

  • Always dispose resources (engine.dispose) to avoid memory leaks
  • Use AnimationGroup instead of individual animations for better management
  • Preload textures and models with AssetsManager
  • Separate rendering logic from business logic in dedicated classes
  • Enable WebGL 2 support and hardware extensions for better performance

Common Mistakes to Avoid

  • Forgetting to call engine.resize() on window changes
  • Creating materials inside the render loop
  • Not checking WebGL availability before initialization
  • Using excessively high frame values without adjusting animation frequency

Going Further

Deepen your skills with the Babylon.js courses from Learni. You will explore glTF model loading, custom shaders, and integration with React Three Fiber.

How to Create Interactive 3D Scenes with Babylon.js in 2026 | Learni