Table of Contents
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
cl-gmath
Graphics math for Common Lisp: vectors, 3x3 and 4x4 matrices, 2D affine transforms and quaternions, of single floats and of doubles, with the transforms, cameras and projections a renderer needs. Values are plain specialised arrays, which go to the GPU as they are, and every function that makes a value can write it into one you give it instead, allocating nothing, for code that runs every frame.
(asdf:load-system :cl-gmath)
(defpackage #:example
(:use #:cl)
(:local-nicknames (#:gm #:cl-gmath)))
(in-package #:example)
;; A model turned a quarter turn about Y and moved back, seen by a camera.
(let* ((model (gm:mat4-compose (gm:make-vec3 :z -2)
(gm:quat-from-axis-angle (gm:make-vec3 :y 1) (gm:radians 90))
(gm:make-vec3 :x 1 :y 1 :z 1)))
(view (gm:mat4-look-at (gm:make-vec3 :y 1 :z 3) ; the eye
(gm:make-vec3 :z -2) ; looks at the model
(gm:make-vec3 :y 1))) ; with +Y up
(projection (gm:mat4-perspective (gm:radians 60) 16/9 0.1 100))
(model-view-projection (gm:mat4* projection (gm:mat4* view model))))
;; Where the model's front, (0, 0, 1), lands: right of the centre of the
;; screen, level with it, and far away, at a depth near 0.
(gm:mat4-project-point model-view-projection (gm:make-vec3 :z 1)))
;; => #(0.19107175 1.4094049e-8 0.018630244)
What it gives you
- Plain values. A
vec3is a(simple-array single-float (3)), amat4sixteen single floats column by column, as GLSL lays them out. A vector or quaternion is also a typed structure over its array, with an accessor for each component, such asvec3-x. Functions are named for the type they take:vec3+,mat4*,quat-slerp. - Results without allocation. A function that returns a vector, matrix
or quaternion takes an optional last argument,
result, to write into, which may be one of its arguments. With it, nothing is allocated. - Doubles for large worlds. Every type has a counterpart of doubles,
such as
dvec3, with every function, for positions far from the origin, and conversions between the precisions. - The conventions of today's engines. Right-handed, +Y up, a camera looking down −Z, as in Godot, Bevy, glTF and Blender; Vulkan's clip space, Y down, which cl-gfx uses on every backend; and reversed depth, which keeps precision far away.
- 2D transforms as
mat3x2s, the six numbers of a canvas transform. - Single numbers:
clamp,lerp,remap,smoothstepand their kin, of any reals. - Batches of points and matrices in flat arrays, over a range, as a job system's chunk gives it.
- SIMD on SBCL, through sb-simd: SSE, SSE2 and AVX on x86-64, NEON on ARM64, chosen when an image starts, for the 4x4 products, matrix times vector, transposes and batches. Every kernel computes the same bits as the scalar code, so every processor gets the same results.
- Errors that say what to change, such as inverting a singular matrix or a camera whose up is the direction it looks in.
Pages
| Page | What it covers |
|---|---|
| Getting Started | Requirements, loading, first steps, running the tests |
| Conventions | Storage, multiplication order, the coordinate system, clip space, reversed depth, angles |
| Vectors | vec2, vec3, vec4: components, arithmetic, lengths and angles, reflecting and projecting, limiting and moving |
| Matrices | mat3, mat4: products, inverses, transposes, elements, normal matrices |
| Quaternions | Rotations as quaternions: making, combining, rotating, interpolating |
| Transforms and Cameras | Translation, rotation and scale, points and directions, cameras and projections |
| 2D Transforms | mat3x2: a 2D node's transform, composing, inverting, points and directions |
| Single Numbers | clamp, lerp, inverse-lerp, remap, smoothstep, move-toward |
| Doubles | The types and functions of doubles, large worlds, converting between precisions |
| Results and Allocation | The result argument, code that runs every frame, threads |
| Batches and SIMD | Many points or matrices at once, with a job system; the SIMD kernels, and how to turn them off |
| Errors | gmath-error and what each message means |
| API Reference | Every exported symbol |
Status
Steps 6 and 12 of the engine's build order: the scalar code, which is also the reference the SIMD code is tested against, and the SIMD path for the 4x4 operations, with the batch routines. Doubles, the choice of SIMD kernels when an image starts, 2D affine transforms, the functions of single numbers, and the structures' constructors and accessors followed on 2026-10-14, and the same day projections moved to Vulkan's clip space, Y down.
Still to come, with the 3D renderer: the model matrices of translated world space; decomposing a matrix into translation, rotation and scale, and Euler angles; more ways to make quaternions; bounding boxes, spheres and frustums for culling; and rays, for picking.
Licence
MIT.