# A faster quaternion-vector multiplication

Today’s post is only a small gem I accidentally came across while I was looking for something entirely different: a faster method of multiplying a quaternion by a vector.

I use quaternion-vector multiplication (rotating a vector by a quaternion) mostly in two places:

• When building the global pose of a skeleton from its local pose, as discussed in this blog post.
• In vertex shaders that are used with instanced rendering, so I only have to send one quaternion (float4) instead of a whole rotation matrix (float3x3).

The canonical way of multiplying a quaternion q by a vector v is given by the following formula:

`v' = q * v * conjugate(q)`

where the vector v is being treated as a quaternion with w=0, so the above essentially boils down to two quaternion multiplications, which are a bit expensive.

Turns out there is a faster way, which is the following:

```t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t)```

The faster method comes courtesy of Fabian Giesen (ryg of Farbrausch fame), who posted this to the MollyRocket forums years ago. Another derivation, yielding the same result, can be found here.

In my SSE2 code path, the new method is about 35% faster than the original. Enjoy, and don’t forget to share this gem with other people!

## 12 thoughts on “A faster quaternion-vector multiplication”

1. Francisco on said:

I optimized the quaternion rotation formula for a vector P and came up with this formula. Where v is the vector part of the quaternion and w is the scalar part. It runs about 15% faster than the formula that you posted here.
p’ = (v*v.dot(p) + v.cross(p)*(w))*2 + p*(w*w – v.dot(v))

• alekzander on said:

It is weird, that your method, which contains 22 float multiplications, 15% faster than post-proposed method with 15 float multiplication, If anything – it should yours to slower.

• tombsar on said:

I don’t think that’s right, Francisco. You’ve turned the term v.cross(v.cross(p)) into -v.dot(v)*p, which is only true in the special case v and p are perpendicular.

• tombsar on said:

Sorry, I somehow missed an entire term of the equation. I have now double-checked that Francisco’s formula is correct.

• Steve on said:

Francisco, I believe there’s a two missing —
. . . + p*(2*w*w – v.dot(v))

• Steve on said:

I believe Francisco’s alternate solution is correct otherwise, with the only assumption being that the quaternion is normalized (which is a common requirement when using them for rotations).

2. tombsar on said:

FYI both source links you provide for the derivation are dead. I think the forum post you mention is archived here: http://mollyrocket.com/forums/molly_forum_833.html albeit in a format that is rather difficult to read.

3. Xun Zhang on said:

This is also what the glm library uses. I found the implementation changes between versions, so the latest one should reflect what the developer finds the fastest.

4. Pingback: Faster quaternion product rotations

This site uses Akismet to reduce spam. Learn how your comment data is processed.