Babylon JS Day 11

I’m kicking off Week 3 of A Month of Babylon JS by diving into a week-long project to present some data as interactive cards in 3D. My Friday Project this week will involve building some VR interaction for these cards. For now, I’m going to focus on the data and the layout of the cards.

Getting the data

In the interest of saving time, I decided to use the blog posts in this series as the data source for the cards. Rather than spend any time on an API to build this data, I used the XML in my RSS feed. Since my site is built on WordPress, the RSS feed has query parameters built right in. All the posts in this series are tagged with a value of babylon-month so the url to get the data is:

I’m not spending any time on the backend of this project, so I’ll just serve the data as a JSON file. I converted it from the RSS XML to JSON with this site. I know… Lazy Joe. The data is hosted on my WebXR Sandbox site here.

Loading the data

Something that caught my attention last week was a reference to a method called addTextFileTask on the Asset Manager. I can use this to load the JSON file, then parse the text as JSON, and pass it to a function that will iterate over it to create cards in the scene.

 var assetsManager = new BABYLON.AssetsManager(scene);

  const dataPath = "";
  assetsManager.addTextFileTask("babylon-month", dataPath).onSuccess = function (task) {
    const parsed = JSON.parse(task.text);
    createCards(scene, parsed.items); // this function will append 3d card objects to the scene

3D GUI in Babylon JS

I didn’t have much time left to work on the cards today, but I got a head start on tomorrow by checking out the 3D GUI features of Babylon JS. For now, I just used some sample code from the Plane Panel example. This will create a panel object, then loop over the array of items, creating a HolographicButton object for each one. Not perfect, but good enough for today.

function createCards(scene, items) {
  // Create the 3D UI manager
  var anchor = new BABYLON.TransformNode("");
  var manager = new BABYLON.GUI.GUI3DManager(scene);

  var panel = new BABYLON.GUI.PlanePanel();
  panel.margin = 0.2;

  panel.position.z = -1.5;

  // Let's add some buttons!
  var addButton = function (item) {
    var button = new BABYLON.GUI.HolographicButton("orientation");
    button.text = item.title;

  panel.blockLayout = true;
  for (item of items) {

  panel.blockLayout = false;
A Plane Panel with some placeholder objects.

Tomorrow I’ll start working on the 3D card object itself. Then I’ll replace the buttons in the sample code above with the new object.

Babylon JS Day 10: Terrarium

This week for my Friday Project I decided that I wanted to build a simple Terrarium with some low poly assets. My main objectives was to learn about composing a scene in Babylon JS. I started with the table/base that I made on Day 8 and what I learned about asset loading on Day 9.

I’m almost embarrassed to admit that I spent most of the day working with the asset files and trying to get them loaded into the scene. I ran into some issue with obj files where sometimes the related mtl file would just not show up in the scene. Eventually I decided to convert the models to glb file instead. Lucky for me I had a copy of the Blender project for each file, so it was just a matter of opening the Blender project and exporting the model and material as a glb file. I ended up with 13 models that I added to the scene using the assetsManager.

// Asset loading example
 var assetsManager = new BABYLON.AssetsManager(scene);

  const path = "../assets/models/";

  // Trees
  assetsManager.addMeshTask("mesh task", "", path, "Tree1.glb").onSuccess = function (task) {
    task.loadedMeshes[0].position = new BABYLON.Vector3(5, 0, 6);
    task.loadedMeshes[0].rotation = new BABYLON.Vector3(0, 30, 0);

    task.loadedMeshes[0].name = "Tree1";

// Many more files loaded....


One interesting side note: files loaded this way are not named in the scene graph, but I found out that I can set the name property of the loaded mesh. This made it easier to work with these models in the Babylon JS inspector.

I wanted to use some of the models more than once, so I learned how to use the clone() method on a mesh. I created these clones right in the .onSuccess call after loading an asset. For example, I wanted a small stand of trees using the Tree3 model. I used the one imported in the loadedMeshes results array as the first instance in the scene, then cloned it twice for the other instances.

assetsManager.addMeshTask("mesh task", "", path, "Tree3.glb").onSuccess = function (task) {
    task.loadedMeshes[0].position = new BABYLON.Vector3(6.5, 0, -4);
    task.loadedMeshes[0].name = "Tree3";

    tree3Clone1 = task.loadedMeshes[0].clone("Tree3Clone1");
    tree3Clone1.position = new BABYLON.Vector3(5, 0, -1);
    tree3Clone1.rotation = new BABYLON.Vector3(0, -70, 0);
    tree3Clone1.scaling = new BABYLON.Vector3(1.2, 1.2, 1.2);

    tree3Clone2 = task.loadedMeshes[0].clone("Tree3Clone2");
    tree3Clone2.position = new BABYLON.Vector3(6.5, 0, -1.5);
    tree3Clone2.rotation = new BABYLON.Vector3(0, 50, 0);
    tree3Clone2.scaling = new BABYLON.Vector3(0.9, 1.2, 0.9);

I spent more time than I care to admit just deciding where on this small table to place everything. This is what I ended up with for now.

One small touch at the end of the day was adding some animations to the camera. I found an interesting Playground on the Babylon JS forum that gave me some ideas using a timeouts to move the camera around the scene. When the scene loads, these animations will play out over a period of 12 seconds, mainly to demonstrate that you can move the camera around the scene.

When I started out this morning, my plans included many more features. I wanted to add some animals that would move around the scene. I also intended to create a soundtrack and some simple sound effects. Don’t get me started about clouds… Not to mention the dome that is supposed to cover the Terrarium. I just ran out of time. Even with this Friday Project complete, I may keep working on this scene. It could make an interesting place to try new concepts as I learn them.

Try the scene out for yourself here.

Babylon JS Day 9

Today was all about working with assets. The project that I’m going to work on tomorrow involves several models, textures, and audio files. Today I wanted to learn how to create a scene while loading assets from the server.

I got started by revisiting the scene I made yesterday. I cleaned up the code a little and made a Babylon JS Playground out of it. You can check it out here.

I saved this scene as a .babylon file and added it to my project. This was the first attempt at loading it into my scene. I only needed to load the mesh, not the rest of the scene, so I passed the “stand” value as the name of the mesh.

BABYLON.SceneLoader.ImportMeshAsync("stand", "../assets/scenes/", "terrarium-base.babylon");

Then I shifted my attention to loading some third-party assets. I’ve followed a low poly artist named @quaternius for a few years, and I support them on Patreon. One of the benefits I get is a full zip archive of all their models. I’m going to use a few of these tomorrow so I wanted to learn how to load them into my scene.

I spent a bit of time reading the documentation for importing assets. Two pages provided what I was after.

  1. Loading Any File Type has instructions for loading a variety of file types.
  2. Asset Manager is an awesome feature that will let me define loading tasks for all my assets at once. I can even provide some code to execute on success.

Below is an example of the asset manager that I created. For now, this loads the .babylon scene file that I mentioned above, along with an .obj (the .mtl file is imported automatically) and a texture atlas. You can see that the onSuccess call for the texture will assign the texture to a material. When the flower task succeeds, I assign a position and the material. At the end of all of this I can the load() method on the asset manager object, right before the scene loads. As far as I can tell, Babylon JS will load all the assets before starting the scene.

  var assetsManager = new BABYLON.AssetsManager(scene);
  var flowerMat = new BABYLON.StandardMaterial("baseMat", scene);

  var textureTask = assetsManager.addTextureTask("image task", "../assets/models/textures/palette_32x32.png");
  textureTask.onSuccess = function (task) {
    flowerMat.diffuseTexture = task.texture;
  var meshTask = assetsManager.addMeshTask("flower task", "", "../assets/models/", "flower.obj");
  meshTask.onSuccess = function (task) {
    task.loadedMeshes[0].position = BABYLON.Vector3.Zero();
    task.loadedMeshes[0].material = flowerMat;
  meshTask.onError = function (task, message, exception) {
    console.log(message, exception);

  var baseTask = assetsManager.addMeshTask("base task", "", "../assets/scenes/", "terrarium-base.babylon");
  baseTask.onSuccess = function (task) {
    // Nothing to do for now
  baseTask.onError = function (task, message, exception) {
    console.log(message, exception);


I still have a lot to learn about working with assets in a Babylon JS project, but I now have enough knowledge to move forward with my project tomorrow.

How to export a scene from the Babylon JS Playground

When working with a Babylon JS Playground, you can export your scene as a GLB or BABYLON file. The only issue is that I keep forgetting how do to this :face-palm

Click on the little toolbox icon in the playground to open the inspector.

Open the Babylon JS Inspector on a Playground
Open the Babylon JS Inspector on a Playground

Then click on the wrench icon in the bottom section of the inspector. Scroll down until you see the Scene Export section.

Scene Export
Scene Export

Babylon JS Day 8

Today I broke away from structured reading and gave myself some time to play and create. I already have an idea of what I want to do for the project this Friday, so I spent my time today creating a scene and some basic features that I’ll need later. I’ll go into more detail regarding the project on Friday.

For now, I focused on a few things: camera, lighting, background color, and a basic pedestal to build on.


I referred to my notes last week to help construct an Arc Rotate camera. This camera will allow a visitor to rotate around a fixed point. Notice the call to upperBetaLimit. I remembered seeing this in the Getting Started guide last week. This will let me stop the camera from moving below a certain point. The scene I’m making is basically on top of a table, so I don’t want the camera to go below the table. The calls to lowerRadiusLimit and upperRadiusLimit allow me to constrain the zoom level of the camera.

  const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
  camera.upperBetaLimit = Math.PI / 2.2;
  camera.lowerRadiusLimit = 10;
  camera.upperRadiusLimit = 50;
  camera.setPosition(new BABYLON.Vector3(0, 15, -28));
  camera.attachControl(canvas, true);

Lighting and Background

This is simple for now. I changed the background color of the scene and positioned some lights. I included both a directional light and a hemispheric light.

  scene.clearColor = BABYLON.Color3.FromHexString("#b1d5fa");

  const ambientLight = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 10, 0));
  const directionalLight = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, -3), scene);


I throught of several ideas for creating the mesh for the table/pedestal before I settled on the Lathe. I referred to the example from the Getting Started guide where we created a fountain. I did something similar for my pedestal.

  const baseMat = new BABYLON.StandardMaterial("baseMat", scene);
  baseMat.diffuseColor = new BABYLON.Color3.FromHexString("#6e6d7c");
  baseMat.specularColor = new BABYLON.Color3(0.2, 0.2, 0.2);

  const standProfile = [
    new BABYLON.Vector3(0, 0, 0),
    new BABYLON.Vector3(8, 0, 0),
    new BABYLON.Vector3(8, 1, 0),
    new BABYLON.Vector3(7, 1, 0),
    new BABYLON.Vector3(7, 0.5, 0),
    new BABYLON.Vector3(1, 0.5, 0),
    new BABYLON.Vector3(1, 15, 0),
    new BABYLON.Vector3(3, 17, 0),
    new BABYLON.Vector3(10, 18, 0),
    new BABYLON.Vector3(10, 19, 0),
    new BABYLON.Vector3(0, 19, 0)

  const stand = BABYLON.MeshBuilder.CreateLathe(
    { tessellation: 24, shape: standProfile, sideOrientation: BABYLON.Mesh.DOUBLESIDE },
  stand.material = baseMat;
  stand.position = new BABYLON.Vector3(0, -17, 0);

At the end of my time today I was left with the building blocks that I’ll use on Friday.

A simple pedestal that I’m going to use for a project

Babylon JS Day 7

I spent my education time today reading the documentation for the GUI system in Babylon JS. This came with a ton of playgrounds to look at, some that included interesting examples of the core features. Highlights include:

  • There are two main GUI modes.
    • Full Screen (screen-space) can be used to create HUDS, overlays, menus
    • Texture Mode can render the contents of a GUI on a texture attached to the face of a mesh. This second option is useful for some of the VR interfaces that I want to build.
  • The core component for GUI is the AdvancedDynamicTexture. This organizes and renders controls that are attached to it.
  • This GUI system comes with a ton of pre-built controls. Some examples are text views, text inputs, password fields, buttons, checkboxes, radio button sets, and sliders. I played around with a few of these and many of them have a decent amount of customization built in.
  • Contains are a way to organize controls in a GUI. Babylon JS has several containers. The one that stands out to me is the StackPanel. If I these can be embedded in other StackPanels then this opens a huge array of layout possibilities.
  • Position, size, padding, etc. all support pixels and percentages. Some containers require the use of pixels.

Overall, it seems like Babylon JS has a lot to offer as far as GUI is concerned. I haven’t even had time to investigate the more interesting 3D GUI. At some point I want to build a GUI for the Breathe demo that I made last week. I’d like to allow guests to set their own timing values and perhaps even include a handful of presets.

Babylon JS Day 6

Today was a bit of a waste of time. When deciding what to learn this week I gave myself two main options.

  1. Pick a handful of topics from the Diving Deeper documentation. Work through these topics with the goal of expanding what I learned last week.
  2. Work through the Create a Game guided learning documentation. This claims to be a step-by-step guild to show some of the common development pattens for making a game in Babylon JS.

I’m not interested in making games, but option two presented a good chance to see how to work with Babylon JS on a larger project, so that is what I spent my time on today.

I didn’t make it far. It turns out that this tutorial is based on TypeScript and involves a ton of project setup and dependencies. I followed along with the documentation as well as I could, but the result was a broken project. As far as I can tell, all modules and dependencies are installed but I can’t build and run the project. I even tried cloning the entire sample project from the provided repo, and that one would not work either.

I’m not going to spend any more time on it. I should have bailed out as soon as I saw the word TypeScript… I know there are a ton of developers who swear by NPM, node modules, webpack, etc. to build their projects, but I just want keep things simple for now. Tomorrow I’m going to start looking at the Diving Deeper documentation that I mentioned above, and I’m going to return to a simple project without all the build tools, config files, and dependencies.

Babylon JS Day 5: Breathe

As I wrote about on Monday, the last day of each week in March I’m taking some time to work on a series of small projects built in Babylon JS. Today I got started with a simple breathing animation. I wanted something similar to the Breathe App on Apple Watch, but I wanted to control the timing animations and add my own sounds.

TL; DR: You can try out the scene on my WebXR Sandbox Site.

If you click the link above, you will see black scene with a sphere in the center. The sphere will grow and shrink over time to indicate the pace of the breathing exercise I’ve been learning. This is based on a pattern of breathing I read about in Breath: The New Science of a Lost Art by James Nestor. Breathe in for 5.5 seconds, breathe out for 5.5 seconds. Pretty simple.


This project didn’t get much attention as far as graphics are concerned. I have a simple icosphere that is placed at the world origin. It has a material with an emissiveColor set to #8c1eff. The only light source is a hemisphere light with a diffuse value of #ff2975 and a specular value of #8c1eff. This combination of material and lighting gave me something that I liked so I moved on to the animations.

Expanded breathing sphere


In the case of this scene, the animations are broken into four segments (five if you count the starting point). These values are hardcoded for now, but in the future, I want to make these something that guests can modify.

0 (start)Base Size
1.5 secondsBase Size, play the wait sound
4 secondsExpanded Size, plan the breathe-in sound
1.5 secondsExpanded Size, play the wait sound
4 secondsBase Size, play the breathe-out sound
Animation sequencing used in the initial Breathe project.

Animations in Babylon JS can only affect a sole property, so I had to create several animations to scale the sphere on all three axes. I set the animation frame rate to 30 and created keyframe for each of the items in the table above. In each keyframe I multiplied the time in the sequence by the frame rate. Babylon JS has an interesting way to call events on a specified frame (maybe I could use this to clean up my redundant code?). I used these animation events to call the play() method on the sound objects. Finally, the animation is set to loop.


Overall, I’m happy with the result. I have a simple breathing animation that I can use to help myself learn this breathing pace, and I was able to use several things that I learned throughout the week. In the future I’ll expand this to include some other breathing patterns and add some customizable elements.

This weekend I’ll review my notes from this past week and plan for what I should learn next week. Every area that I covered in the Getting Started guide has an expanded section of documentation available, so I don’t think I’ll run out of things to learn anytime soon.

Here is a copy of the source code for the scene. I didn’t spend any time making this code pretty. I used the Babylon JS Playground Template as a starting point and did all the work in the createScene() function.

const canvas = document.getElementById("renderCanvas"); // Get the canvas element
const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

var shapeColor = "#8c1eff";

// Editable time sets for the animation segments
var set1 = 1.5;
var set2 = 4;
var set3 = 1.5;
var set4 = 4;

// Add scene code here
const createScene = () => {
  const scene = new BABYLON.Scene(engine);
  scene.clearColor = BABYLON.Color3.Black();

  const camera = new BABYLON.ArcRotateCamera("camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0));
  camera.setPosition(new BABYLON.Vector3(0, 0, -20));
  // camera.attachControl(canvas, true);

  const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, -0.5, 10));
  light.diffuse = new BABYLON.Color3.FromHexString("#ff2975");
  light.specular = new BABYLON.Color3.FromHexString("#8c1eff");

  const mat1 = new BABYLON.StandardMaterial("mat1", scene);
  mat1.emissiveColor = new BABYLON.Color3.FromHexString(shapeColor);

  // Create some sound objects
  const breathIn = new BABYLON.Sound("breathIn", "../assets/audio/BreathIn.mp3", scene);
  const breathOut = new BABYLON.Sound("breathOut", "../assets/audio/BreathOut.mp3", scene);
  const breathWait = new BABYLON.Sound("breathWait", "../assets/audio/BreathWait.mp3", scene);

  // Create a mesh
  let shape1 = BABYLON.MeshBuilder.CreateIcoSphere("shape1", { radius: 1, flat: false, subdivisions: 16 }, scene);
  shape1.material = mat1;

  // Setup for animations
  let frameRate = 30;

  const keyFrames = [];
  let seg1 = set1;
  let seg2 = set1 + set2;
  let seg3 = set1 + set2 + set3;
  let seg4 = set1 + set2 + set3 + set4;
  var totalTime = seg1 + seg2 + seg3 + seg4;

    frame: 0,
    value: 0.5

    frame: seg1 * frameRate,
    value: 0.5

    frame: seg2 * frameRate,
    value: 2.5

    frame: seg3 * frameRate,
    value: 2.5

    frame: seg4 * frameRate,
    value: 0.5

  const scaleX = new BABYLON.Animation(

  const playIn = new BABYLON.AnimationEvent(
    seg1 * frameRate,
    function () {;
  const playWait = new BABYLON.AnimationEvent(
    (seg2 - 0.5) * frameRate,
    function () {;
  const playOut = new BABYLON.AnimationEvent(
    seg3 * frameRate,
    function () {;
  const playWait2 = new BABYLON.AnimationEvent(
    (seg4 - 0.5) * frameRate,
    function () {;

  const scaleY = new BABYLON.Animation(
  const scaleZ = new BABYLON.Animation(


  var easingFunction = new BABYLON.QuadraticEase();

  // For each easing function, you can choose beetween EASEIN (default), EASEOUT, EASEINOUT

  // Adding easing function to my animation

  console.log("total time:", totalTime);
  scene.beginAnimation(shape1, 0, totalTime * frameRate, true);

  return scene;

// Call the scene
const scene = createScene(); //Call the createScene function

// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {

Babylon JS Day 4

Today I completed the final two chapters of the Babylon JS Getting Started guide. These chapters focused mostly on lighting and cameras, but also briefly touched on GUI. Today’s interesting items are

  • Babylon JS has all the common 3D lighting types that I would expect. It has point, directional, spot, and hemispheric (ambient) lights.
  • Hemispheric lights don’t cast shadows, so for most scenes where I want shadows, I’ll need to add a directional light.
  • Adding shadows is a bit more involved than other platforms I’ve worked in. In addition to adding a light source that can cast shadows, I’ll need to add a `ShadowGenerator` to the scene. Then I need to add meshes that can cast shadows to the generater via the `addShadowCaster` method. Objects that need to receive shadows need to have the `receiveShadows` property flag set to true.
  • Babylon JS has several camera types. I’ve been using the `ArcRotateCamera` for most of the demo scenes so far. Interestingly, this camera can be attached to an object as a child to create a basic third-person camera view.
  • There is also a handy camera called `FollowCamera` that does what it says on the tin. Instead of attaching the camera to an object, I can just pass it the name of a mesh to track. This is useful when I want to have a camera track several objects over time in a scene.

This concludes my tour of the basics of Babylon JS. At this point I have a better idea of what Babylon JS has to offer and I’m started to get a feel for how it implements common features, how the API is structured. Tomorrow I’m going to dive into my first “project day” where I’ll try to build something (or several things) with what I’ve learned this week.

Babylon JS Day 3

Today I covered chapters five and six of the Babylon JS Getting Started guide. These chapter gave me a quick tour around some of the environmental features of Babylon JS. Notable items include

  • Ground planes/objects can be created with grayscale heightmaps. I’ve done this in Unity a few times. Nice to know this is available to me in Babylon.
  • Building skyboxes from images seems like sort of a nuisance. It’s good to know how to do this but most of the projects I want to build will use simple color or gradient skyboxes.
  • Babylon JS supports using sprites in 3D scenes as a type of billboard object. These will always face the camera. While this looks great in 3D scenes on desktop or mobile, these always look bad to me when I see them in VR.
  • Babylon JS has a nifty particle system. I could easily get lost with a feature like this and spend a great deal of time working on nothing but particles. Perhaps I’ll make one of my Friday Projects based around particles…
  • Bonus: I learned about another advanced modeling method called CreateLathe. You pass it an array of Vector3 points (along the same z plane) and it will create a 3D object. Super cool! I’ve used stuff like this in Blender before but to see this happen with just a few lines of JavaScript blew my mind.
1 2 3 4 5