geomancy: Vectors and matrix manipulation

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Warnings:

Sometimes it is unavoidable you have to do stuff on CPU. Let's at least do it faster.


[Skip to Readme]

Properties

Versions 0.2.2.3, 0.2.2.4, 0.2.3.0, 0.2.4.0, 0.2.4.1, 0.2.4.2, 0.2.5.0, 0.2.6.0, 0.3.0.0, 0.3.0.1, 0.3.1.0, 0.4.0.0
Change log ChangeLog.md
Dependencies base (>=4.7 && <5), containers, deepseq, gl-block, mono-traversable, ptrdiff, serialise, simple-affine-space, template-haskell, webcolor-labels [details]
License BSD-3-Clause
Copyright 2020-2026 IC Rainbow
Author IC Rainbow
Maintainer aenor.realm@gmail.com
Category Graphics
Source repo head: git clone https://gitlab.com/dpwiz/geomancy
Uploaded by AlexanderBondarenko at 2026-10-21T22:59:47Z

Modules

Flags

Manual Flags

NameDescriptionDefault
serialiseEnabled
th-liftEnabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for geomancy-0.4.0.0

[back to package description]

Geomancy

Linear is nice, but slow. Those are naughty, but a bit faster.

The Numbers

Storing a list of transformations (e.g. rendering instance data):

    poke
      10
        geomancy: OK
          42.3 ns ± 1.4 ns, 0.47x
        linear:   OK
          90.5 ns ± 3.1 ns
        linear/T: OK
          81.6 ns ± 2.7 ns
...
      1000
        geomancy: OK
          2.85 μs ±  37 ns, 0.36x
        linear:   OK
          7.93 μs ± 132 ns
        linear/T: OK
          7.08 μs ± 348 ns

Folding down a gloss-style scene tree is where it is all started:

    multiply
      2
        geomancy: OK
          12.3 ns ± 164 ps, 0.34x
        linear:   OK
          36.1 ns ± 1.3 ns
...
      1000
        geomancy: OK
          7.71 μs ±  93 ns, 0.23x
        linear:   OK
          34.0 μs ± 1.3 μs

Add that time to the poking that'll follow.

Sure, it is in the lower microseconds range, but this budget can be used elsewhere.

Benchmarking and comparing

stack bench --ba '--csv baseline.csv --stdev 2 --timeout 120'
stack bench --ba '--baseline baseline.csv --fail-if-slower 5'

Conventions

Matrix layout

Transforms produced, composed, and applied to mimic the GLSL order (col-major):

This way you don't have to transpose your transforms or fiddle with layout annotations.

Projections / Views

Geomancy.Vulkan.Projection is using the "reverse-depth" trick that remaps the vulkan default [0; 1] range to [1; 0]. This grants extra precision with one less parameter to specify (you only need "near" now), but makes handedness reasoning tricky. The default depth range the coordinate is left-handed (+X right, +Y down, +Z forward). But after reversing the depth it has to be paired with a right-handed view function like Geomancy.Vulkan.View.lookAtRH.

The intended up vector is still vec3 0 (-1) 0 -- +Y down. Silly as it sounds, this matches the XY plane of the window with XY plane in front of a "first person" camera.

Rotations

Axis rotations (using rotateQ) will appear clockwise when looking along the axis.

Angle rotations follow Tait-Bryan angles (heading/elevation/bank or yaw/pitch/roll) in the y-x-z frame.

Using Geomancy.Quaternion.intrinsic roll pitch yaw will make a rotation from the 3 angles in one go. You can use it to rotate a point directly (e.g vec3 0 0 1 to get a direction vector from Quaternion) or commit to a matrix using Transform.rotateQ.

yaw-pitch-roll

You're of course free to define your own transforms, just copy the modules and tune to your liking. Just make sure that you use matching row/column constructors and the math layer will do the rest, fast.

GLSL-like functions

To further facilitate conversion between the host and shader code Geomancy.Gl.Funs provides common functions like glFract and smoothstep.