geomancy-0.3.1.0@sha256:21917ccdecebed3034b3b34a9f2f1efa89e1bafc51466dbf1c1d4d37940708ea,2588Module documentation for 0.3.1.0
- Geomancy
- Geomancy.Elementwise
- Geomancy.Gl
- Geomancy.IVec2
- Geomancy.IVec3
- Geomancy.IVec4
- Geomancy.Interpolate
- Geomancy.Mat4
- Geomancy.Point
- Geomancy.Quaternion
- Geomancy.Swizzle
- Geomancy.Transform
- Geomancy.Tree
- Geomancy.UVec2
- Geomancy.UVec3
- Geomancy.UVec4
- Geomancy.Vec2
- Geomancy.Vec3
- Geomancy.Vec4
- Geomancy.Vector
- Geomancy.Vulkan
Geomancy
Linear is nice, but slow. Those are naughty, but a bit faster.
- All data types are monomorphic, unpacked and specialized.
Mat4andVec4areByteArray#.Mat4xMat4andMat4xVec4is done with SIMD.
The Numbers
Storing a list of 1000 transformations (e.g. rendering instance data):
benchmarking 4x4 poke/1000/geomancy
time 11.76 μs (11.66 μs .. 11.92 μs)
0.999 R² (0.998 R² .. 1.000 R²)
mean 11.75 μs (11.69 μs .. 11.86 μs)
std dev 283.4 ns (199.0 ns .. 399.0 ns)
variance introduced by outliers: 26% (moderately inflated)
If you’re willing to adjust your shaders, it’s only 2.4 times slower.
benchmarking 4x4 poke/1000/linear
time 28.29 μs (28.21 μs .. 28.38 μs)
1.000 R² (1.000 R² .. 1.000 R²)
mean 28.40 μs (28.34 μs .. 28.50 μs)
std dev 267.4 ns (145.5 ns .. 419.9 ns)
Keeping your shaders straight make the affair 6.1x slower.
benchmarking 4x4 poke/1000/linear/T
time 73.70 μs (73.06 μs .. 74.49 μs)
1.000 R² (0.999 R² .. 1.000 R²)
mean 72.77 μs (72.50 μs .. 73.22 μs)
std dev 1.129 μs (793.5 ns .. 1.580 μs)
Folding down a gloss-style scene graph is where it is all started:
benchmarking 4x4 multiply/1000/geomancy
time 20.79 μs (20.77 μs .. 20.83 μs)
1.000 R² (1.000 R² .. 1.000 R²)
mean 20.80 μs (20.78 μs .. 20.83 μs)
std dev 76.71 ns (60.01 ns .. 99.06 ns)
benchmarking 4x4 multiply/1000/linear
time 173.9 μs (173.6 μs .. 174.4 μs)
1.000 R² (1.000 R² .. 1.000 R²)
mean 173.5 μs (173.2 μs .. 174.4 μs)
std dev 1.733 μs (727.8 ns .. 3.422 μ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.
Conventions
Matrix layout
Transforms produced, composed, and applied to mimic the GLSL order (col-major):
vec4 vPosOut = P * V * M * vPosIn;vPosOut = (p <> v <> m) !* vPosIn
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.
rotateZ (time * rate)will follow the clock hands in 2D scenes and roll in 3D.rotateXwill follow the sun from sunrise to sunset, increasing elevation / pitching UP.rotateYwill turn you right, increasing yaw/heading eastwards.
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.
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.
Changes
Changelog for geomancy
0.3.1.0
- Fixed Block.sizeOf40 for Packed 3-vectors (was 16, now 12).
0.3.0.1
- Added Lift instances for data.
Opt-out by disabling the
th-liftflag. - Added Serialise instances for data.
Opt-out by disabling the
serialiseflag.
0.3.0.0
[0]releases without row/col-major, handedness, and counter/clockwise confusion.
This release brings sanity and consistency around the transform stack.
Transforms have proper col-major definitions.- Operation ordering follows the GLSL convention.
- The composition order is
(p <> v <> m <> ...)(from global to local). Reverse your transforms to adjust. - The application order is
m !* v(with the operators becoming infixr 5, just under the<>). It will doMᵀ * vinside for SIMD reasons and to match what GLSL does for itsM * vops.
- The composition order is
Geomancy.Vulkan.Projectionis right-handed, BUT produces reverse-depth range ([1; 0], In 3D infinite-Z converges to 0).- Replace your depth tests with
OP_GREATERand clear to0.0- get better precision for your migration troubles.
- Replace your depth tests with
Geomancy.Vulkan.Viewis right-handed, with +Z being forward.- 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.
- The intended up vector is still
- 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.
rotateZ (time * rate)will follow the clock hands in 2D scenes and roll in 3D.rotateXwill follow the sun from sunrise to sunset, pitching UP / increasing elevation.rotateYwill turn you right, increasing yaw / heading eastwards.
- 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.
- Added
webcolor-labelsinstances for UVec3/Vec3/Vec4.
0.2.6.0
Geomancy.Gl.Blockextract togl-blockpackage asGraphics.Gl.Block.- Added
convertfunction to vector modules to facilitate type-changing operations like rounding. - Added
Ixinstances for integral vectors. - Added
dotfor integral vectors.
0.2.5.0
- Added Geomancy.Gl.Block to derive packed/std140/std430 layouts generically.
Originally a part of the unpublished
glowpackage in thecodexproject by Edward Kmett. Addptrdiff-0to your stack resolvers.
0.2.4.2
- Support ARM/aarch64 SIMD.
0.2.4.1
- Support simple-affine-space-0.2
0.2.4.0
A bunch of experimental code to see what sticks.
- Added
simple-affine-spaceinstances.- The classes are re-exported from
Geomancy, bringing stuff likedotandnormalize.
- The classes are re-exported from
- Added
mono-traversableinstances andGeomancy.Elementwisewrapper. - Added
Pointwrapper andPointNaliases. - Added
Geomancy.Interpolatewith generic linear, quadratic and cubic functions.- ⚠️
VecN.lerphas wrong (flipped) order of vector arguments. This is fixed inlinear.
- ⚠️
- Added
Geomancy.Swizzleoverloaded labels. - Added
Geomancy.Gl.Funswith kinda-GLSL math functions, appropriately overloaded.
0.2.3.0
- Vec4 moved to ByteArray#.
- Mat4 !* Vec4 is now SIMD too.
0.2.2.4
- Add Transform trees.
0.2.2.3
- Add IVec and UVec 32-bit integer vectors.
0.2.2.2
- Fixed using Transform.apply with projection inverses.
0.2.2.1
- Add Vec2.
- Add pattern synonyms to
Geomancyre-exports. - Add Fractional instances.
- Add conversions from tuples and lower-dimension vecs.
0.2.2.0
- Add pattern synonym alternatives to
withVecN. - Add Mat4 converstion from
Linear.M44.
- Hide
toListandtoListTrans.
- Add
toList2dand publish its element-order wrappers.
0.2.1.0
Transform rewrite
- Change perspective FoV to radians.
- Add
infinitePerspective. - Add
Transform.inverse.
- Hide
mat4,withMat4.
0.2.0.0
Mat4 rewrite
- Add
rowMajor,withRowMajor,toListRowMajor. - Add
colMajor,withColMajor,toListColMajor. - Add
Mat4.inverse.
- Expose
matrixProduct.
- Add
scalarMultiply. - Add
Mat4.(!*)to use withVec4.
- Extract transformations to
Geomancy.Transformand use column notation.
- Add
Transform.(!.)andapplyto use withVec3.
- Rename
scaletoscale3.
- Add uniform
scale. - Add
scaleXYfor flat meshes.
- Rename
mkTransformationtodirPos.
- Add
rotateQviadirPoswith empty translation. - Add
Vec3.Packednewtype without extra padding.
0.1.3.0
- Update tests
- Add
zipWith
- Rename
elementwisetopointwise - Rename
colMajortotoList - Rename
rowMajortotoListTrans
0.1.2.1
- Add Mat4 multiplication test via
linear - Add
elementwise,colMajor,rowMajor
0.1.2.0
- Move projections and views to Vulkan namespace.
0.1.1.2
- Fix bug in quaternion rotationBetween.
0.1.1.1
- Add lookAtUp and rotationBetween.