# Why does this order of Quaternion multiplication not introduce roll into my fps-style character controller?

I'm working on an OpenGL based project (in C#), employing Quaternions to rotate my camera I first tried to:

cameraOrientation = cameraOrientation * framePitch * frameYaw;


This accumulated an undesired roll in my cam-controller which made rotations unusable. I found a post on stack exchange which suggested this reordering of operations:

cameraOrientation = framePitch * cameraOrientation * frameYaw;


Which completely solved this accumulation of roll. While I'm comfortable with matrix multiplication, I can't seem to understand why this removes roll accumulation. Does anybody have any articles or images so I can grok what's happening here?

It feels weird not to understand such a fundamental operation in my project. Thanks!

• Is this the StackExchange post you mentioned? I show some animated gif examples to try to explain this effect, which may help you if that's not the original source you used. – DMGregory Sep 21 at 21:37
• I hadn't seen that post but it helps a lot, thanks. So from my understanding the rearranging makes the pitch dependent on a global orientation instead of the camera's or the yaw's? – Charly Sep 21 at 21:56