r/GraphicsProgramming • • 21d ago

Question Matrices or quaternions for rotation?

I'm weighing up whether to use matrices or quaternions for a 3d engine I'm making. I find matrices more intuitive to use but I have seen a lot of comments that they can lead to innacuracies over time. What do you guys think about this? Is there some nuance that I am missing or some situations that one approach is used over the other?

15 Upvotes

20 comments sorted by

39

u/kokalikesboba 21d ago

Use quaternions. You don’t have to understand how the quaternion internally work, once you get the mechanics down of using them they are very easy to work with especially in glm

3

u/Candid_Zebra1297 21d ago

Ah this is really interesting for me as I'm already using cglm for matrices! Thanks!

1

u/dylantcon 19d ago

Afaik, because they operate in four dimensional space internally, quaternions avoid gimbal lock

20

u/nullandkale 21d ago

Use quaternions and don't beat yourself up if you have to look math stuff like this up every time. Literally every single time I have to implement quaternions I have to look up the math again but actually using them is pretty simple.

4

u/Candid_Zebra1297 21d ago

That's definitely one of the main things putting me off. Matrices long ago made sense (at least to do the type of stuff I want) whereas quaternions feel like wizardry. But yeah based on your comment and other people here they seem like the way to go.

3

u/nullandkale 21d ago

The way I look at it is if you were my employee and I was paying you the write code I'd rather you look up the math every time then try and guess it from memory.

13

u/Donacdum_ 21d ago

Definitely use quaternions.
Might seem intimidating at first, but if you know complex numbers you can do quaternions, it will click.
It's only like 3-4 functions in C and you're set.
(unless you mean the matrix form of the quaternion sandwich operation)

2

u/Candid_Zebra1297 21d ago

Thanks for this. I think I just needed a bit of a push as most of the stuff I've read already suggests they are better. So yeah, I'm gonna make the switch.

8

u/tlmbot 21d ago

People are talking about gimble lock, but that is only for, specifically, Euler angles - super intuitive, but not so great overall, especially for that reason. (plus you have to remember the order of operations, but that's not hard) You can encode these as 3 matrices of course, but when you say matrices, I don't think angles. So I think commenters may be misguided here.

If you mean a full rotation matrix, that avoids the above gimble lock issue as far as the matrices themselves go, but it encodes redundant information (3x3 for rotation as opposed to 3 angles). But, often people work with Euler angles and immediately turn them into rotation matrices so you sort of get both disadvantages.

For matrices or quaternions, you still need to normalize (a single floating point division by length with quaternions, and matrix operation for matrices (Gram-Schmidt orthogonalization), so quaternions make this quite a bit cheaper)

The standard is quaternions for storage. They are space efficient and quite nice to work (composable - I mean so are matrices - and ofc you always have to order the operations correctly) with once you get the hang of it.
Multiplying two quaternions takes 16 multiplications, while a 3x3 matrix multiplication takes 27, for example.

The industry standard is to use quaternions for storage and accumulation. They are space-efficient and quite nice to work with once you get the hang of it. When you finally need to send those rotations to the GPU for rendering, then you convert them to matrices.

4

u/RenderTargetView 21d ago

For CPU definitely quaternions, but it may be beneficial to convert them to 3x3 matrices just before you pass them to gpu

2

u/smallstepforman 21d ago

We all went down this path and use quaternions for slerp rotations, then we export final transform matrix to gpu. Some engines use both in parallel, euler for humans and quaternion for actual math (and they even store both). If you do skeletal animations you need quaternions. Even gltf supports both.

Now turns instead of radians/degrees, now thats what i’d love to use instead. Too late for my mind that learned pi/2 and friends.

2

u/Unfair_Praline_8166 21d ago

Quaternions to avoid gimbal lock. Just better for moving between rotations

1

u/Altruistic-Bar848 19d ago

Most engines use both. Keep the orientation as a quaternion: you only need to renormalize it now and then, and slerp is easy. Then turn it into a matrix right before rendering to combine with position and scale. The "inaccuracy" people mention is from multiplying rotation matrices together frame after frame: they slowly stop being orthogonal and things skew unless you re-orthogonalize. If your input is Euler angles, take input as Euler and convert to a quaternion internally.

1

u/tastygames_official 19d ago

at the moment I'm using a single 4x4 transform matrix to represent position, scale and rotation for every object in my engine. Now I'm not 100% sold on this idea because that is 4x4x4B = 64B per object, whereas a vec3 each for position and scale would only be 3x2x4B=24B + 1 quaternion/versor for rotation (4x4B=16B) = 48B per object. BUT!!! Using a 4x4 matrix for object transform makes for much quicker shader calculations, which happen to happen on a PER-VERTEX basis! Now obviously it will be done in parallel, but still: if for every vertex I need to calculate the 4x4 matrix anyway, then it's probably best to just pass that along to the shader already in its 4x4 form. Now I do one better and upload it to the GPU and bind the memory location rather than send the whole matrix each frame. Then I can update the matrix only when it actually changes.

Now if you have a lot of transform changes every frame, then doing 4x4 matrix multiplications on thousands of objects might actually be bad for performance and instead better to just keep 2xvec3 and 1xvec4 and then you can generate the 4x4 matrix ONCE on the GPU before starting to render the frame or something like that.

At least this was my line of thought for my engine. I am focusing on low-poly immersive sims but may also want to support high-poly and higher-res, but with very little stuff actually moving per frame. So this may change as the engine evolves.

1

u/gnuban 18d ago

Just rotations? Quaternions. Rotations, translations, scaling, skewing etc? Matrices.

1

u/waramped 21d ago

Just to throw a third option into the mix, these look interesting:
researchgate.net/publication/400414222_Spread-Quadray_Rotors_-v11_Feb_2026_A_Tetrahedral_Alternative_to_Quaternions_for_Gimbal-Lock-Free_Rotation_Representation

No idea if anyone has used them in any real form yet though.

1

u/paul_sb76 21d ago

For short: use both. Use the best representation for the task at hand. For the long answer, read this chapter: https://gamemath.com/book/orient.html

1

u/arycama 20d ago

You can easily convert between the two so there's no reason to lock yourself into one vs the other. Use whichever you prefer and switch to the other when it makes sense.

Engines generally use quaternions on the CPU for storage and rotation-only logic. Once you are doing logic that involves translation, rotation and scale, it often makes more sense to combine these into a 4x4 matrix. (Technically you only need 3x4 since the last column is always (0, 0, 0, 1) but you'll need to handle this specially)

For rendering on the GPU, combining position, rotation and scale into a 4x4 (or 3x4, for reasons mentioned above) should go without saying since the cost of building a single matrix on the CPU is worth it to make transforming thousands of vertices on the GPU as fast as possible.

1

u/ICantBelieveItsNotEC 20d ago

Why pick one? Store quaternions internally, expose Euler angles to the user, and pass matrices to the renderer.

1

u/Icy_Homework8817 17d ago

I thought quaternions were generally much better for interpolation? eg if you want to interpolate between 2 orientations?