4 Home
dxtr edited this page 2026-10-17 04:43:21 +02:00
This file contains ambiguous Unicode characters

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 vec3 is a (simple-array single-float (3)), a mat4 sixteen 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 as vec3-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, smoothstep and 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.