Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Threejs Core Math

  • 19 installs
  • 11 repo stars
  • Updated July 8, 2026
  • openaec-foundation/three.js-claude-skill-package

Helps with ai & agent building tasks.

About

threejs-core-math is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • threejs-core-math
  • AI & Agent Building
  • AI-coding skill

Threejs Core Math by the numbers

  • 19 all-time installs (skills.sh)
  • +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #10,587 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/three.js-claude-skill-package --skill threejs-core-math

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs19
repo stars11
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/three.js-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

threejs-core-math

Quick Reference

Coordinate System

Three.js uses a right-handed coordinate system with Y-up:

AxisDirectionNotes
XRightPositive toward screen right
YUpPositive toward ceiling
ZToward viewerPositive out of the screen

Import conversion rules:

SourceConventionConversion
BlenderZ-upglTF exporter converts automatically
FBXZ-upFBXLoader converts automatically
OBJNo standardALWAYS verify orientation after loading
IFCZ-upALWAYS apply -90 degree X rotation or use a converting loader

NEVER assume imported models match Three.js conventions -- ALWAYS verify orientation after loading.

Core Math Classes

ClassPurposeIdentity/Default
Vector3Position, direction, scale(0, 0, 0)
Vector2UV coordinates, 2D positions(0, 0)
Vector4Homogeneous coordinates, shader data(0, 0, 0, 0)
Matrix44x4 transformation matrixIdentity matrix
QuaternionRotation without gimbal lock(0, 0, 0, 1)
EulerHuman-readable rotation angles(0, 0, 0, 'XYZ')
ColorRGB color (0-1 range)(1, 1, 1) white
Box3Axis-aligned bounding boxEmpty (+Inf min, -Inf max)
SphereBounding sphereCenter origin, radius -1
PlaneInfinite planeNormal (1,0,0), constant 0
RayOrigin + directionOrigin (0,0,0), direction (0,0,-1)
Frustum6-plane view frustum--

Critical Warnings

NEVER modify a Vector3/Matrix4/Quaternion that is shared between objects -- most methods mutate in-place. ALWAYS use .clone() before modifying shared instances.

// WRONG: mutates the shared vector
const offset = new Vector3(1, 0, 0);
meshA.position.add(offset);
meshB.position.add(offset); // offset is still (1, 0, 0) BUT if you
                             // had stored meshA.position somewhere,
                             // it would be mutated

// CORRECT: clone before mutation
const pos = sharedPosition.clone().add(offset);

NEVER interpolate Euler angles directly -- it produces incorrect rotation paths and triggers gimbal lock. ALWAYS convert to Quaternion, use slerp(), then convert back if needed.

NEVER manually set Quaternion x, y, z, w values unless you understand quaternion math. ALWAYS use setFromAxisAngle(), setFromEuler(), or slerp().

NEVER use lerp() on Color for hue-shifting animations -- it produces muddy intermediate colors. ALWAYS use lerpHSL() for transitions through different hues.

ALWAYS use MathUtils.degToRad() when Three.js expects radians -- all rotation methods use radians, not degrees.

---

Vector3

The most-used math class. All mutating methods return this for chaining.

Arithmetic: add(v), addScalar(s), sub(v), multiply(v), multiplyScalar(s), divide(v), divideScalar(s), negate()

Geometric: dot(v): number, cross(v), length(): number, lengthSq(): number, normalize(), setLength(l), reflect(normal), project(camera), unproject(camera)

Distance: distanceTo(v): number, distanceToSquared(v): number, manhattanDistanceTo(v): number

Interpolation: lerp(v, alpha), lerpVectors(v1, v2, t), clamp(min, max), clampLength(min, max)

Transform: applyMatrix4(m), applyQuaternion(q), applyAxisAngle(axis, angle), applyEuler(euler)

Conversion: setFromMatrixPosition(m), setFromMatrixScale(m), setFromSphericalCoords(r, phi, theta), toArray(arr?, offset?), fromArray(arr, offset?)

Assignment: set(x, y, z), copy(v), clone(), equals(v): boolean

Vector2 differs: has only x, y. No cross() (returns scalar via cross(v): number). No 3D transforms.

Vector4 differs: has x, y, z, w. Used for homogeneous coordinates and shader uniforms.

---

Matrix4

Column-major storage (WebGL convention). 16 floats in elements array:

elements[0]  elements[4]  elements[8]   elements[12]  // Translation = [12,13,14]
elements[1]  elements[5]  elements[9]   elements[13]
elements[2]  elements[6]  elements[10]  elements[14]
elements[3]  elements[7]  elements[11]  elements[15]

Composition: compose(position, quaternion, scale) / decompose(position, quaternion, scale) -- the standard TRS (Translate-Rotate-Scale) pattern.

Multiplication order: Right-to-left. M1.multiply(M2) means M2 is applied first, then M1. Use premultiply(m) for left-multiplication (this = m * this).

Factory methods: makeTranslation(x,y,z), makeScale(x,y,z), makeRotationX(theta), makeRotationY(theta), makeRotationZ(theta), makeRotationAxis(axis, angle), lookAt(eye, target, up)

Operations: invert(), transpose(), determinant(): number, identity(), extractBasis(x, y, z), extractRotation(m), setPosition(v)

---

Quaternion

Represents rotation without gimbal lock. ALWAYS prefer Quaternion over Euler for interpolated animations and compound rotations.

import { Quaternion } from 'three';
const q = new Quaternion(); // identity: (0, 0, 0, 1)

Setters: setFromAxisAngle(axis, angle), setFromEuler(euler), setFromRotationMatrix(m), setFromUnitVectors(vFrom, vTo)

Operations: multiply(q) (q applied first, then this), premultiply(q), slerp(qb, t), slerpQuaternions(qa, qb, t), rotateTowards(q, step), conjugate(), invert(), normalize()

Comparison: dot(q): number, angleTo(q): number, equals(q): boolean

---

Euler

Human-readable rotation in radians with a rotation order.

import { Euler } from 'three';
const e = new Euler(0, Math.PI / 2, 0, 'XYZ');

Rotation orders: 'XYZ' (default), 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY'

Gimbal lock: In 'XYZ' order, gimbal lock occurs at Y = +/- 90 degrees. Symptoms: unexpected snapping, loss of one rotational axis.

Methods: setFromRotationMatrix(m), setFromQuaternion(q, order?), reorder(newOrder), equals(euler): boolean

Euler vs Quaternion Decision Tree

ScenarioUse
Setting a fixed rotationEuler -- human-readable
Smooth rotation animationQuaternion + slerp()
Combining multiple rotationsQuaternion + multiply()
Avoiding gimbal lockQuaternion
Reading rotation from user input (degrees)Euler, convert via quaternion.setFromEuler(euler)
Storing rotation in scene graphobject.rotation (Euler) auto-syncs with object.quaternion

---

Color

import { Color } from 'three';

new Color(0xff0000);               // hex integer
new Color('red');                   // CSS color name
new Color('rgb(255, 0, 0)');       // CSS rgb string
new Color('#ff0000');              // CSS hex string
new Color('hsl(0, 100%, 50%)');   // CSS hsl string
new Color(1.0, 0.0, 0.0);        // RGB floats (0-1 range)

Properties: r, g, b (number, 0-1 range).

Setters: set(value), setHex(hex), setRGB(r,g,b), setHSL(h,s,l), setStyle(css), setColorName(name)

Getters: getHex(): number, getHexString(): string, getHSL(target): {h,s,l}, getStyle(): string

Interpolation: lerp(color, alpha) (RGB), lerpHSL(color, alpha) (perceptually better for hue shifts), lerpColors(c1, c2, alpha)

Color space: convertSRGBToLinear(), convertLinearToSRGB() -- ALWAYS convert texture colors to linear space for physically correct rendering.

---

MathUtils

Static utility methods -- NEVER instantiate, ALWAYS access via MathUtils.method().

import { MathUtils } from 'three';

MathUtils.degToRad(90);           // 1.5707...
MathUtils.clamp(value, 0, 1);    // clamp to range
MathUtils.lerp(0, 100, 0.5);     // 50
MathUtils.mapLinear(5, 0, 10, 0, 100); // 50
MathUtils.smoothstep(0.5, 0, 1); // Hermite ease
MathUtils.damp(current, target, lambda, dt); // frame-rate-independent damping
MathUtils.generateUUID();         // RFC 4122 v4 UUID

damp() is particularly useful for smooth camera follow and UI animations -- it produces exponential decay that is frame-rate independent, unlike naive lerp in an animation loop.

---

Bounding Volumes

Box3 (Axis-Aligned Bounding Box)

import { Box3, Vector3 } from 'three';

const box = new Box3();
box.setFromObject(mesh);                    // compute from mesh
box.containsPoint(new Vector3(1, 2, 3));   // boolean
box.intersectsBox(otherBox);               // boolean
box.getCenter(new Vector3());              // center point
box.getSize(new Vector3());                // dimensions

Sphere, Plane, Ray, Frustum

  • Sphere: containsPoint(), intersectsBox(), intersectsSphere(), distanceToPoint()
  • Plane: distanceToPoint(), projectPoint(), intersectLine()
  • Ray: intersectBox(), intersectSphere(), intersectPlane(), distanceToPoint()
  • Frustum: setFromProjectionMatrix(m), containsPoint(), intersectsObject(), intersectsBox()

---

Reference Links

  • references/methods.md -- Complete method signatures for Vector3, Matrix4, Quaternion, Euler, Color, MathUtils, Box3, Sphere, Plane, Ray
  • references/examples.md -- Working code examples for common 3D math operations
  • references/anti-patterns.md -- What NOT to do with Three.js math classes

Official Sources

  • https://threejs.org/docs/#api/en/math/Vector3
  • https://threejs.org/docs/#api/en/math/Matrix4
  • https://threejs.org/docs/#api/en/math/Quaternion
  • https://threejs.org/docs/#api/en/math/Euler
  • https://threejs.org/docs/#api/en/math/Color
  • https://threejs.org/docs/#api/en/math/MathUtils
  • https://threejs.org/docs/#api/en/math/Box3

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.