vs BufferGeometry

MeshBuilder Compared with Three.js's BufferGeometry

Both libraries upload the same arrays. Three.js 30,815 separates a reusable BufferGeometry from the Mesh that pairs it with a material (Anatomy of a BufferGeometry); a Babylon.js 89,603 builder creates both at once.

Geometry in Babylon.js and Three.js
Task Babylon.js Three.js (Geometries and BufferGeometry)
Built-in shape MeshBuilder.CreateBox(name, options, scene) new Mesh(new BoxGeometry(w, h, d), material)
Custom arrays VertexData + applyToMesh() setAttribute('position', new BufferAttribute())
Smooth normals VertexData.ComputeNormals() geometry.computeVertexNormals()
Merge Mesh.MergeMeshes() in core mergeGeometries() from an add-on
Booleans CSG2 in core (Manifold) Community libraries such as three-bvh-csg
Handedness Left-handed by default Right-handed

Porting is mechanical: copy the arrays, flip z or set scene.useRightHandedSystem = true, and check the winding (Custom Geometry). Babylon's options objects read better than positional arguments, and mesh names serve getMeshByName() and the Inspector (Inspector and Tools).

The same book built by MeshBuilder and from BufferGeometry-style arrays, with each library's axesHTMLLive
<!doctype html>
<style>
  body { margin: 0; background: #f7f3ec; }
  canvas { width: 100%; max-width: 600px; height: 360px; display: block; touch-action: none; }
</style>
<canvas id="view"></canvas>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babylonjs-gui@9.28.0/babylon.gui.min.js"></script>
<script>
const canvas = document.getElementById('view');
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color4.FromHexString('#f7f3ecff');
const camera = new BABYLON.ArcRotateCamera('cam', -Math.PI / 2 - 0.25, 1.2, 5.2, new BABYLON.Vector3(0, 0.3, 0), scene);
camera.attachControl(canvas, true);
new BABYLON.HemisphericLight('sky', new BABYLON.Vector3(0.3, 1, -0.4), scene);
const ui = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('ui');
const cover = new BABYLON.StandardMaterial('cover', scene);
cover.diffuseColor = BABYLON.Color3.FromHexString('#1f5f8b');

// 1. Babylon.js: one builder call creates the geometry AND the mesh
const built = BABYLON.MeshBuilder.CreateBox('built', { width: 0.8, height: 1.2, depth: 0.2 }, scene);
built.position.x = -1.2;
built.material = cover;

// 2. Three.js style: flat arrays, like setAttribute('position', new BufferAttribute(...)).
//    Here they go into a VertexData and applyToMesh; the corners are shared (8 vertices).
const [w, h, d] = [0.4, 0.6, 0.1];
const positions = [-w, -h, -d, w, -h, -d, w, h, -d, -w, h, -d,     // front face (-z)
  -w, -h, d, w, -h, d, w, h, d, -w, h, d];                        // back face (+z)
const indices = [0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 0, 1, 5, 0, 5, 4,   // front, back, bottom
  3, 6, 2, 3, 7, 6, 0, 4, 7, 0, 7, 3, 1, 2, 6, 1, 6, 5];             // top, left, right
const normals = [];
BABYLON.VertexData.ComputeNormals(positions, indices, normals);   // like computeVertexNormals()
const custom = new BABYLON.Mesh('custom', scene);
Object.assign(new BABYLON.VertexData(), { positions, indices, normals }).applyToMesh(custom);
custom.position.x = 1.2;
custom.material = cover;

// Babylon is left-handed (+z into the screen); Three.js is right-handed (+z toward you)
const axes = new BABYLON.AxesViewer(scene, 0.7);
axes.update(new BABYLON.Vector3(-1.2, -0.7, -0.3), BABYLON.Axis.X, BABYLON.Axis.Y, BABYLON.Axis.Z);
const threeAxes = new BABYLON.AxesViewer(scene, 0.7);
threeAxes.update(new BABYLON.Vector3(1.2, -0.7, -0.3), BABYLON.Axis.X, BABYLON.Axis.Y, BABYLON.Axis.Z.negate());

label(built, 'MeshBuilder.CreateBox\n24 vertices (per-face normals)', -110);
label(custom, 'VertexData + applyToMesh\n8 shared vertices (smoothed)', -110);
const foot = label(null, 'left: Babylon axes, +z away    right: Three.js axes, +z toward you', 0);
foot.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;
foot.top = '-8px';

function label(mesh, text, offsetY) {
  const block = new BABYLON.GUI.TextBlock('', text);
  Object.assign(block, { color: '#333', fontSize: 13, resizeToFit: true });
  ui.addControl(block);
  if (mesh) { block.linkWithMesh(mesh); block.linkOffsetY = offsetY; }
  return block;
}
scene.onBeforeRenderObservable.add(() => {
  built.rotation.y = custom.rotation.y += engine.getDeltaTime() / 1500;
});
engine.runRenderLoop(() => scene.render());
addEventListener('resize', () => engine.resize());
</script>