Here is my proposal for how quaternions in Blender could work moving forward.
Core proposal
The core of the proposal is to add a single new quaternion rotation mode, like so:
…with the following properties:
- Blender internally recognizes the WXYZ channels as being associated.
- Key frames are always on WXYZ together. In other words, having different channels keyed on different frames isn’t possible.
- Key frames are enforced to be normalized. (But segments between key frames are not).
I think these three properties together allow some really nice things, and provide a lot of flexibility for designing how things work.
The remainder of this proposal is one way things could work within that core, and I think helps illustrate the advantages that fall out of it. But I hope this can be a jumping off point for further discussion and refinement. (Having said that, the following isn’t a throw-away proposal by any means.)
Per-segment interpolation modes
Standard fcurves allow users to interpolate different parts of the curve differently. For example, one segment can be linear, another constant, and another spline. It all works together nicely because all keys are valid for any interpolation approach.
By enforcing that all quaternion channels are keyed together and are normalized at those keys, we get the same benefit with quaternions. One segment can be constant, another slerp, and another per-component spline, and it all works together.
I think this is a more practical and useful solution than having completely different quaternion modes for each type of interpolation, and it also keeps quaternions working more like other curves, making things less jarring for users.
Quaternions as quaternions
I propose that we still display quaternions as WXYZ in the fcurves editor, n-panel, etc. Blender would enforce normalization when tweaking those values by hand.
The main concern with exposing quaternions as quaternions like this is that it potentially gets in the way of shortest-path interpolation. But I believe there’s a reasonable solution to that (see the section below).
Additionally, visualizing things as the actual WXYZ values makes it easy for users to tweak the tangents of spline segments, and it potentially even enables the use fcurve modifiers (sometimes useful for e.g. adding jitter/wobble).
Shortest-path interpolation
Always taking the shortest rotation path when interpolating is desirable, as it avoids a host of issues including (as outlined clearly by @StefanW):
- Preventing ill-formed interpolation situations (specifically, interpolating between opposite quaternions).
- Preventing accidental sub-frame long-way-around interpolations.
It also generally provides a more intuitive way for animators to work, who ideally shouldn’t need specific education about double-cover and its properties.
However, exposing the WXYZ values seems to preclude shortest-path interpolation. For example, consider the following animation curves:
This is a (per-component) spline interpolation between two quaternion keys, and already takes the shortest path. If we flip one of the quaternions, however, we get this:
This is now interpolating the long way around. At first glance, it seems impossible to take the shortest-path interpolation here while still displaying the quaternion values as they actually are. However, there is a solution: allow discontinuities in the curves:
(Actual visualization of the discontinuity very open to improvement.)
This might seem ugly, and… it is. But there actually is a discontinuity in quaternion space is these cases, so it’s representing things accurately. Moreover, discontinuities are already a part of fcurves in the form of constant interpolation, so it isn’t introducing anything new in that sense.
I personally prefer this from a visualization standpoint, as it provides an opportunity for users to understand what’s happening with the real data if they want to. But more important than the visualization is what it enables practically:
- We can still work with quaternions as quaternions.
- We can include all interpolation approaches (constant, lerp, etc.) within the same animation curve.
- Animators can still adjust tangent curves and other data where relevant.
- Fcurve modifiers can still be used.
- Possibly other things as well…?
Finally, it’s completely mechanical and lossless to fix these discontinuities by iteratively flipping quaternion keys (and their tangents) wherever discontinuities are encountered. We could even introduce an operator that does this automatically, similar in spirit to the Euler discontinuity filter.
What to do about squad?
(Edit: upon further poking around, it seems that what I’ve described below isn’t squad. I’ve always assumed it was, since it’s what’s described in the widely referenced Shoemake paper. With that in mind… I don’t think squad itself is actually useful, and what I’ve actually been referring to as squad is what I’ve described below. I’ll leave the below unedited.)
My initial thought when drawing up this proposal was that, at least for a first implementation, we would leave out squad, and just provide the following interpolation approaches:
- Constant
- Slerp (linear)
- Per-component spline.
I do think these three cover the practical animation use-cases. And you may notice as well that I’ve dropped lerp, since slerp covers its use-case strictly better.
But on further thought, I think some discussion about squad is needed before settling on any proposal (whether this one or another).
As a quick primer for anyone unfamiliar: squad is directly analogous to standard cubic bezier curve interpolation, but in spherical space. Given four unit quaternions start, handle_1, handle_2, and end, as well as an interpolation scalar t in [0, 1], you do the following:
a = slerp(start, handle_1, t)
b = slerp(handle_1, handle_2, t)
c = slerp(handle_2, end, t)
final = slerp(slerp(a, b, t), slerp(b, c, t), t)
(To further emphasize how analogous this is: if you replaced all the slerps above with lerps, you would have standard cubic bezier interpolation.)
The essential similarity of this to Blender’s standard fcurve splines makes it really tempting to just use this instead of per-component splines. And I think that’s a perfectly fine thing to propose–I’m halfway there myself. But there are some issues:
- How can users work with the tangent handles? In particular, they have to be unit quaternions.
- Are there meaningful performance implications here? Slerp is a bit computationally spendy, and here we’re doing six of them.
- How do we calculate the tangent handles automatically? This is covered in the original paper “Animating Rotation with Quaternion Curves” by Ken Shoemake, but it doesn’t address things like “clamped auto” which are useful in practice for animators, but not (to me) obvious how to formulate in spherical space.
One possibility for issue 1 above is to just let the user manipulate the handles un-normalized, and normalize them before plugging them into the squad evaluation. Automatic handles would still produce normalized handles. I think this could work nicely.
For issue 2, there may be alternative formulations of squad that use fewer slerps (I’m not sure). And we could use a fast approximate slerp in the spirit of Hacking Quaternions or Approximating slerp. And knowing that all channels are keyed together, SIMD could potentially be employed as long as we avoid branching in our slerp approximation.
For issue 3, I don’t really have any specific thoughts yet.
Ultimately, I think this all comes down to the following question: does squad, in practice, have any properties that we care about over per-component splines? I think for the large majority of use-cases, the answer is no, as evidenced by animators getting along just fine without it up to this point. But there may be important niches, and maybe there are secondary things it would enable that are valuable.
Maybe it’s okay to punt on it for now, and just implement constant, slerp, and per-component spline first. And then if concrete use-cases show up for squad down the line, we can sort this out and implement it then. But it would be kind of unfortunate to ultimately end up with two confusingly similar interpolation approaches that users have to choose between.
Visualizations and tooling
Conspicuously absent from this proposal is anything about more sophisticated visualizations or tooling, such as viewport-based manipulation. This is on purpose. Not because I don’t think that would be useful (on the contrary). But rather because I think that can and should be layered on top of a more technical foundation like this that addresses the core technical issues.
Partly that’s simply because it seems feasible to do so, and addressing problems one-at-a-time is easier. But more importantly, it’s because those kinds of advanced visualizations and tooling apply to more than just quaternions or even rotations, and I think it would be better to address that in a holistic way that looks more broadly at how we want to enable people to work with animation.



