Geometry Manipulation in Three.js — Twisting

Shay Keinan
2 min readApr 24, 2018

--

In this article we are going to cover a common technique for manipulating geometries in Three.js.

Three.js is a cross-browser JavaScript library and Application Programming Interface (API) used to create and display animated 3D computer graphics in a web browser.

In Three.js we have something called a Mesh — a class representing triangular polygon mesh based objects. When creating a new Mesh we must provide the base geometry and material.

Geometries store attributes (vertex positions, faces, colors, etc.) using objects like Vector3 or Color that are easier to read and edit, but less efficient than typed arrays.

Materials describe the appearance of objects.

With the use of Mathematics we can manipulate and deform geometries.

In the next examples we are going to manipulate the geometry vertices — a set of points that define the geometry faces.

Vertices edges and faces of a geometry

Twist

We’ll begin by creating a new mesh and make sure that we have enough divisions along each one of the axis.

const geometry = new THREE.BoxGeometry(20, 20, 20, 20, 20, 20); 
const material = new THREE.MeshNormalMaterial({ wireframe: true });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
Box geometry

Next, we are going to create a Twist function and iterate over the vertices of the geometry — each vertex will be manipulated with a quaternion according to his Y position.

A quaternion is used to rotate things. In mathematics, the quaternions are a number system that extends the complex numbers. A feature of quaternions is that multiplication of two quaternions is non-commutative.

In Three.js we use quaternions as follows —

const quaternion = new THREE.Quaternion(); quaternion.setFromAxisAngle( 
new THREE.Vector3(0, 1, 0),
Math.PI / 2
);
const vector = new THREE.Vector3(1, 0, 0); vector.applyQuaternion(quaternion);

Let’s take a look at our twist function —

twist(geometry) {
const quaternion = new THREE.Quaternion();

for (let i = 0; i < geometry.vertices.length; i++) {
// a single vertex Y position
const yPos = geometry.vertices[i].y;
const twistAmount = 10;
const upVec = new THREE.Vector3(0, 1, 0);

quaternion.setFromAxisAngle(
upVec,
(Math.PI / 180) * (yPos / twistAmount)
);

geometry.vertices[i].applyQuaternion(quaternion);
}

// tells Three.js to re-render this mesh
geometry.verticesNeedUpdate = true;
}
Twist effect using quaternion

We can apply this effect on loaded models, for example — this vase

Stay tuned for similar experiments in the coming weeks, and let me know what you’ve made!

--

--

Shay Keinan

Front-end Architect @ Salesforce, Public speaker and trainer.