Lily Math library for Graphics and Rendering.
Math library only for presentation, has support for 2D and 3D vector, Quaternion, and Matrix
⚠️ WARNING: NOT CROSS-PLATFORM BITWISE DETERMINISTIC
This library does NOT produce bitwise-identical results across platforms.
The same code with the same inputs is likely to produce different results on different machines (x86, Arm, WASM, etc.).
Cross-platform divergence can be caused by:
- Platform-specific SIMD optimizations
- Instruction selection, evaluation order, and FMA (fused multiply-add)
- Platform/libm differences in internal transcendental functions
- Denormal/subnormal handling and flush-to-zero (used sometimes for performance)
- NaN and signed-zero edge-case differences
- Approximation algorithms used by optimized math paths
- Compiler/backend/version-specific optimizations
You MUST NOT use this library for:
- Physics simulation
- Gameplay logic
- Lockstep or rollback networking
- Replay or re-simulation systems
- Serialization (can be accidentily used by gameplay, physics or used by other devices)
Conventions:
- Angles are in radians.
- Matrices are column-major.
References:
Structs
Vec2
struct Vec2 {
secret: Block<U8, 8>
}
2D vector.
Member Functions
new
fn Vec2::new(x: Float, y: Float) -> Vec2
Return a new 2D vector
x
fn Vec2::x(self) -> Float
Return the x component
y
fn Vec2::y(self) -> Float
Return the y component
magnitude
fn Vec2::magnitude(self) -> Float
Return the magnitude (length) of the vector
normalize
fn Vec2::normalize(self) -> Vec2
Return a normalized (unit length) vector.
Behavior is undefined if the input has zero magnitude.
add
fn Vec2::add(self, other: Vec2) -> Vec2
Add two vectors
sub
fn Vec2::sub(self, other: Vec2) -> Vec2
Subtract two vectors
dot
fn Vec2::dot(self, other: Vec2) -> Float
Compute the dot product of two vectors
lerp
fn Vec2::lerp(
self,
other: Vec2,
t: Float
) -> Vec2
Linear interpolation between two vectors.
t = 0.0 returns self.
t = 1.0 returns other.
distance
fn Vec2::distance(self, other: Vec2) -> Float
Distance between two points
string
fn Vec2::string(self) -> String
Convert vector to string for debugging
Vec3
struct Vec3 {
secret: Block<U8, 12>
}
3D vector.
Member Functions
new
fn Vec3::new(
x: Float,
y: Float,
z: Float
) -> Vec3
Return a new 3D vector
x
fn Vec3::x(self) -> Float
Return the x component
y
fn Vec3::y(self) -> Float
Return the y component
z
fn Vec3::z(self) -> Float
Return the z component
magnitude
fn Vec3::magnitude(self) -> Float
Return the magnitude (length) of the vector
normalize
fn Vec3::normalize(self) -> Vec3
Return a normalized (unit magnitude) vector.
Behavior is undefined if the input has zero magnitude.
add
fn Vec3::add(self, other: Vec3) -> Vec3
Add two vectors
sub
fn Vec3::sub(self, other: Vec3) -> Vec3
Subtract two vectors
dot
fn Vec3::dot(self, other: Vec3) -> Float
Compute the dot product of two vectors
lerp
fn Vec3::lerp(
self,
other: Vec3,
t: Float
) -> Vec3
Linear interpolation between two vectors.
t = 0.0 returns self.
t = 1.0 returns other.
distance
fn Vec3::distance(self, other: Vec3) -> Float
Distance between two points
string
fn Vec3::string(self) -> String
Convert vector to string for debugging
Mat3
struct Mat3 {
secret: Block<U8, 36>
}
3x3 column-major matrix.
Member Functions
identity
fn Mat3::identity() -> Mat3
Return an identity matrix
mul
fn Mat3::mul(self, other: Mat3) -> Mat3
Multiply (compose) two matrices.
Multiplication order matters.
string
fn Mat3::string(self) -> String
Convert matrix to string for debugging
Vec4
struct Vec4 {
secret: Block<U8, 16>
}
4D vector.
Member Functions
new
fn Vec4::new(
x: Float,
y: Float,
z: Float,
w: Float
) -> Vec4
Return a new 4D vector
x
fn Vec4::x(self) -> Float
Return the x component
y
fn Vec4::y(self) -> Float
Return the y component
z
fn Vec4::z(self) -> Float
Return the z component
w
fn Vec4::w(self) -> Float
Return the w component
string
fn Vec4::string(self) -> String
Convert vector to string for debugging
Quat
struct Quat {
secret: Block<U8, 16>
}
Quaternion for 3D rotations
Member Functions
identity
fn Quat::identity() -> Quat
Return an identity quaternion (no rotation)
from_rotation_z
fn Quat::from_rotation_z(radians: Float) -> Quat
Return a quaternion from rotation around Z axis
from_rotation_x
fn Quat::from_rotation_x(radians: Float) -> Quat
Return a quaternion from rotation around X axis
from_rotation_y
fn Quat::from_rotation_y(radians: Float) -> Quat
Return a quaternion from rotation around Y axis
x
fn Quat::x(self) -> Float
Return the x component
y
fn Quat::y(self) -> Float
Return the y component
z
fn Quat::z(self) -> Float
Return the z component
w
fn Quat::w(self) -> Float
Return the w component
normalize
fn Quat::normalize(self) -> Quat
Return a normalized (unit magnitude) quaternion
Behavior is undefined if the input has zero magnitude.
inverse
fn Quat::inverse(self) -> Quat
Return the inverse (opposite) rotation.
Behavior is undefined if the quaternion has zero magnitude.
mul
fn Quat::mul(self, other: Quat) -> Quat
Multiply (compose) two quaternions.
Think of this as combining an existing rotation with an additional “delta” rotation.
Multiplication order matters and is not commutative.
slerp
fn Quat::slerp(
self,
other: Quat,
t: Float
) -> Quat
Return the spherical linear interpolation between self and other.
t = 0.0 returns self.
t = 1.0 returns other.
nlerp
fn Quat::nlerp(
self,
other: Quat,
t: Float
) -> Quat
Normalized linear interpolation (nlerp).
Typically faster than slerp, but does not result in constant angular
velocity.
Use it for small angular differences or when interpolating frequently
(e.g. per frame), as it is faster and looks similar to slerp.
t = 0.0 returns self.
t = 1.0 returns other.
string
fn Quat::string(self) -> String
Convert quaternion to string for debugging
Vec4f
struct Vec4f {
w: F32
x: F32
y: F32
z: F32
}
Mat4
struct Mat4 {
secret: Block<U8, 64>
}
4x4 column-major matrix.
Member Functions
identity
fn Mat4::identity() -> Mat4
Return an identity matrix (no transformation)
ortho_2d_y_down_int
fn Mat4::ortho_2d_y_down_int(
width: Int,
height: Int,
zoom: Float
) -> Mat4
Return an orthographic projection matrix for 2D (Y-down).
width and height are viewport dimensions in pixels.
zoom must be positive.
Read more about projections
ortho_2d_int
fn Mat4::ortho_2d_int(
width: Int,
height: Int,
zoom: Float
) -> Mat4
Return an orthographic projection matrix for 2D with normal RH (Y-going up).
width and height are viewport dimensions in pixels.
zoom must be positive.
Read more about projections
ortho_2d_y_down_near_far_int
fn Mat4::ortho_2d_y_down_near_far_int(
width: Int,
height: Int,
near: Int,
far: Int
) -> Mat4
ortho_2d_pixel_y_down_near_far_int
fn Mat4::ortho_2d_pixel_y_down_near_far_int(
width: Int,
height: Int,
near: Int,
far: Int
) -> Mat4
Uses pixel centers (-0.5)
ortho_2d_pixel_near_far_int
fn Mat4::ortho_2d_pixel_near_far_int(
width: Int,
height: Int,
near: Int,
far: Int
) -> Mat4
Uses pixel centers (-0.5)
from_translation
fn Mat4::from_translation(
translation: Vec3
) -> Mat4
Return a translation matrix
from_rotation_z
fn Mat4::from_rotation_z(radians: Float) -> Mat4
Return a rotation matrix around Z axis (2D rotation)
from_quat
fn Mat4::from_quat(rotation: Quat) -> Mat4
Return a rotation matrix from a quaternion
from_scale
fn Mat4::from_scale(scale: Vec3) -> Mat4
Return a scale matrix
from_rotation_translation
fn Mat4::from_rotation_translation(
rotation: Quat,
translation: Vec3
) -> Mat4
Return a transform from rotation and translation (no scale)
from_scale_rotation_translation
fn Mat4::from_scale_rotation_translation(
scale: Vec3,
rotation: Quat,
translation: Vec3
) -> Mat4
Return a full transform from scale, rotation and translation
mul
fn Mat4::mul(self, other: Mat4) -> Mat4
Multiply (compose) two matrices.
Multiplication order matters.
A * B and B * A (usually) produce different results.
For example, rotate-then-translate is different from
translate-then-rotate.
Build projection P once (for the viewport), build model M per object
(for example, a translation), then multiply P * V * M.
This applies object/world transform first, then projection to clip space.
MVP convention:
M(Model): object local space -> world spaceV(View): world space -> camera/view spaceP(Projection): maps view space -> clip space and encodes projection (aspect ratio and orthographic/perspective)
translation
fn Mat4::translation(self) -> Vec3
Return the translation component (same as w_axis)
x_axis
fn Mat4::x_axis(self) -> Vec3
Return the first column vector
y_axis
fn Mat4::y_axis(self) -> Vec3
Return the second column vector
z_axis
fn Mat4::z_axis(self) -> Vec3
Return the third column vector
w_axis
fn Mat4::w_axis(self) -> Vec3
Return the fourth column vector (translation)
to_scale_rotation_translation
fn Mat4::to_scale_rotation_translation(
self
) -> (Vec3, Quat, Vec3)
Decompose transform into scale, rotation and translation.
to_mat4f
fn Mat4::to_mat4f(self) -> Mat4f
Convert to WebGPU type Mat4f (array of 16 F32)
inverse
fn Mat4::inverse(self) -> Mat4
Calculate the inverse matrix.
Behavior is undefined for non-invertible (singular) matrices. (e.g. when zero or close to zero scale on any axis)
transpose
fn Mat4::transpose(self) -> Mat4
Transpose the matrix (swap rows and columns)
string
fn Mat4::string(self) -> String
Convert matrix to string for debugging.
Do not rely on the string being formatted in a specific way.