-
Notifications
You must be signed in to change notification settings - Fork 0
Adding a Scene
Alex Coulombe edited this page Apr 30, 2026
·
1 revision
This walks through adding a fourth scene from scratch. Use four-seasons.ts as your reference implementation.
src/scenes/<slug>.ts
Minimal scaffold:
import { Engine, Scene, Vector3, Color4, HemisphericLight, MeshBuilder } from "@babylonjs/core";
import type { SceneApi, SceneDefinition } from "../types";
import { Controls } from "../controls";
const mySceneDef: SceneDefinition = {
id: "my-scene", // must match the slug you'll use in the URL: #scene=my-scene
title: "My Scene",
subtitle: "Short description shown in the UI header",
placeholder: false, // set true while geometry is placeholder; shows "Real venue model loads in the live demo"
options: [
{
id: "time",
label: "Time of day",
choices: [
{ value: "day", label: "Day" },
{ value: "night", label: "Night" },
],
default: "day",
},
],
build(engine: Engine): SceneApi {
const canvas = engine.getRenderingCanvas() as HTMLCanvasElement;
const scene = new Scene(engine);
scene.clearColor = new Color4(0.5, 0.7, 0.9, 1);
scene.collisionsEnabled = true;
new HemisphericLight("sky", new Vector3(0, 1, 0), scene).intensity = 0.8;
// Ground — always add collision so the player doesn't fall through
const ground = MeshBuilder.CreateGround("ground", { width: 40, height: 40 }, scene);
ground.checkCollisions = true;
// Load your venue model
import("@babylonjs/loaders/glTF").then(() => {
BABYLON.SceneLoader.ImportMeshAsync("", "/models/my-scene/", "venue.glb", scene)
.catch(err => console.warn("Model load failed, falling back to placeholders", err));
});
const controls = new Controls(
scene, canvas,
new Vector3(0, 1.7, 8), // spawn position
new Vector3(0, 1.7, 0), // look target
);
scene.onBeforeRenderObservable.add(() => {
controls.tick(engine, engine.getDeltaTime() / 1000);
});
return {
scene,
camera: controls.camera,
meshes: [],
applyOption(id, value) {
if (id === "time") {
scene.clearColor = value === "night"
? new Color4(0.02, 0.02, 0.08, 1)
: new Color4(0.5, 0.7, 0.9, 1);
}
},
dispose() {
controls.dispose();
scene.dispose();
},
};
},
};
export default mySceneDef;src/types.ts — add to the SceneId union:
// before:
export type SceneId = "four-seasons" | "carol" | "dnd";
// after:
export type SceneId = "four-seasons" | "carol" | "dnd" | "my-scene";src/main.ts — import and add to SCENES:
import mySceneDef from "./scenes/my-scene";
const SCENES: Record<SceneId, SceneDefinition> = {
"four-seasons": fourSeasonsDef,
"carol": carolDef,
"dnd": dndDef,
"my-scene": mySceneDef, // add this line
};Place your venue model (GLB preferred, Draco-compressed for size):
public/models/my-scene/venue.glb
Size budget: ≤8 MB total per scene for comfortable phone WebXR. Draco compression typically cuts geometry 6–10×. Use gltfpack to compress:
gltfpack -i venue-raw.glb -cc -o public/models/my-scene/venue.glbOr gltf-pipeline:
npx gltf-pipeline -i venue-raw.glb -o public/models/my-scene/venue.glb -dEach option maps to an applyOption(id, value) call. Keep options to 2–3 maximum — the UI panel is narrow on phones.
Good option patterns:
-
Lighting preset — swap
PointLightdiffuse colors andHemisphericLightintensity - Layout swap — dispose and rebuild a set of meshes
-
Material toggle — swap
PBRMaterial.albedoColoror texture -
Fog density —
scene.fogMode+scene.fogDensity
Once the scene renders correctly:
- Add a screenshot to
public/screenshots/desktop-my-scene-entry.png(1920×1080) - Update
README.md— add a row to the Scenes table and a step to "Things to Try" - Update Models and Licenses — add attribution for any third-party models
A minimal diff adding a new scene looks like:
+ src/scenes/my-scene.ts (new file)
src/types.ts
+ "my-scene" added to SceneId union
src/main.ts
+ import mySceneDef from "./scenes/my-scene";
+ "my-scene": mySceneDef added to SCENES map
README.md
+ Row added to Scenes table
+ Step added to Things to Try
+ public/models/my-scene/venue.glb
+ public/screenshots/desktop-my-scene-entry.png
LICENSES.md
+ Attribution block for any new third-party models