Scene Management
The Scene object is the container for all elements in your 3D world - meshes, lights, cameras, and more. It coordinates these elements and manages their interactions within the 3D space.
Creating a scene is straightforward:
// Create a new scene
const scene = new BABYLON.Scene(engine);
// Optional: Set scene properties
scene.clearColor = new BABYLON.Color4(0.2, 0.2, 0.3, 1); // Set background color
scene.ambientColor = new BABYLON.Color3(0.3, 0.3, 0.3); // Set ambient light
The Scene class implements several important software engineering patterns:
The Scene class in Babylon.js implements several important software engineering patterns that facilitate effective 3D application development:
- Observer Pattern: The scene utilizes a robust event system where objects emit events that other components can subscribe to. This enables loose coupling between components, as listeners can react to changes without direct dependencies. For example,
scene.onBeforeRenderObservable
allows code to execute before each frame renders without modifying the render loop itself. This pattern is extensively used throughout Babylon.js for everything from input handling to animation triggers. - Component System: Elements like meshes, lights, cameras, and materials are managed as components attached to the scene. Each component handles its specific functionality while the scene coordinates their interactions. This modular approach allows developers to add, remove, or modify scene elements independently. The scene maintains registries of these components (e.g.,
scene.meshes
,scene.lights
) and handles their lifecycle events appropriately. - Hierarchical Structure: Objects within the scene can form parent-child relationships creating a scene graph. Transformations applied to parent nodes cascade down to their children, allowing for complex object grouping and simplified manipulation of related elements. This hierarchy enables intuitive organization of scene elements and efficient transforms through matrix inheritance. The scene itself acts as the root of this hierarchy.
- Rendering Pipeline: The scene controls a sophisticated rendering pipeline that determines how and when elements are drawn to the screen. This pipeline includes stages for shadow generation, post-processing effects, particle systems, and various render targets. Developers can customize this pipeline through scene rendering groups, layer masks, and custom render targets to achieve complex visual effects while maintaining performance.
- State Management: The scene maintains the global state of the 3D environment, including active cameras, lights, environmental settings, and physics configuration. This centralized state management provides a single source of truth for the rendering system and ensures consistent behavior across the application.
- Resource Management: The scene helps coordinate resource loading, tracking, and disposal. It provides mechanisms for asynchronous asset loading, texture management, and garbage collection of unused resources to prevent memory leaks.
The scene provides several key lifecycle hooks:
// Before render hook - called before each frame render
scene.onBeforeRenderObservable.add(() => {
// Perform operations before rendering
});
// After render hook - called after each frame render
scene.onAfterRenderObservable.add(() => {
// Perform operations after rendering
});
// Ready event - called when the scene is fully loaded
scene.onReadyObservable.add(() => {
// Scene is ready, all resources loaded
});
For complex applications, you might manage multiple scenes:
// Create multiple scenes
const gameScene = new BABYLON.Scene(engine);
const uiScene = new BABYLON.Scene(engine);
// Switch between scenes
let activeScene = gameScene;
engine.runRenderLoop(() => {
activeScene.render();
});
// Function to switch scenes
function switchToUIScene() {
activeScene = uiScene;
}
The scene maintains a hierarchical graph of all objects:
// Create a parent node
const parentNode = new BABYLON.TransformNode("parent", scene);
// Create child meshes
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene);
sphere.parent = parentNode;
const box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
box.parent = parentNode;
// Transforming the parent affects all children
parentNode.position.y = 2;
parentNode.rotation.y = Math.PI / 4;
Babylon.js 7 includes enhanced scene optimization tools:
// Activate scene optimizer
const options = new BABYLON.SceneOptimizerOptions();
options.addOptimization(new BABYLON.HardwareScalingOptimization(0, 1));
options.addOptimization(new BABYLON.ParticlesOptimization(0.5));
options.addOptimization(new BABYLON.ShadowsOptimization(0.5));
const optimizer = new BABYLON.SceneOptimizer(scene, options);
optimizer.start();
Scenes can be serialized to JSON for saving and loading:
// Serialize scene to JSON
const serializedScene = BABYLON.SceneSerializer.Serialize(scene);
const sceneString = JSON.stringify(serializedScene);
// Save to localStorage or server...
localStorage.setItem('savedScene', sceneString);
// Later, load the scene
const loadedScene = new BABYLON.Scene(engine);
const savedData = localStorage.getItem('savedScene');
BABYLON.SceneLoader.Append("", "data:" + savedData, loadedScene);