Meshes and Geometry
Meshes are the 3D objects that populate your scene. Babylon.js provides comprehensive tools for creating, manipulating, and optimizing meshes, from built-in primitive shapes to complex imported models.
Babylon.js includes a variety of parametric shapes through the MeshBuilder class:
// Create a sphere
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {
diameter: 2,
segments: 32,
updatable: true // Allow geometry to be modified later
}, scene);
// Create a box/cube
const box = BABYLON.MeshBuilder.CreateBox("box", {
size: 2, // Size in all dimensions
width: 3, // Override specific dimensions
height: 1,
depth: 2,
faceColors: [ // Color each face differently
new BABYLON.Color4(1,0,0,1), // red front
new BABYLON.Color4(0,1,0,1), // green back
BABYLON.Color4.Blue(), // blue top
BABYLON.Color4.White(), // white bottom
BABYLON.Color4.Yellow(), // yellow right
BABYLON.Color4.Cyan() // cyan left
]
}, scene);
// Create a plane
const plane = BABYLON.MeshBuilder.CreatePlane("plane", {
width: 10,
height: 5,
sideOrientation: BABYLON.Mesh.DOUBLESIDE // Visible from both sides
}, scene);
// Create a cylinder
const cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", {
height: 3,
diameterTop: 1,
diameterBottom: 2,
tessellation: 24, // Number of segments around circumference
subdivisions: 1 // Number of height segments
}, scene);
// Create a torus (donut)
const torus = BABYLON.MeshBuilder.CreateTorus("torus", {
diameter: 5,
thickness: 1,
tessellation: 32
}, scene);
// Create a ground mesh
const ground = BABYLON.MeshBuilder.CreateGround("ground", {
width: 100,
height: 100,
subdivisions: 20, // Increases detail for height maps
updatable: false
}, scene);
Position, rotate, and scale meshes to arrange your scene:
// Position (translation)
box.position = new BABYLON.Vector3(0, 2, 0); // Set absolute position
box.position.y += 1; // Relative position change
// Rotation (in radians)
cylinder.rotation = new BABYLON.Vector3(
0, // X-axis rotation (pitch)
Math.PI / 4, // Y-axis rotation (yaw)
0 // Z-axis rotation (roll)
);
// Alternative rotation with Quaternions (better for complex rotations)
const quaternion = BABYLON.Quaternion.RotationAxis(
new BABYLON.Vector3(1, 1, 0).normalize(), // Axis to rotate around
Math.PI / 3 // Angle in radians
);
sphere.rotationQuaternion = quaternion;
// Scaling
torus.scaling = new BABYLON.Vector3(1.5, 1.5, 1.5); // Uniform scaling
plane.scaling = new BABYLON.Vector3(2, 1, 1); // Non-uniform scaling
// Apply multiple transformations with a matrix
const matrix = BABYLON.Matrix.Compose(
new BABYLON.Vector3(1.2, 0.8, 1.2), // Scaling
BABYLON.Quaternion.RotationYawPitchRoll(0.3, 0, 0), // Rotation
new BABYLON.Vector3(2, 0, -3) // Translation
);
ground.setPivotMatrix(matrix);
Create parent-child relationships between meshes:
// Create parent node
const parent = new BABYLON.TransformNode("parent", scene);
parent.position.y = 5;
// Make meshes children of the parent
sphere.parent = parent;
box.parent = parent;
// Position children relative to parent
sphere.position = new BABYLON.Vector3(2, 0, 0); // 2 units right of parent
box.position = new BABYLON.Vector3(-2, 0, 0); // 2 units left of parent
// Rotate the parent (affects all children)
parent.rotation.y = Math.PI / 4;
Load 3D models created in external applications:
// Load a single model (glTF or GLB format - recommended)
BABYLON.SceneLoader.ImportMesh(
"", // Names of meshes to import (empty = all)
"./models/", // Path to models
"character.glb", // Filename
scene, // Scene to import into
(meshes, particleSystems, skeletons, animationGroups) => {
// Successfully imported
const character = meshes[0];
character.scaling = new BABYLON.Vector3(0.1, 0.1, 0.1);
// Play animations if available
if (animationGroups.length > 0) {
animationGroups[0].start(true); // true = loop
}
}
);
// Asynchronous loading with await
async function loadModel() {
const result = await BABYLON.SceneLoader.ImportMeshAsync(
"", "./models/", "scene.gltf", scene
);
// Process imported meshes
for (const mesh of result.meshes) {
mesh.checkCollisions = true;
}
// Handle animations
if (result.animationGroups.length > 0) {
const idleAnim = result.animationGroups.find(g => g.name === "Idle");
if (idleAnim) idleAnim.start(true);
}
}
// Load a complete scene (replaces current scene)
BABYLON.SceneLoader.Load("./models/", "environment.glb", engine, (newScene) => {
// newScene is now the active scene
newScene.createDefaultCameraOrLight(true, true, true);
});
Combine and modify meshes:
// Merge multiple meshes into one for better performance
const merged = BABYLON.Mesh.MergeMeshes(
[box, sphere, cylinder], // Meshes to merge
true, // Dispose original meshes
true, // Allow different materials
undefined, // Use default world matrix
false, // Don't clone meshes
true // Allow different vertex colors
);
// Create instances for repeated objects with shared geometry
const boxInstance = box.createInstance("boxInstance");
boxInstance.position.x = 5;
// Create many instances efficiently
for (let i = 0; i < 100; i++) {
const instance = box.createInstance("box" + i);
instance.position = new BABYLON.Vector3(
Math.random() * 20 - 10,
Math.random() * 5,
Math.random() * 20 - 10
);
instance.rotation.y = Math.random() * Math.PI * 2;
}
Create custom meshes with vertex data:
// Create a custom mesh (triangle)
const customMesh = new BABYLON.Mesh("custom", scene);
// Define vertex data
const vertexData = new BABYLON.VertexData();
// Positions (3 vertices, each with x,y,z coordinates)
vertexData.positions = [
0, 1, 0, // Top vertex
-1, -1, 0, // Bottom left vertex
1, -1, 0 // Bottom right vertex
];
// Indices (defines triangles using position indices)
vertexData.indices = [0, 1, 2]; // Counter-clockwise winding
// Normals (perpendicular vectors for lighting calculations)
vertexData.normals = [
0, 0, 1,
0, 0, 1,
0, 0, 1
];
// UV coordinates for texturing
vertexData.uvs = [
0.5, 0, // Top vertex UV
0, 1, // Bottom left UV
1, 1 // Bottom right UV
];
// Apply the vertex data to the mesh
vertexData.applyToMesh(customMesh);
Optimize meshes for better performance:
// Freeze transformations (improves performance)
box.freezeWorldMatrix();
// Convert to a thin instance mesh (very efficient for many copies)
const matrix1 = BABYLON.Matrix.Translation(3, 0, 0);
const matrix2 = BABYLON.Matrix.Translation(-3, 0, 0);
const matrix3 = BABYLON.Matrix.Translation(0, 0, 3);
sphere.thinInstanceSetBuffer("matrix", [matrix1, matrix2, matrix3]);
// Level of Detail (LOD)
const highDetailSphere = BABYLON.MeshBuilder.CreateSphere("highDetail", {
segments: 32,
diameter: 2
}, scene);
const mediumDetailSphere = BABYLON.MeshBuilder.CreateSphere("mediumDetail", {
segments: 16,
diameter: 2
}, scene);
const lowDetailSphere = BABYLON.MeshBuilder.CreateSphere("lowDetail", {
segments: 8,
diameter: 2
}, scene);
// Add LOD levels
highDetailSphere.addLODLevel(30, mediumDetailSphere); // Switch at 30 units distance
highDetailSphere.addLODLevel(60, lowDetailSphere); // Switch at 60 units distance
highDetailSphere.addLODLevel(100, null); // Hide beyond 100 units
// Only the highDetailSphere needs to be visible in the scene
mediumDetailSphere.isVisible = false;
lowDetailSphere.isVisible = false;
Babylon.js 7 introduces improved mesh features:
// Enable mesh tessellation (dynamic subdivision)
ground.enableTessellation = true;
ground.tessellationProperties = {
maxSubdivisions: 8, // Maximum subdivision level
distanceFunction: (x, y, z, camera) => {
// Custom function to determine subdivision based on distance
const distanceToCamera = BABYLON.Vector3.Distance(
new BABYLON.Vector3(x, y, z),
camera.position
);
return Math.max(1, 8 - Math.floor(distanceToCamera / 10));
}
};
// GPU instancing with custom attributes
const buffer = new Float32Array(4 * 100); // 100 instances, 4 values each
for (let i = 0; i < 100; i++) {
// Custom color and scale for each instance
buffer[i*4] = Math.random(); // R
buffer[i*4+1] = Math.random(); // G
buffer[i*4+2] = Math.random(); // B
buffer[i*4+3] = 0.5 + Math.random() * 0.5; // Scale
}
sphere.thinInstanceSetBuffer("color", buffer, 4);
// Create vertex shader that uses the buffer
const shader = new BABYLON.ShaderMaterial(/* shader code that accesses custom attributes */);
sphere.material = shader;
These mesh capabilities in Babylon.js 7 provide powerful tools for creating and optimizing 3D objects, from simple primitives to complex imported models, with performance optimizations for both desktop and mobile platforms.