{"_id":"@aperture-engine/math","_rev":"3-64900cd933d82a54c1ff933804391ac8","name":"@aperture-engine/math","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@aperture-engine/math","version":"0.1.0","keywords":["aperture","webgpu","3d-math","matrix","vector","quaternion","gamedev","typescript","linear-algebra"],"author":{"name":"Felix Zhang"},"license":"MIT","_id":"@aperture-engine/math@0.1.0","maintainers":[{"name":"felixtrz","email":"felixtrz96@gmail.com"}],"homepage":"https://github.com/felixtrz/aperture/tree/main/packages/math#readme","bugs":{"url":"https://github.com/felixtrz/aperture/issues"},"dist":{"shasum":"b45247e83ae24c8fb03847c6766b1788d3af09b7","tarball":"https://registry.npmjs.org/@aperture-engine/math/-/math-0.1.0.tgz","fileCount":83,"integrity":"sha512-KJ+rjJHUT4z1POSwR2bmG7NE6n9zKOBuM6JRtjmGHIIQSQ2K6UyT+kDGPxm7rrrJD/aLpK7fdcqwvtD2uN30mA==","signatures":[{"sig":"MEYCIQCH66r2AQbsTehKPLVyn+qUtJWmjVy1Wrk/OGvazjWm2wIhAPkfQ6pQ7eL25sqoZ0O3IUy5mNjeJoHKbw+W1J57CMfz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":244612},"main":"./dist/index.js","type":"module","_from":"file:aperture-engine-math-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./kernel":{"types":"./dist/kernel/index.d.ts","import":"./dist/kernel/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"felixtrz","email":"felixtrz96@gmail.com"},"_resolved":"/private/var/folders/xc/nttyc9pj3xngmbjsfbgdbddc0000gn/T/05aed2b3c9af6ac955cbbf9a0a4df124/aperture-engine-math-0.1.0.tgz","_integrity":"sha512-KJ+rjJHUT4z1POSwR2bmG7NE6n9zKOBuM6JRtjmGHIIQSQ2K6UyT+kDGPxm7rrrJD/aLpK7fdcqwvtD2uN30mA==","repository":{"url":"git+https://github.com/felixtrz/aperture.git","type":"git","directory":"packages/math"},"_npmVersion":"11.12.1","description":"Fast, zero-dependency, WebGPU-first 3D math for the Aperture engine: Float32Array-native vectors, quaternions, and matrices with fused transform fast paths.","directories":{},"sideEffects":false,"_nodeVersion":"26.0.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/math_0.1.0_1782151616173_0.5751878688025858","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aperture-engine/math","version":"0.2.0","keywords":["aperture","webgpu","3d-math","matrix","vector","quaternion","gamedev","typescript","linear-algebra"],"author":{"name":"Felix Zhang"},"license":"MIT","_id":"@aperture-engine/math@0.2.0","maintainers":[{"name":"felixtrz","email":"felixtrz96@gmail.com"}],"homepage":"https://github.com/felixtrz/aperture/tree/main/packages/math#readme","bugs":{"url":"https://github.com/felixtrz/aperture/issues"},"dist":{"shasum":"8118b09839641e381bdfb5c127152eaf34744892","tarball":"https://registry.npmjs.org/@aperture-engine/math/-/math-0.2.0.tgz","fileCount":83,"integrity":"sha512-ZaBO9hPYJkIfEy5cDyGEU4AEKClsE+NOx/pQUDm5gNAUYhBps9qtRaF+TlIE0oBqQ6NL/yEpfV6ycI+KERo0wA==","signatures":[{"sig":"MEUCIQDEYBN8bW91GaCaV9XzHO3GwXIdUf3C3Eq5YAsLIogaSgIgXlTns55/2UETx6gHUqsRY8ZXQEH47piegzBwHmhJQVE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":244612},"main":"./dist/index.js","type":"module","_from":"file:aperture-engine-math-0.2.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./kernel":{"types":"./dist/kernel/index.d.ts","import":"./dist/kernel/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc --noEmit -p tsconfig.json"},"_npmUser":{"name":"felixtrz","email":"felixtrz96@gmail.com"},"_resolved":"/private/var/folders/xc/nttyc9pj3xngmbjsfbgdbddc0000gn/T/527098bf3da46dc39343dee6b241363c/aperture-engine-math-0.2.0.tgz","_integrity":"sha512-ZaBO9hPYJkIfEy5cDyGEU4AEKClsE+NOx/pQUDm5gNAUYhBps9qtRaF+TlIE0oBqQ6NL/yEpfV6ycI+KERo0wA==","repository":{"url":"git+https://github.com/felixtrz/aperture.git","type":"git","directory":"packages/math"},"_npmVersion":"11.12.1","description":"Fast, zero-dependency, WebGPU-first 3D math for the Aperture engine: Float32Array-native vectors, quaternions, and matrices with fused transform fast paths.","directories":{},"sideEffects":false,"_nodeVersion":"26.0.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/math_0.2.0_1782246083725_0.15790057266095658","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aperture-engine/math","version":"0.3.0","description":"Fast, zero-dependency, WebGPU-first 3D math for the Aperture engine: Float32Array-native vectors, quaternions, and matrices with fused transform fast paths.","author":{"name":"Felix Zhang"},"repository":{"type":"git","url":"git+https://github.com/felixtrz/aperture.git","directory":"packages/math"},"homepage":"https://github.com/felixtrz/aperture/tree/main/packages/math#readme","bugs":{"url":"https://github.com/felixtrz/aperture/issues"},"keywords":["aperture","webgpu","3d-math","matrix","vector","quaternion","gamedev","typescript","linear-algebra"],"type":"module","license":"MIT","sideEffects":false,"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./kernel":{"types":"./dist/kernel/index.d.ts","import":"./dist/kernel/index.js"},"./package.json":"./package.json"},"main":"./dist/index.js","types":"./dist/index.d.ts","publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc --noEmit -p tsconfig.json"},"_id":"@aperture-engine/math@0.3.0","_integrity":"sha512-tjZ0YglFWzu011Brspb8Mo/AJ+MXkn78cvRxy/FXLRf/FMFCAhKNASlDzDXk+CcxUd0l/0jjr30O3njIGqewuQ==","_resolved":"/private/var/folders/xc/nttyc9pj3xngmbjsfbgdbddc0000gn/T/eb5136a75bec634624e5356bb1b988ce/aperture-engine-math-0.3.0.tgz","_from":"file:aperture-engine-math-0.3.0.tgz","_nodeVersion":"26.0.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-tjZ0YglFWzu011Brspb8Mo/AJ+MXkn78cvRxy/FXLRf/FMFCAhKNASlDzDXk+CcxUd0l/0jjr30O3njIGqewuQ==","shasum":"30174b8bd5e33a5c37c16de3b28efc005d56685b","tarball":"https://registry.npmjs.org/@aperture-engine/math/-/math-0.3.0.tgz","fileCount":83,"unpackedSize":245736,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGoU1IRIinw7VazBxMTGRfBKt6zciSqx5znP4+uVH7WuAiAkFMN5yYzF49JlXkFx2pddZR4WQDVIhvfECC0W7Und4w=="}]},"_npmUser":{"name":"felixtrz","email":"felixtrz96@gmail.com"},"directories":{},"maintainers":[{"name":"felixtrz","email":"felixtrz96@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/math_0.3.0_1783122747854_0.1276056121041793"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-22T18:06:55.958Z","modified":"2026-07-03T23:52:28.124Z","0.1.0":"2026-06-22T18:06:56.314Z","0.2.0":"2026-06-23T20:21:23.869Z","0.3.0":"2026-07-03T23:52:28.012Z"},"bugs":{"url":"https://github.com/felixtrz/aperture/issues"},"author":{"name":"Felix Zhang"},"license":"MIT","homepage":"https://github.com/felixtrz/aperture/tree/main/packages/math#readme","keywords":["aperture","webgpu","3d-math","matrix","vector","quaternion","gamedev","typescript","linear-algebra"],"repository":{"type":"git","url":"git+https://github.com/felixtrz/aperture.git","directory":"packages/math"},"description":"Fast, zero-dependency, WebGPU-first 3D math for the Aperture engine: Float32Array-native vectors, quaternions, and matrices with fused transform fast paths.","maintainers":[{"name":"felixtrz","email":"felixtrz96@gmail.com"}],"readme":"# @aperture-engine/math\n\nFast, zero-dependency, **WebGPU-first** 3D math for the [Aperture](https://github.com/felixtrz/aperture) engine.\n\n`Float32Array`-native vectors, quaternions, and 4×4 matrices, with an ergonomic wrapper API and a raw, allocation-free kernel — tuned to be the fastest option for a real engine's transform workload.\n\n## Install\n\n```sh\npnpm add @aperture-engine/math\n```\n\n## Why\n\n- **Zero dependencies.** Pure TypeScript over `Float32Array`. Nothing to audit, nothing to bundle.\n- **WebGPU-first by default.** Column-major matrices, clip-space depth `z ∈ [0, 1]`, `[x, y, z, w]` quaternions, right-handed world space — the conventions WGSL and the engine expect, with no flags.\n- **Allocation-free hot paths.** Every operation takes an optional output parameter, so per-frame, per-entity code never allocates.\n- **Fused fast paths for the workload that matters.** `composeTRS`, `mulAffine`, and `invertAffine` collapse the per-entity transform pipeline into single passes.\n- **Two layers.** An ergonomic wrapper (`composeTrsMatrix`, `makePerspective`, `vec3Cross`, …) for app code, and a raw kernel (`mat4.multiply`, `quat.slerp`, …) for the hottest loops.\n\n## Quick start\n\nErgonomic wrapper — the default entry point:\n\n```ts\nimport {\n  composeTrsMatrix,\n  makePerspective,\n  vec3,\n  quatFromAxisAngle,\n} from \"@aperture-engine/math\";\n\nconst model = composeTrsMatrix(\n  [0, 1, 0], // translation\n  quatFromAxisAngle([0, 1, 0], Math.PI / 4), // rotation\n  [1, 1, 1], // scale\n);\n\nconst projection = makePerspective(Math.PI / 3, 16 / 9, 0.1, 1000);\n```\n\nRaw kernel — namespaced, output-parameter ops for allocation-free inner loops:\n\n```ts\nimport { mat4, vec3, quat } from \"@aperture-engine/math/kernel\";\n\nconst world = new Float32Array(16);\nconst local = new Float32Array(16);\n\n// Fused translation·rotation·scale in one pass, written into `local`.\nmat4.composeTRS(translation, rotation, scale, local);\n// Affine-only multiply: skips the homogeneous row.\nmat4.mulAffine(parentWorld, local, world);\n```\n\n## Conventions\n\n|                |                                                          |\n| -------------- | -------------------------------------------------------- |\n| Storage        | `Float32Array` (tight, GPU/ECS/worker-friendly)          |\n| Matrices       | column-major, 16 contiguous floats                       |\n| Depth range    | WebGPU clip space `z ∈ [0, 1]` (`perspective` / `ortho`) |\n| Quaternions    | `[x, y, z, w]`                                           |\n| Handedness     | right-handed                                             |\n| Argument order | inputs first, optional `dst` last                        |\n\n## Benchmarks\n\nThe headline number: on the engine's real **per-entity transform-propagation** workload (compose a local TRS matrix and multiply it by a parent world matrix, over thousands of entities in packed `Float32Array` storage), this library is **~1.3× faster than `wgpu-matrix`** and **~1.1× faster than `gl-matrix`**.\n\nMeasured with `node scripts/bench-math.mjs` (standalone Node, all three libraries loaded as native modules with preallocated outputs — median ops/s, Node 22):\n\n| Operation                                     | @aperture-engine/math | vs `wgpu-matrix` |   vs `gl-matrix` |\n| --------------------------------------------- | --------------------: | ---------------: | ---------------: |\n| `mat4.multiply`                               |             **21.5M** | **1.13× faster** | **1.06× faster** |\n| `mat4.inverse` (general)                      |                 19.0M | **1.25× faster** |     1.03× slower |\n| compose TRS → `mat4`                          |             **45.0M** | **1.30× faster** |     1.02× faster |\n| `mat4 × vec3` (transform point)               |             **44.3M** |     1.00× (tied) |     1.01× faster |\n| `quat.multiply`                               |                 58.3M |     1.01× slower |     1.01× faster |\n| `quat.fromEuler`                              |                 21.7M |     1.00× (tied) |                — |\n| `perspective` (z 0..1)                        |             **70.0M** |     1.00× (tied) |     1.00× (tied) |\n| `vec3.normalize`                              |                 70.5M |     1.01× slower |     1.08× faster |\n| **`mulAffine`** (fused) vs general multiply   |             **26.4M** | **1.36× faster** |                — |\n| **`invertAffine`** (fused) vs general inverse |             **29.0M** | **1.92× faster** |                — |\n| **transform propagation (4096 entities)**     |           **fastest** | **1.33× faster** | **1.10× faster** |\n\nFastest-or-tied on every core primitive, and decisively fastest on the fused operations and the end-to-end transform workload — the path that dominates engine frame time. The two non-wins (general `inverse` vs `gl-matrix`, `vec3.normalize` vs `wgpu-matrix`) are within run-to-run noise.\n\nRun them yourself from the repo root:\n\n```sh\npnpm run bench:math\n```\n\nMethodology notes:\n\n- All competitors get **preallocated output buffers**, so we measure compute, not allocation — exactly how the engine calls them.\n- A vitest bench (`test/math/kernel.bench.ts`) also exists, but it runs engine source through vite's module runner while node_modules deps load natively, which understates this library. The standalone script (`scripts/bench-math.mjs`) loads the **built** kernel so all three are equal native modules — that's the fair comparison reported above.\n- Correctness is locked by parity tests against `wgpu-matrix` as an oracle (`test/math/kernel.test.ts`), including the fused ops vs the primitives they replace.\n\n## API surface\n\n**Wrapper (`@aperture-engine/math`)** — vectors (`vec2`/`vec3`/`vec4`, `vec3Add`/`vec3Cross`/`vec3Dot`/`vec3Normalize`/…), quaternions (`quat`, `quatFromAxisAngle`/`quatFromEuler`/`quatMultiply`/`quatLookAt`/…), matrices (`mat4`, `composeTrsMatrix`/`decomposeTrsMatrix`/`multiplyMat4`/`invertMat4`/`transformPoint`/…), projections (`makePerspective`/`makeOrthographic`), tuple converters (`toVec3Tuple`/…), bounds & rays (AABB/sphere intersection), scalar helpers (`lerp`/`clamp`/`remap`/…), and the shared types (`Vec3`, `Mat4`, `Vec3Like`, …).\n\n**Kernel (`@aperture-engine/math/kernel`)** — namespaced raw ops: `mat4` (incl. `composeTRS`, `mulAffine`, `invertAffine`, `perspective`, `ortho`), `vec2`, `vec3`, `vec4`, `quat`. Every op is monomorphic over `Float32Array` and takes an optional `dst`.\n\n## License\n\nPart of the [Aperture](https://github.com/felixtrz/aperture) monorepo. MIT licensed.\n","readmeFilename":"README.md"}