High-performance orthogonal basis transformations for WebGL/Three.js (supports Array, Float32Array, Float64Array)
A high-performance library for 3D coordinate transformations between orthogonal bases, optimized for graphics programming (WebGL, Three.js, and real-time rendering pipelines). It simplifies conversions between world space and local coordinate systems (e.g., camera view space, model space) with support for multiple vector types.
[u, v, w] that satisfy: u · v = u · w = v · w = 0). ||u|| = ||v|| = ||w|| = 1). Common examples in graphics:
- Camera view basis: u (right), v (up), w (forward).
- Model local basis: Object's local X, Y, Z axes.
- Light space basis: Coordinate system aligned with a directional light.
[number, number, number] (arrays), Float32Array (WebGL/GPU-friendly), and Float64Array (high precision). bash
npm install gl-transform
`$3
`html
`
Quick Start
$3
`typescript
import { to, from, OrthoBasis } from 'gl-transform';// Define a camera's orthogonal basis (right/up/forward in world space)
const cameraBasis: OrthoBasis<[number, number, number]> = [
[1, 0, 0], // u: Right direction (world space)
[0, 1, 0], // v: Up direction (world space)
[0, 0, -1] // w: Forward direction (world space; -Z in camera space)
];
// A point in world space
const worldPoint: [number, number, number] = [5, 3, 2];
const cameraPoint: [number, number, number] = [0, 0, 0];
// Transform world → camera space (using
to)
to(cameraPoint, worldPoint, cameraBasis);
console.log(cameraPoint); // [5, 3, -2] (Z flipped due to camera forward)// Transform camera → world space (using
from)
const worldPoint2: [number, number, number] = [0, 0, 0];
from(worldPoint2, cameraPoint, cameraBasis);
console.log(worldPoint2); // [5, 3, 2] (matches original)
`
$3
`typescript
import { to32, from32, OrthoBasis } from 'gl-transform';// WebGL-compatible basis (Float32Array matches GPU precision)
const modelBasis: OrthoBasis = [
new Float32Array([0, 1, 0]), // u: Model's right (world space)
new Float32Array([1, 0, 0]), // v: Model's up (world space)
new Float32Array([0, 0, 1]) // w: Model's forward (world space)
];
// Model-local point (in model's coordinate system)
const localPoint = new Float32Array([1, 0, 0]); // 1 unit along model's right
const worldPoint = new Float32Array(3);
// Convert local → world space
from32(worldPoint, localPoint, modelBasis);
console.log(Array.from(worldPoint)); // [0, 1, 0] (matches model's right in world space)
`
$3
`html
`
API Reference
$3
| Type | Description |
|---------------------|-----------------------------------------------------------------------------|
| Vector3 | 3D vector type, supporting:
- [number, number, number] (array)
- Float32Array (single-precision)
- Float64Array (double-precision) |
| OrthoBasis | Orthogonal basis composed of 3 vectors of type T (e.g., OrthoBasis for WebGL). |
$3
#### isOrthoBasis(basis: OrthoBasis
Checks if a set of vectors forms a valid orthogonal basis.
- Parameters:
- basis: The basis to validate ([u, v, w]).
- epsilon: Tolerance for floating-point errors (default: 1e-6).
- Returns: true if the basis is orthogonal and unit-length.
$3
Convert a vector from world space to a local orthogonal basis.####
to(out: [number, number, number], vec: [number, number, number], basis: OrthoBasis<[number, number, number]>): [number, number, number]
Array-based transformation. ####
to32(out: Float32Array, vec: Float32Array, basis: OrthoBasis
Float32Array transformation (optimized for WebGL). ####
to64(out: Float64Array, vec: Float64Array, basis: OrthoBasis
Float64Array transformation (high-precision).
$3
Convert a vector from a local orthogonal basis back to world space.####
from(out: [number, number, number], vec: [number, number, number], basis: OrthoBasis<[number, number, number]>): [number, number, number]
Array-based transformation. ####
from32(out: Float32Array, vec: Float32Array, basis: OrthoBasis
Float32Array transformation (optimized for WebGL). ####
from64(out: Float64Array, vec: Float64Array, basis: OrthoBasis
Float64Array transformation (high-precision).
Performance
- Throughput: ~420 million operations/second (for to32 in Node.js 20+ on Intel i7-12700H).
- Memory Efficiency: Float32Array methods use 50% less memory than Float64Array, matching GPU memory constraints.
- No Garbage Collection: Reuses out` parameters to avoid temporary object allocation, critical for smooth real-time rendering.