Skip to content

BabylonJS - Curve3

The BABYLON.Curve3 class provides static methods for creating smooth curves in 3D space based on various mathematical spline algorithms. These generated curves are essentially ordered arrays of Vector3 points that can then be used as paths for other MeshBuilder methods like CreateLines, CreateTube, or CreateRibbon, or for animating objects along the curve.

Using Curve3 avoids the need to manually calculate the numerous intermediate points required for a smooth curve, simplifying the creation of complex paths.

A simple curve defined by three points: a start point, an end point, and a single control point that pulls the curve towards it.

const startPoint = new BABYLON.Vector3(0, 0, 0);
const controlPoint = new BABYLON.Vector3(5, 5, 0);
const endPoint = new BABYLON.Vector3(10, 0, 0);
const numberOfPoints = 20; // Number of points to generate along the curve
const quadraticBezierCurve = BABYLON.Curve3.CreateQuadraticBezier(
startPoint,
controlPoint,
endPoint,
numberOfPoints
);
// Get the array of Vector3 points
const pointsArray = quadraticBezierCurve.getPoints();
// Example: Draw the curve using CreateLines
const lineMesh = BABYLON.MeshBuilder.CreateLines("qBezierLine", { points: pointsArray }, scene);
lineMesh.color = BABYLON.Color3.Red();

A more versatile curve defined by four points: a start point, an end point, and two control points that influence the curve’s shape at the start and end, respectively.

const startPoint = new BABYLON.Vector3(0, 0, 0);
const controlPoint1 = new BABYLON.Vector3(2, 8, 2);
const controlPoint2 = new BABYLON.Vector3(8, 8, -2);
const endPoint = new BABYLON.Vector3(10, 0, 0);
const numberOfPoints = 30;
const cubicBezierCurve = BABYLON.Curve3.CreateCubicBezier(
startPoint,
controlPoint1,
controlPoint2,
endPoint,
numberOfPoints
);
const pointsArray = cubicBezierCurve.getPoints();
const lineMesh = BABYLON.MeshBuilder.CreateLines("cBezierLine", { points: pointsArray }, scene);
lineMesh.color = BABYLON.Color3.Green();

Defined by a start point, an end point, and tangent vectors at both the start and end points. The tangents control the direction the curve leaves the start point and arrives at the end point.

const startPoint = new BABYLON.Vector3(0, 0, 0);
const startTangent = new BABYLON.Vector3(5, 5, 0); // Direction leaving startPoint
const endPoint = new BABYLON.Vector3(10, 0, 5);
const endTangent = new BABYLON.Vector3(5, -5, 0); // Direction arriving at endPoint
const numberOfPoints = 25;
const hermiteSpline = BABYLON.Curve3.CreateHermiteSpline(
startPoint,
startTangent,
endPoint,
endTangent,
numberOfPoints
);
const pointsArray = hermiteSpline.getPoints();
const lineMesh = BABYLON.MeshBuilder.CreateLines("hermiteLine", { points: pointsArray }, scene);
lineMesh.color = BABYLON.Color3.Blue();

Creates a smooth curve that passes through a given sequence of control points. This is very useful when you know several points the path must hit.

const controlPoints = [
new BABYLON.Vector3(-5, 0, 0),
new BABYLON.Vector3(0, 5, 2),
new BABYLON.Vector3(5, 0, -2),
new BABYLON.Vector3(10, 5, 0),
new BABYLON.Vector3(15, 0, 0)
];
const pointsPerSegment = 10; // Number of points generated BETWEEN each control point
const catmullRomSpline = BABYLON.Curve3.CreateCatmullRomSpline(
controlPoints,
pointsPerSegment
);
const pointsArray = catmullRomSpline.getPoints();
const lineMesh = BABYLON.MeshBuilder.CreateLines("catmullRomLine", { points: pointsArray }, scene);
lineMesh.color = BABYLON.Color3.Yellow();
// Get curve length
const curveLength = catmullRomSpline.length();
console.log("Catmull-Rom curve length:", curveLength);

You can chain different curve segments together using the continue() method.

// Assuming quadraticBezierCurve and cubicBezierCurve are defined Curve3 objects
const combinedCurve = quadraticBezierCurve.continue(cubicBezierCurve);
const combinedPoints = combinedCurve.getPoints();
const combinedLine = BABYLON.MeshBuilder.CreateLines("combined", { points: combinedPoints }, scene);
combinedLine.color = BABYLON.Color3.Magenta();

This demo creates and displays lines for each of the four curve types described above, using helper functions to show axes and labels for reference.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Babylon.js - Curve3 Demo</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; }
#renderCanvas { width: 100%; height: 100%; touch-action: none; }
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="text/javascript">
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
// Helper function to create text labels
const makeTextPlane = function (text, color, size, scene) {
const dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture" + text, {width: text.length * 20 + 10, height: 70}, scene, true);
dynamicTexture.hasAlpha = true;
dynamicTexture.drawText(text, null, 50, "bold 36px Arial", color, "transparent", true);
const plane = BABYLON.MeshBuilder.CreatePlane("TextPlane" + text, {size: size}, scene, true);
plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial" + text, scene);
plane.material.backFaceCulling = false;
plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
plane.material.diffuseTexture = dynamicTexture;
plane.material.useAlphaFromDiffuseTexture = true;
return plane;
};
// Helper function to show axes
const showAxis = function(size, scene) {
const axisX = BABYLON.MeshBuilder.CreateLines("axisX", { points: [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0)] }, scene);
axisX.color = new BABYLON.Color3(1, 0, 0);
const xChar = makeTextPlane("X", "red", size / 10, scene);
xChar.position = new BABYLON.Vector3(0.9 * size, 0.05 * size, 0);
const axisY = BABYLON.MeshBuilder.CreateLines("axisY", { points: [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0)] }, scene);
axisY.color = new BABYLON.Color3(0, 1, 0);
const yChar = makeTextPlane("Y", "green", size / 10, scene);
yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
const axisZ = BABYLON.MeshBuilder.CreateLines("axisZ", { points: [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size)] }, scene);
axisZ.color = new BABYLON.Color3(0, 0, 1);
const zChar = makeTextPlane("Z", "blue", size / 10, scene);
zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
};
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.2, 0.2, 0.2, 1.0);
const camera = new BABYLON.ArcRotateCamera("camera1", Math.PI / 4, Math.PI / 3, 30, new BABYLON.Vector3(5, 3, 0), scene);
camera.attachControl(canvas, true);
camera.wheelPrecision = 50;
const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.8;
showAxis(10, scene);
// --- Define and Draw Curves ---
// 1. Quadratic Bezier (Red)
const qbCurve = BABYLON.Curve3.CreateQuadraticBezier(
new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(5, 8, -2), new BABYLON.Vector3(10, 0, 0), 20);
const qbLine = BABYLON.MeshBuilder.CreateLines("qBezier", { points: qbCurve.getPoints() }, scene);
qbLine.color = new BABYLON.Color3(1, 0.2, 0.2);
// 2. Cubic Bezier (Green)
const cbCurve = BABYLON.Curve3.CreateCubicBezier(
new BABYLON.Vector3(-5, 0, 5), new BABYLON.Vector3(-2, 8, 3), new BABYLON.Vector3(5, 8, -3), new BABYLON.Vector3(10, 0, 5), 30);
const cbLine = BABYLON.MeshBuilder.CreateLines("cBezier", { points: cbCurve.getPoints() }, scene);
cbLine.color = new BABYLON.Color3(0.2, 1, 0.2);
// 3. Hermite Spline (Blue)
const hsCurve = BABYLON.Curve3.CreateHermiteSpline(
new BABYLON.Vector3(-8, 0, -5), new BABYLON.Vector3(0, 10, 0),
new BABYLON.Vector3(8, 0, -5), new BABYLON.Vector3(0, -10, 10), 25);
const hsLine = BABYLON.MeshBuilder.CreateLines("hermite", { points: hsCurve.getPoints() }, scene);
hsLine.color = new BABYLON.Color3(0.2, 0.2, 1);
// 4. Catmull-Rom Spline (Yellow)
const crPoints = [ new BABYLON.Vector3(-10, -2, 8), new BABYLON.Vector3(-5, 3, -3), new BABYLON.Vector3(0, -2, 5), new BABYLON.Vector3(5, 3, -6), new BABYLON.Vector3(10, -2, 8) ];
const crCurve = BABYLON.Curve3.CreateCatmullRomSpline(crPoints, 10);
const crLine = BABYLON.MeshBuilder.CreateLines("catmullRom", { points: crCurve.getPoints() }, scene);
crLine.color = new BABYLON.Color3(1, 1, 0.2);
// Mark Catmull-Rom control points
crPoints.forEach((p, i) => {
const marker = BABYLON.MeshBuilder.CreateSphere(`crp_${i}`, {diameter: 0.3}, scene);
marker.position = p;
const markerMat = new BABYLON.StandardMaterial(`crpMat_${i}`, scene);
markerMat.emissiveColor = new BABYLON.Color3(1, 1, 0.2);
marker.material = markerMat;
});
// -----------------------------
return scene;
};
const scene = createScene();
engine.runRenderLoop(function () { scene.render(); });
window.addEventListener("resize", function () { engine.resize(); });
</script>
</body>
</html>

The demo displays a 3D coordinate system (XYZ axes with labels). Several colored lines are drawn, representing different types of curves: a red Quadratic Bezier curve, a green Cubic Bezier curve, a blue Hermite spline, and a yellow Catmull-Rom spline. Small yellow spheres mark the control points that the Catmull-Rom spline passes through. This allows you to visually compare the shapes generated by each algorithm.