Different Shapes

white line

Boxes and spheres are fine, but what if you want something more interesting — an arrow, a star, a bottle, or a triangle? Three.js gives you a few different tools for building custom shapes, and which one you use depends on what kind of shape you're making.

making an arrow with lines

If you want a simple outline of a shape (like a wireframe arrow), use BufferGeometry with setFromPoints:

const points = [];
points.push(new THREE.Vector3(-10, 0, 0));
points.push(new THREE.Vector3(0, 10, 0));
points.push(new THREE.Vector3(10, 0, 0));

const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0x0000ff });
const line = new THREE.Line(geometry, material);

scene.add(line);

This creates a V-shaped arrow using just three points connected by lines.

Good for: Wireframes, arrows, diagrams, measurements.

making a star with Shape

If you want a solid, filled 2D shape — like a star that you can texture or extrude into 3D — use THREE.Shape. It works like drawing on a canvas with moveTo and lineTo:

const shape = new THREE.Shape();
const outerRadius = 10;
const innerRadius = 4;
const spikes = 5;

for (let i = 0; i  spikes * 2; i++) {
    const radius = i % 2 === 0 ? outerRadius : innerRadius;
    const angle = (i / (spikes * 2)) * Math.PI * 2 - Math.PI / 2;
    const x = Math.cos(angle) * radius;
    const y = Math.sin(angle) * radius;
    if (i === 0) {
        shape.moveTo(x, y);
    } else {
        shape.lineTo(x, y);
    }
}
shape.closePath();

const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({
    color: 0x0000ff,
    side: THREE.DoubleSide,
});
const star = new THREE.Mesh(geometry, material);

scene.add(star);

Good for: Stars, badges, icons, any 2D shape with straight or curved edges.

making a bottle with LatheGeometry

For shapes that are round but not simple spheres — like a bottle, a vase, or a chess piece — use LatheGeometry. It works by taking a 2D profile (a set of points) and revolving it around an axis, like spinning clay on a pottery wheel.

const points = [];
const height = 20;
const radius = 8;
const neckHeight = 6;
const neckRadius = 2;

// Profile of the bottle — trace one side
points.push(new THREE.Vector2(0, 0)); // center of base
points.push(new THREE.Vector2(radius * 0.8, 0)); // base edge
points.push(new THREE.Vector2(radius, 1)); // start of body

// Body
points.push(new THREE.Vector2(radius, height - neckHeight - 2));
points.push(new THREE.Vector2(radius * 0.9, height - neckHeight - 1));

// Neck
points.push(new THREE.Vector2(neckRadius + 1, height - neckHeight));
points.push(new THREE.Vector2(neckRadius, height - neckHeight + 1));

// Top
points.push(new THREE.Vector2(neckRadius, height));
points.push(new THREE.Vector2(0, height)); // center of top

const geometry = new THREE.LatheGeometry(points, 32);
const material = new THREE.MeshStandardMaterial({
    color: 0x4488aa,
    side: THREE.DoubleSide,
});
const bottle = new THREE.Mesh(geometry, material);

scene.add(bottle);

Good for: Bottles, vases, lamp shades, goblets, pillars — anything with rotational symmetry.

making a triangle with Shape

Here's the simplest solid shape — a triangle:

const shape = new THREE.Shape();
shape.moveTo(-10, -10);
shape.lineTo(10, -10);
shape.lineTo(0, 10);
shape.closePath();

const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({
    color: 0x0000ff,
    side: THREE.DoubleSide,
});
const triangle = new THREE.Mesh(geometry, material);
scene.add(triangle);

which approach should you use?

You want to... Use this
Draw lines or wireframes Line + setFromPoints
Make a solid 2D shape (star, triangle) ShapeGeometry
Make a rotated object (bottle, vase) LatheGeometry
Build any shape from scratch (custom) BufferGeometry

Each is useful for different things. Start with Shape for flat shapes and LatheGeometry for anything round and symmetrical.