Fast 3D Math library for WebGPU
$ dotnet add package Blazor.WebGPU.MatrixThis is a port of WGPU-Matrix API Version 3.x which can be found here:
We tried to keep the API as close as possible but there are some notable differences:
ortho, perspective, frustum are differentcompare
// Blazor.WebGPU.Matrix
var t = Mat4.Translation([x, y, z]);
var p = Mat4.Perspective(fov, aspect, near, far);
var r = Mat4.RotationX(rad);
// gl-matrix
const t = mat4.create();
mat4.fromTranslation(t, [x, y, z]);
const p = mat4.create();
mat4.perspective(p, fov, aspect, near, far);
const r = mat4.create();
mat4.fromXRotation(r, rad);
Note that if you want to pre-create matrices you can still do this in Blazor.WebGPU.Matrix
var t = Mat4.Create();
Mat4.Translation([x, y, z], t);
var p = Mat4.Create();
Mat4.Perspective(fov, aspect, near, far, p);
var r = Mat4.Create();
Mat4.RotationX(rad, r);
Since this library depends on SpawnDev.BlazorJS, you must first setup it into your blazor project. Follow their own documentation for that.
using Blazor.WebGPU.Matrix;
var fov = 60 * MathF.PI / 180
var aspect = width / height;
var near = 0.1;
var far = 1000;
var perspective = Mat4.Perspective(fov, aspect, near, far);
var eye = [3, 5, 10];
var target = [0, 4, 0];
var up = [0, 1, 0];
var view = Mat4.LookAt(eye, target, up);
Note: for translation, rotation, and scaling there are 2 versions of each function. One generates a translation, rotation, or scaling matrix. The other translates, rotates, or scales a matrix.
using Blazor.WebGPU.Matrix;
var t = Mat4.Translation([1, 2, 3]); // a translation matrix
var r = Mat4.RotationX(MathF.PI * 0.5); // a rotation matrix
var s = Mat4.Scaling([1, 2, 3]); // a scaling matrix
using Blazor.WebGPU.Matrix;
var m = Mat4.Identity();
var t = Mat4.Translate(m, [1, 2, 3]); // m * translation([1, 2, 3])
var r = Mat4.RotateX(m, MathF.PI * 0.5); // m * rotationX(Math.PI * 0.5)
var s = Mat4.Scale(m, [1, 2, 3]); // m * scaling([1, 2, 3])
Functions take an optional destination to hold the result.
using Blazor.WebGPU.Matrix;
var m = Mat4.Create(); // m = new mat4
Mat4.Identity(m); // m = identity
Mat4.Translate(m, [1, 2, 3], m); // m *= translation([1, 2, 3])
Mat4.RotateX(m, MathF.PI * 0.5, m); // m *= rotationX(Math.PI * 0.5)
Mat4.Scale(m, [1, 2, 3], m); // m *= scaling([1, 2, 3])
mat4.perspective,
mat4.ortho, and
mat4.frustum
all return matrices with Z clip space from 0 to 1 (unlike most WebGL matrix libraries which return -1 to 1)
mat4.create makes an all zero matrix if passed no parameters.
If you want an identity matrix call mat4.identity
mat3 uses the space of 12 elements
// a mat3
new [
xx, xy, xz, 0
yx, yy, yz, 0
zx, zy, zz, 0
]
This is because WebGPU requires mat3s to be in this format and since this library is for WebGPU it makes sense to match so you can manipulate mat3s in TypeArrays directly.
vec3 in this library uses 3 floats per but be aware that an array of
vec3 in a Uniform Block or other structure in WGSL, each vec3 is
padded to 4 floats! In other words, if you declare
struct Foo {
bar: vec3<f32>[3];
};
then bar[0] is at byte offset 0, bar[1] at byte offset 16, bar[2] at byte offset 32.
See the WGSL spec on alignment and size.
WebGPU follows the same conventions as OpenGL, Vulkan, Metal for matrices. Some people call this "column major". The issue is the columns of a traditional "math" matrix are stored as rows when declaring a matrix in code.
[
x1, x2, x3, x4, // <- column 0
y1, y2, y3, y4, // <- column 1
z1, z2, z3, z4, // <- column 2
w1, w2, w3, w4, // <- column 3
]
To put it another way, the translation vector is in elements 12, 13, 14
[
xx, xy, xz, 0, // <- x-axis
yx, yy, yz, 0, // <- y-axis
zx, zy, zz, 0, // <- z-axis
tx, ty, tz, 1, // <- translation
]
This issue has confused programmers since at least the early 90s 😌
Most functions take an optional destination as the last argument. If you don't supply it, a new one (vector, matrix) will be created for you.
// convenient usage
var persp = Mat4.Perspective(fov, aspect, near, far);
var camera = Mat4.LookAt(eye, target, up);
var view = Mat4.Inverse(camera);
// performant usage
// at init time
var persp = Mat4.Create();
var camera = Mat4.Create();
var view = Mat4.Create();
// at usage time
Mat4.Perspective(fov, aspect, near, far, persp);
Mat4.LookAt(eye, target, up, camera);
Mat4.Inverse(camera, view);
git clone https://github.com/Oblikovati/Blazor.WebGPU.Matrix.git
cd Blazor.WebGPU.Matrix\\Source
VisualStudio Blazor.WebGPU.Matrix.sln
You can run tests by running Blazor.WebGPU.Test.Runtime Project
Now go to https://localhost:7286/.
You can Click 'Run Tests' to run all the tests. Or Run tests individually.
This package is maintained by Vinicius Miguel
PRs with bug-fixes and test enhancements are welcome.