First Render

BookNest's Empty Bookstore Room: A First Render

BookNest's bookstore starts as an empty room 8 m wide, 6 m deep and 3 m high (glTF and WebXR use meters), seen like a doll's house with the front wall off. A TransformNode groups the floor and walls:

BookNest's empty bookstore roomHTMLLive
<canvas id="view" style="width: 620px; height: 230px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script>
{
  const engine = new BABYLON.Engine(view, true, {}, true);
  const scene = new BABYLON.Scene(engine);
  scene.clearColor = BABYLON.Color4.FromHexString('#cfd8dcff');
  new BABYLON.HemisphericLight('sky', new BABYLON.Vector3(0.3, 1, -0.4), scene)
    .groundColor = new BABYLON.Color3(0.35, 0.32, 0.3);
  new BABYLON.ArcRotateCamera('overview', -Math.PI / 2, 1.05, 10, new BABYLON.Vector3(0, 1, 0),
    scene);
  const room = new BABYLON.TransformNode('room', scene);
  const paint = (mesh, hex) => {                        // matte color, child of the room
    mesh.material = new BABYLON.StandardMaterial(hex, scene);
    mesh.material.diffuseColor = BABYLON.Color3.FromHexString(hex);
    mesh.material.specularColor = BABYLON.Color3.Black();
    mesh.parent = room;
  };
  paint(BABYLON.MeshBuilder.CreateGround('floor', { width: 8, height: 6 }, scene), '#b08d6a');
  const walls = [['back', 8, 0, 3], ['left', 6, -4, 0], ['right', 6, 4, 0]];
  for (const [name, width, x, z] of walls) {
    const wall = BABYLON.MeshBuilder.CreateBox(name, { width, height: 3, depth: 0.15 }, scene);
    wall.position.set(x, 1.5, z);
    wall.rotation.y = x ? Math.PI / 2 : 0;              // side walls turn a quarter
    paint(wall, '#fff3e0');
  }
  scene.executeWhenReady(() => engine.runRenderLoop(() => scene.render()));
  scene.onAfterRenderObservable.add(() => { window.__done = scene.getFrameId() > 3; });
}
</script>
Browser output of Listing 7.9
Browser output of 9

The walls are boxes, so they have thickness and can take a window (CSG2). The last two lines are this chapter's figure idiom: draw once shaders and textures are ready, and let the capture shoot after a few frames. demos/ch07/bookstore.js keeps this code for later sections as BookNestStore.createScene(engine), createRoom(scene) (room node, floor, walls) and renderWhenReady(engine, scene), plus BOOKS, the six books.