English — High-performance linear algebra library for Deno, purpose-built for WebGPU.
中文 — 为 Deno 打造的高性能线性代数库,专为 WebGPU 设计。
Zero dependencies. Float32Array-backed. Column-major matrices.
零依赖。基于 Float32Array 存储。列主序矩阵。
-
WebGPU-native / WebGPU 原生 — All types expose a
.datagetter returning a freshFloat32Array, ready fordevice.createBuffer()/queue.writeBuffer().
所有类型通过.datagetter 返回Float32Array副本,可直接上传到 WebGPU 缓冲区。 -
Immutable operations / 不可变操作 — Every arithmetic operation returns a new instance; no mutation surprises.
所有运算返回新实例,无副作用。 -
Column-major matrices / 列主序矩阵 —
Mat2,Mat3,Mat4follow the standard graphics convention (same as GLSL / WGSL).
遵循图形学标准列主序布局,与 GLSL / WGSL 一致。 -
Full transformation chain / 完整变换链路 —
Mat4.perspective(),Mat4.orthographic(),Mat4.lookAt(), plusrotationX/Y/Z(),translation(),scale().
完整支持透视/正交投影、观察矩阵及旋转/平移/缩放。 -
No dependencies / 零依赖 — Zero runtime deps.
零运行时依赖。 -
Tree-shakeable / 可摇树 — Import only what you need.
按需导入。
deno add @brass/mathOr import directly from JSR / 或直接从 JSR 导入:
import { Vec3, Mat4 } from "jsr:@brass/math";import { Vec3, Mat4 } from "@brass/math";
// --- Vectors / 向量 ---
const position = new Vec3(1, 2, 3);
const forward = new Vec3(0, 0, -1);
const dir = forward.add(position.normalize());
const len = position.length();
const n = position.normalize();
// --- Matrices / 矩阵 ---
const view = Mat4.lookAt(
new Vec3(0, 2, 5), // eye / 眼睛位置
Vec3.zero(), // center / 目标点
Vec3.unitY(), // up / 上方向
);
const proj = Mat4.perspective(
Math.PI / 4, // fovY (45°)
16 / 9, // aspect / 宽高比
0.1, // near / 近平面
100, // far / 远平面
);
const vp = proj.mul(view);
// Transform a point (w=1 for position)
// 变换点 (w=1 表示位置点)
const worldPos = new Vec3(1, 0, -3);
const clipPos = vp.mulVec3(worldPos, 1);
// --- Upload to WebGPU / 上传到 WebGPU ---
// device.queue.writeBuffer(uniformBuffer, 0, vp.data);| Type / 类型 | Components / 分量 | Operations / 运算 |
|---|---|---|
Vec2 |
x, y |
add, sub, scale, dot, length, lengthSq, normalize, negate, lerp, equals |
Vec3 |
x, y, z |
all Vec2 ops + cross, reflect |
Vec4 |
x, y, z, w |
all Vec2 ops |
All vectors expose a data getter → Float32Array for buffer uploads.
所有向量提供 data getter,返回 Float32Array。
Static factories / 静态工厂方法:
| Method / 方法 | English | 中文 |
|---|---|---|
Vec2/3/4.zero() |
Zero vector | 零向量 |
Vec2/3/4.one() |
Vector of all ones | 全 1 向量 |
Vec2/3/4.unitX/Y/Z/W() |
Axis-aligned unit vectors | 轴向单位向量 |
Vec2/3/4.fromArray(arr) |
From number[] or Float32Array |
从数组创建 |
| Type / 类型 | Size / 尺寸 | Description / 说明 |
|---|---|---|
Mat2 |
2×2 | 2D rotation, scale / 二维旋转、缩放 |
Mat3 |
3×3 | 3D rotation, normal matrix / 三维旋转、法线矩阵 |
Mat4 |
4×4 | 3D transforms, projections, view / 三维变换、投影、视图 |
Common methods / 通用方法:
| Method / 方法 | English | 中文 |
|---|---|---|
.clone() |
Deep copy | 深拷贝 |
.add(m) |
Component-wise addition | 逐分量加法 |
.sub(m) |
Component-wise subtraction | 逐分量减法 |
.scale(s) |
Uniform scalar multiplication | 统一标量乘法 |
.mul(m) |
Matrix-matrix multiplication | 矩阵乘法 |
.mulVec2(v) / .mulVec3(v) / .mulVec4(v) |
Matrix-vector multiplication | 矩阵×向量 |
.determinant() |
Matrix determinant | 行列式 |
.inverse() |
Matrix inverse (throws if singular) | 逆矩阵(奇异时抛出) |
.transpose() |
Matrix transpose | 转置 |
.equals(m, eps?) |
Approximate equality | 近似相等 |
.toArray() |
Float32Array copy (column-major) |
导出列主序 Float32Array |
.toJSArray() |
number[][] in row-major display order |
导出行主序二维数组 |
// --- Transformations / 变换 ---
Mat4.translation(tx, ty, tz) // translate / 平移
Mat4.rotationX(angle) // rotate X (radians / 弧度)
Mat4.rotationY(angle) // rotate Y
Mat4.rotationZ(angle) // rotate Z
Mat4.scale(sx, sy, sz) // scale / 缩放
// --- Projections / 投影 ---
Mat4.perspective(fovY, aspect, near, far)
Mat4.orthographic(left, right, bottom, top, near, far)
Mat4.frustum(left, right, bottom, top, near, far)
// --- View / 视图 ---
Mat4.lookAt(eye, center, up) // world-to-view matrix / 世界到视图矩阵import { Vec3, Mat4 } from "@brass/math";
function viewMatrix(eye: Vec3, yaw: number, pitch: number): Mat4 {
const cosY = Math.cos(yaw);
const sinY = Math.sin(yaw);
const cosP = Math.cos(pitch);
const sinP = Math.sin(pitch);
const forward = new Vec3(sinY * cosP, sinP, cosY * cosP).normalize();
const center = eye.add(forward);
return Mat4.lookAt(eye, center, Vec3.unitY());
}function mvp(model: Mat4, view: Mat4, proj: Mat4): Mat4 {
return proj.mul(view).mul(model);
}// In your rendering loop / 在你的渲染循环中:
const mvpMatrix = mvp(modelMat, viewMat, projMat);
device.queue.writeBuffer(
uniformBuffer,
0,
mvpMatrix.data, // Float32Array(16), column-major / 列主序
);Matrices use column-major order, matching WGSL's default matrix layout.
矩阵采用列主序存储,与 WGSL 默认矩阵布局一致:
Index / 索引: 0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
Mat4 m;
m.data → Float32Array [ m[0], m[1], ..., m[15] ]
→ column 0 / 第 0 列, column 1, column 2, column 3
In WGSL / 在 WGSL 中:
struct Uniforms {
mvp: mat4x4<f32>,
}Upload mvpMatrix.data directly — no transpose needed.
直接上传 mvpMatrix.data — 无需转置。
-
All vector and matrix arithmetic allocates new
Float32Arrayinstances. For hot paths, consider reusing buffers and usingFloat32Array.set()if profiling indicates GC pressure.
所有向量和矩阵运算都会分配新的Float32Array实例。如果性能分析显示 GC 压力较大,可考虑复用缓冲区并使用Float32Array.set()。 -
.datareturns a copy of the internal buffer. This is intentional — it prevents accidental mutation and ensures safety when the array is passed to WebGPU. If you need zero-copy access, extend the class or access internals directly (not recommended).
.data返回内部缓冲区的副本。这是有意为之——防止意外修改,确保传入 WebGPU 时的安全性。如需零拷贝访问,可扩展类或直接访问内部(不推荐)。
Run on / 测试环境: 12th Gen Intel Core i3-12100, Deno 2.7.14.
| Operation / 操作 | Time / 时间 (avg) |
|---|---|
.determinant |
3.4 ns |
.inverse |
281 ns |
.transpose |
267 ns |
.mul |
315 ns |
.mulVec2 |
330 ns |
| Operation / 操作 | Time / 时间 (avg) |
|---|---|
.determinant |
3.6 ns |
.inverse |
279 ns |
.transpose |
269 ns |
.mul |
331 ns |
.mulVec3 |
311 ns |
.rotationX |
273 ns |
| Operation / 操作 | Time / 时间 (avg) |
|---|---|
.determinant |
4.5 ns |
.inverse |
308 ns |
.transpose |
279 ns |
.mul |
467 ns |
.mulVec4 |
315 ns |
.mulVec3 |
307 ns |
| Operation / 操作 | Time / 时间 (avg) |
|---|---|
.identity |
274 ns |
.translation |
293 ns |
.rotationX |
265 ns |
.rotationY |
264 ns |
.rotationZ |
257 ns |
.scale |
264 ns |
.perspective |
262 ns |
.orthographic |
264 ns |
.frustum |
285 ns |
.lookAt |
1.9 µs |
| Chain / 链路 | Time / 时间 (avg) |
|---|---|
perspective * lookAt * scale |
3.4 µs |
To run the benchmarks yourself / 自行运行基准测试:
deno bench bench/matrix.bench.ts