Chapter 02Cylinders and Cones

Using the CreateCylinder method of the MeshBuilder class, we can make cylinders, cones, triangular prisms, and ratios of cylinders.

let cylinder = BABYLON.MeshBuilder.CreateCylinder("name", {options}, scene);

The first argument of CreateCylinder() is a String that we can use to retrieve the entire cylinder mesh and data about the cylinder later. The second argument is an object that specifies various properties of the cylinder. The last argument is a reference to the scene in which the cylinder 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", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {}, scene);
    cylinder.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>
Figure 1. Default Babylon.js cylinder.

Properties

Height

The height property can be used to specify the height of the cylinder. The default value is 2.

<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, 6, 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", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {height: 3}, scene);
    cylinder.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>
Figure 2. The height property of the cylinder is set to 5.

Diameter

The diameter property allows us to specify the diameter of the entire cylinder. The default value is 1.

<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, 6, 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", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
    
    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {diameter: 3}, scene);
    cylinder.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>
Figure 3. The diameter property of the cylinder is set to 3.

Diameter Top and Diameter Bottom

The diameterTop and diameterBottom properties allow us to specify the diameter of the top and bottom of the cylinder, respectively. The default value for both is 1.

If we want to make the cylinder into a cone, we can change the value of either diameterTop or diameterBottom to 0.

<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 mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {diameterTop: 0}, scene);
    cylinder.material = mat;

    return scene;
};

var scene1 = createScene1(canvas1, engine1);

engine1.runRenderLoop(function(){
    scene1.render();
});

window.addEventListener("resize", function(){
    engine1.resize();
});
</script>

<canvas id="renderCanvas1"></canvas>
Figure 4. The diameterTop property is set to 0, which turns our cylinder into a cone.

Tessellation

The tessellation property specifies the number of radial sides on our cylinder. The more sides the cylinder has, the smoother and more cylindrical it is. The default value is 24.

<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, 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", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
    mat.wireframe = true;
    
    let cylinder1 = BABYLON.MeshBuilder.CreateCylinder("cylinder1", {tessellation: 3}, scene);
    cylinder1.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>
Figure 5. The tessellation property of the cylinder is set to 3. This makes the cylinder have 3 sides, and therefore look like a triangular prism.

Subdivisions

The subdivisions property allows us to specify the number of horizontal segments on the sides of the cylinder. 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 / 2, Math.PI / 3, 6, 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);
    mat.wireframe = true;

    let cylinder1 = BABYLON.MeshBuilder.CreateCylinder("cylinder1", {tessellation: 3, subdivisions: 1}, scene);
    cylinder1.material = mat;
    cylinder1.position = new BABYLON.Vector3(-3, 0, 0);
    
    let cylinder2 = BABYLON.MeshBuilder.CreateCylinder("cylinder2", {tessellation: 3, subdivisions: 2}, scene);
    cylinder2.material = mat;
    cylinder2.position = new BABYLON.Vector3(-1, 0, 0);
    
    let cylinder3 = BABYLON.MeshBuilder.CreateCylinder("cylinder3", {tessellation: 3, subdivisions: 3}, scene);
    cylinder3.material = mat;
    cylinder3.position = new BABYLON.Vector3(1, 0, 0);
    
    let cylinder4 = BABYLON.MeshBuilder.CreateCylinder("cylinder4", {tessellation: 3, subdivisions: 4}, scene);
    cylinder4.material = mat;
    cylinder4.position = new BABYLON.Vector3(3, 0, 0);

    return scene;
};

var scene7 = createScene7(canvas7, engine7);

engine7.runRenderLoop(function(){
    scene7.render();
});

window.addEventListener("resize", function(){
    engine7.resize();
});
</script>

<canvas id="renderCanvas7"></canvas>
Figure 6. The cylinders above have their subdivision properties set to, in order, 4, 3, 2, and 1.

Face Colors

The faceColors parameter allows us to use color4 to add color to the cylinder. The default value is color4(1, 1, 1, 1), which is white.

<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 colors = new Array(3);

    colors[0] = new BABYLON.Color4(0, 1, 0, 1);
    colors[1] = new BABYLON.Color3.Green;
    colors[2] = new BABYLON.Color3(1, 0, 0);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {faceColors: colors}, scene);
    return scene;
};

var scene5 = createScene5(canvas5, engine5);

engine5.runRenderLoop(function(){
    scene5.render();
});

window.addEventListener("resize", function(){
    engine5.resize();
});
</script>

<canvas id="renderCanvas5"></canvas>
Figure 7. The faceColors property uses an array to set the sides to green, the top to red, and the bottom to blue.

We can change the colors of the cylinder by making an array of 3 where the bottom of the cylinder is at index 0, the side of the cylinder is at index 1, and the top of the cylinder is at index 2.

See our tutorial on colors here for information on the color4 and color3 class.

FaceUV

The faceUV property allows us to select a specific area to crop from an image, and then apply it to the faces of the cylinder. To change the faceUV values, we can make an array.

<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, Math.PI / 3, 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(0, 1, 0);

    let faceUV = [];
    faceUV[0] = new BABYLON.Vector4(0, 0, 1/6, 1);
    faceUV[1] = new BABYLON.Vector4(1/3, 0, 1/6, 1);
    faceUV[2] = new BABYLON.Vector4(1/3, 0, 1/2, 1);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {faceUV: faceUV}, scene);
    cylinder.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>
Figure 8. We apply a texture to the cylinder using faceUV so that 0 appears on the side with index 0, 1 appears on the side with index 1, and 2 appears on the side with index 2.

Below is a list that specifies which sides correspond to which indices in the faceUV array, as shown in figure 8. These values are consistent even when we adjust the tessellation of the cylinder.

FaceUV Index Direction of Face Normals/Face
0 Bottom of cylinder, -y
1 Sides of cylinder, -x, +x, -z, +z
2 Top of cylinder, +y

Arc

The arc property affects the ratio of the circumference of the cylinder that is visible in the scene. The default value is 1. We can change the value to a number between 0 and 1 to change the ratio.

<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 / 2, Math.PI / 3, 6, 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", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
    
    let cylinder1 = BABYLON.MeshBuilder.CreateCylinder("cylinder1", {arc: 0.25, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
    cylinder1.material = mat;
    cylinder1.position = new BABYLON.Vector3(-3, 0, 0);
    
    let cylinder2 = BABYLON.MeshBuilder.CreateCylinder("cylinder2", {arc: 0.5, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
    cylinder2.material = mat;
    cylinder2.position = new BABYLON.Vector3(-1, 0, 0);
    
    let cylinder3 = BABYLON.MeshBuilder.CreateCylinder("cylinder3", {arc: 0.75, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
    cylinder3.material = mat;
    cylinder3.position = new BABYLON.Vector3(1, 0, 0);
    
    let cylinder4 = BABYLON.MeshBuilder.CreateCylinder("cylinder4", {arc: 1, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
    cylinder4.material = mat;
    cylinder4.position = new BABYLON.Vector3(3, 0, 0);
    
    return scene;
};

var scene8 = createScene8(canvas8, engine8);

engine8.runRenderLoop(function(){
    scene8.render();
});

window.addEventListener("resize", function(){
    engine8.resize();
});
</script>

<canvas id="renderCanvas8"></canvas>
Figure 8. The cylinders above have their arc properties set to, in order, 1, 0.75, 0.5, and 0.25.

Updatable

If we want the cylinder to be able to have its internal geometry changed after creation, we can set the Boolean parameter updatable equal to true. The default value is false.

Side Orientation

The sideOrientation property allows us to make our sphere doubled-sided, which is especially useful when we use the arc property. The default value FRONTSIDE.

The different values for the sideOrientation property are:

FrontUVs and BackUVs

If the cylinder is double-sided, we can choose what parts of a texture to crop and stick on the front and back sides of our mesh with the fontUVs and backUVs properties, respectively. The default value for both is Vector4(0, 0, 1, 1), which sticks the entire image to the face.

<script>
var canvas0 = document.getElementById("renderCanvas0");
var engine0 = new BABYLON.Engine(canvas0, true);

function createScene0(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(0, 1, 0);

    let front = new BABYLON.Vector4(0, 0, 1/6, 1);
    let back = new BABYLON.Vector4(1/6, 0, 1/3, 1);

    let cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {arc: 0.75, sideOrientation: BABYLON.Mesh.DOUBLESIDE, frontUVs: front, backUVs: back}, scene);
    cylinder.material = mat;
    
    return scene;
};

var scene0 = createScene0(canvas0, engine0);

engine0.runRenderLoop(function(){
    scene0.render();
});

window.addEventListener("resize", function(){
    engine0.resize();
});
</script>

<canvas id="renderCanvas0"></canvas>
Figure 9. A cylinder which utilizes the frontUV, backUV, and sideOrientation properties.

As seen in figure 9 above, the frontUV property applies the texture to all the front areas of the cylinder, including the top, bottom, and sides of the cylinder. The backUV cylinder applies the texture to all back areas of the cylinder.

References