Chapter 02Boxes (Cuboids)
Using the CreateBox
method of the MeshBuilder
class, we can make boxes and cuboids.
let box = BABYLON.MeshBuilder.CreateBox("name", {options}, scene);
The first argument of CreateBox()
is a String that we can use to retrieve the entire box and data about the box later. The second argument is an object that specifies various properties of the box. The last argument is a reference to the scene in which the box will be inserted into.
<script> var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); function createScene(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseColor = new BABYLON.Color3(0, 1, 0); let box = BABYLON.MeshBuilder.CreateBox("box", {}, scene); box.material = mat; return scene; }; var scene = createScene(canvas, engine); engine.runRenderLoop(function(){ scene.render(); }); window.addEventListener("resize", function(){ engine.resize(); }); </script> <canvas id="renderCanvas"></canvas>
Properties
Size
The size
parameter can be used to specify the height, width, and depth of the box. The default value is 1.
<script> var canvas7 = document.getElementById("renderCanvas7"); var engine7 = new BABYLON.Engine(canvas7, true); function createScene7(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 4.5, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseColor = new BABYLON.Color3(0, 1, 0); let box = BABYLON.MeshBuilder.CreateBox("box", {size: 2}, scene); box.material = mat; return scene; }; var scene7 = createScene7(canvas7, engine7); engine7.runRenderLoop(function(){ scene7.render(); }); window.addEventListener("resize", function(){ engine7.resize(); }); </script> <canvas id="renderCanvas7"></canvas>
Height, Width, and Depth
To create a cuboid whose sides have different lengths, we can use the height
, width
, and depth
parameters, which default to the value of the size parameter if not included.
<script> var canvas8 = document.getElementById("renderCanvas8"); var engine8 = new BABYLON.Engine(canvas8, true); function createScene8(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 4, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseColor = new BABYLON.Color3(0, 1, 0); let box = BABYLON.MeshBuilder.CreateBox("box", {height: 2, width: 1, depth: 2}, scene); box.material = mat; return scene; }; var scene8 = createScene8(canvas8, engine8); engine8.runRenderLoop(function(){ scene8.render(); }); window.addEventListener("resize", function(){ engine8.resize(); }); </script> <canvas id="renderCanvas8"></canvas>
Face Colors
To add color to the box we can use the faceColors
parameter. The faceColors
parameter is an array of length 6 that holds color values for each face. The default value is Color4(1, 1, 1, 1)
, which is white.
The indices of the array we used for the faceColors
parameter each correspond to a different side of the box.
<script> var canvas1 = document.getElementById("renderCanvas1"); var engine1 = new BABYLON.Engine(canvas1, true); function createScene1(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let colors = new Array(6); colors[0] = new BABYLON.Color3.Green; colors[1] = new BABYLON.Color3.Red; colors[2] = new BABYLON.Color3.Blue; colors[3] = new BABYLON.Color4(0, 0, 0, 0); colors[4] = new BABYLON.Color3.Yellow; colors[5] = new BABYLON.Color3.Yellow; let box = BABYLON.MeshBuilder.CreateBox("box", {faceColors: colors}, scene); return scene; }; var scene1 = createScene1(canvas1, engine1); engine1.runRenderLoop(function(){ scene1.render(); }); window.addEventListener("resize", function(){ engine1.resize(); }); </script> <canvas id="renderCanvas1"></canvas>
See our tutorial here for information on the color4
and color3
class.
Face UV
The faceUV
property allows us to select a specific area to crop from an image, and then apply it to the box. The default value is Vector4(0, 0, 1, 1)
, which displays the entire image on each face.
Below is a list that specifies which sides correspond to which indices in the faceUV array.
FaceUV Index | Direction of Face Normals |
---|---|
0 | +z |
1 | -z |
2 | +x |
3 | -x |
4 | +y |
5 | -y |
<script> var canvas4 = document.getElementById("renderCanvas4"); var engine4 = new BABYLON.Engine(canvas4, true); function createScene4(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/environments/numbers.jpg") mat.diffuseColor = new BABYLON.Color3.Green; let faceUV = []; faceUV[0] = new BABYLON.Vector4(0, 0, 0.166, 1); //rear face faceUV[1] = new BABYLON.Vector4(0.166, 0, .33, 1); //front face faceUV[2] = new BABYLON.Vector4(0.33, 0, 0.5, 1); //right side faceUV[3] = new BABYLON.Vector4(0.5, 0, 0.66, 1); //left side faceUV[4] = new BABYLON.Vector4(0.66, 0, .833, 1); //top face faceUV[5] = new BABYLON.Vector4(0.833, 0, 1, 1); // botttom face let box = BABYLON.MeshBuilder.CreateBox("box", {faceUV: faceUV}, scene); box.material = mat; return scene; }; var scene4 = createScene4(canvas4, engine4); engine4.runRenderLoop(function(){ scene4.render(); }); window.addEventListener("resize", function(){ engine4.resize(); }); </script> <canvas id="renderCanvas4"></canvas>
In figure 3, we use Vector4()
to apply the image to our box. We recommend looking at our Understanding Meshes chapter to review vectors in Babylon.js. The first set of parameters of Vector4()
are the bottom left coordinates of the portion of the image we want to use on the mesh. We can call these u1 and v1. The second set of parameters for Vector4()
are the upper right coordinates of the portion of the image we want to use on the mesh. We can call these u2 and v2.
To figure out what values we want to use for our arguments, we need to consider our image and the number values associated with the sides of the box.
Both length and width of our image are considered to be value 1, so the values we enter for our coordinates will be float
values between 0 and 1. We want to split our image into 6 separate sections for each box face.
Rear Face
faceUV[0] = new BABYLON.Vector4(0, 0, 0.166, 1);
The value for the rear face of the box is 0. In order for the number 0 in the image to appear on this face, we need to use vectors. In this case, the (x, y) coordinates, or the upper left coordinates, would be (0, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (1/6, 1).
Front Face
faceUV[1] = new BABYLON.Vector4(0.166, 0, .33, 1);
The index value for the front face of the box is 1. In order for the number 1 in the image to appear on this face, we need to use vectors. In this case, the (x, y) coordinates, or the upper left coordinates, would be (1/6, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (2/6, 1).
Right-side Face
faceUV[2] = new BABYLON.Vector4(0.33, 0, 0.5, 1);
The index value for the right-side face of the box is 2. We want the number 2 in the image to appear on this face. In this case, the (x, y) coordinates, or the upper left coordinates, would be (2/6, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (3/6, 1).
Left-side Face
faceUV[3] = new BABYLON.Vector4(0.5, 0, 0.66, 1);
The index value for the left-side face of the box is 3. We want the number 3 in the image to appear on this face. In this case, the (x, y) coordinates, or the upper left coordinates, would be (3/6, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (4/6, 1).
Top Face
faceUV[4] = new BABYLON.Vector4(0.66, 0, .833, 1);
The index value for the top face of the box is 4. We want the number 4 in the image to appear on this face. In this case, the (x, y) coordinates, or the upper left coordinates, would be (4/6, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (5/6, 1).
Bottom Face
faceUV[5] = new BABYLON.Vector4(0.833, 0, 1, 1);
The index value for the bottom face of the box is 5. We want the number 5 in the image to appear on this face. In this case, the (x, y) coordinates, or the upper left coordinates, would be (5/6, 0), and the (z, w) coordinates, or the bottom right coordinates, would be (1, 1).
Finding the Values Algebraically
In order to precisely calculate what part of the image we want to apply to the mesh face, we can use the number of rows and columns to find the four values for Vector4()
algebraically.
Wrap
The wrap
parameter can be used to orientate images upright on the box sides if set to true
. The default value is false
.
<script> var canvas2 = document.getElementById("renderCanvas2"); var engine2 = new BABYLON.Engine(canvas2, true); function createScene2(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/environments/numbers.jpg"); mat.diffuseColor = new BABYLON.Color3.Green; let faceUV = []; faceUV[0] = new BABYLON.Vector4(0, 0, 0.166, 1); //rear face faceUV[1] = new BABYLON.Vector4(0.166, 0, .33, 1); //front face faceUV[2] = new BABYLON.Vector4(0.33, 0, 0.5, 1); //right side faceUV[3] = new BABYLON.Vector4(0.5, 0, 0.66, 1); //left side faceUV[4] = new BABYLON.Vector4(0.66, 0, .833, 1); //top face faceUV[5] = new BABYLON.Vector4(0.833, 0, 1, 1); // botttom face let box = BABYLON.MeshBuilder.CreateBox("box", {faceUV: faceUV, wrap: true}, scene); box.material = mat; return scene; }; var scene2 = createScene2(canvas2, engine2); engine2.runRenderLoop(function(){ scene2.render(); }); window.addEventListener("resize", function(){ engine2.resize(); }); </script> <canvas id="renderCanvas2"></canvas>
topBaseAt
We can change the orientation of our texture on the top of the box using the topBaseAt
argument. The default value is 1, which means the base of the texture on the top face of the box will correspond to the side associated with index 1 of the faceUV array. This argument can take values 0, 1, 2, or 3, and the base will face the side with that index value.
The sides of the box are numbered 0 to 3 as illustrated below.
<script> var canvas5 = document.getElementById("renderCanvas5"); var engine5 = new BABYLON.Engine(canvas5, true); function createScene5(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/environments/numbers.jpg") mat.diffuseColor = new BABYLON.Color3.Green; let faceUV = []; faceUV[0] = new BABYLON.Vector4(0, 0, 0.166, 1); faceUV[1] = new BABYLON.Vector4(0.166, 0, .33, 1); faceUV[2] = new BABYLON.Vector4(0.33, 0, 0.5, 1); faceUV[3] = new BABYLON.Vector4(0.5, 0, 0.66, 1); faceUV[4] = new BABYLON.Vector4(0.66, 0, .833, 1); faceUV[5] = new BABYLON.Vector4(0.833, 0, 1, 1); let box = BABYLON.MeshBuilder.CreateBox("box", {faceUV: faceUV, wrap: true, topBaseAt: 3}, scene); box.material = mat; return scene; }; var scene5 = createScene5(canvas5, engine5); engine5.runRenderLoop(function(){ scene5.render(); }); window.addEventListener("resize", function(){ engine5.resize(); }); </script> <canvas id="renderCanvas5"></canvas>
bottomBaseAt
We can change the orientation of our texture on the bottom face of the box using the bottomBaseAt
argument. The default value is 1, which means the base of the texture on the bottom face of the box will correspond to the side associated with index 1 of the faceUV array. This argument can take values 0, 1, 2, or 3, and the base will face the side with that index value in the faceUV array.
The sides of the box are numbered 0 to 3 as illustrated below.
<script> var canvas3 = document.getElementById("renderCanvas3"); var engine3 = new BABYLON.Engine(canvas3, true); function createScene3(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 4, 2.5 * Math.PI / 3, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 0, 0), scene); let mat = new BABYLON.StandardMaterial("boxMat"); mat.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/environments/numbers.jpg") mat.diffuseColor = new BABYLON.Color3.Green; let faceUV = []; faceUV[0] = new BABYLON.Vector4(0, 0, 0.166, 1); faceUV[1] = new BABYLON.Vector4(0.166, 0, .33, 1); faceUV[2] = new BABYLON.Vector4(0.33, 0, 0.5, 1); faceUV[3] = new BABYLON.Vector4(0.5, 0, 0.66, 1); faceUV[4] = new BABYLON.Vector4(0.66, 0, .833, 1); faceUV[5] = new BABYLON.Vector4(0.833, 0, 1, 1); let box = BABYLON.MeshBuilder.CreateBox("box", {faceUV: faceUV, wrap: true, bottomBaseAt: 3}, scene); box.material = mat; return scene; }; var scene3 = createScene3(canvas3, engine3); engine3.runRenderLoop(function(){ scene3.render(); }); window.addEventListener("resize", function(){ engine3.resize(); }); </script> <canvas id="renderCanvas3"></canvas>
Updatable
If we want the box to be able to have its internal geometry changed after creation, we can set the parameter updatable
equal to true
. The default value is false
.
Side Orientation
The sideOrientation
property allows us to make our box double-sided. The default value is FRONTSIDE
.
The different values for the sideOrientation
property are:
FrontUVs and BackUVs
If the mesh is double-sided, we can choose what parts of a texture image to crop and stick on the front and back sides of the box with the frontUVs
and backUVs
parameters, respectively.
<script> var canvas6 = document.getElementById("renderCanvas6"); var engine6 = new BABYLON.Engine(canvas6, true); function createScene6(canvas, engine){ let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1, 1, 1); let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 3, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene); let front = new BABYLON.Vector4(0, 0, 1/6, 1); let back = new BABYLON.Vector4(1/3, 0, 1/6, 1); let mat = new BABYLON.StandardMaterial("mat"); mat.diffuseTexture = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/fur.jpg") mat.diffuseColor = new BABYLON.Color3.Green; let box = BABYLON.MeshBuilder.CreateBox("box", {frontUVs: front, backUVs: back}, scene); box.material = mat; return scene; }; var scene6 = createScene6(canvas6, engine6); engine6.runRenderLoop(function(){ scene6.render(); }); window.addEventListener("resize", function(){ engine6.resize(); }); </script> <canvas id="renderCanvas6"></canvas>