ArcRotateCamera upVector and alpha make wrong rotation

Hello. Please help me to understand how it works or is it a bug

I have ArcRotateCamera. I want to set upVector and then set alpha.

camera.upVector = new BABYLON.Vector3(0, -1, 0)
camera.alpha = 1.5707963267948966 // 90 degrees

It works good on different upVectors, but there’s some case that I can’t understand. If I set x = 0.01 and y = -1 of upVector like this new BABYLON.Vector3(0.01, -1, 0) it seems that alpha is changed too. If x is 0.04 it still works strange. But when x is 0.05 it works predictable again.

Here is an example:

I expect that the blue arrow always looks down and the red arrow always looks right. But when camera.upVector = new BABYLON.Vector3(0.01, -1, 0) the angle of both arrows is changed about 45 degrees

Please uncomment one of these lines (13 - 15) for better understanding what I mean.

    // camera.upVector = new BABYLON.Vector3(0, -1, 0) // ok
    camera.upVector = new BABYLON.Vector3(0.01, -1, 0) // not ok
    // camera.upVector = new BABYLON.Vector3(0.1, -1, 0) // ok

Also if I set alpha = 0 OR upVector’s y = 1 (not negative) then it works good in all cases

Hi @uiosade welcome to the forum

This issue is named Gimbal Lock : Gimbal lock - Wikipedia

Basically, trying to keep an up vector aligned with view direction is unstable and a slow variation on 1 axis forces the other axis to realign.
Or, in other words, if a view and up are aligned, then there is an infinite number of possible axis values for right vector.

There is no perfect solution. Usually, in my PG, I set a limit to arc rotate camera angles so up and direction can’t be aligned.

3 Likes

Hello @uiosade, welcome ! :slight_smile:

Yeah as @Cedric said, it’s a gimbal lock issue, which happens only near perfect 90° angles.
Have a look at this topic (not specific to cameras) where I had explained a little bit about this issue :


To give an explanation proper to the camera, let’s consider this :
The ArcRotateCamera has 2 angles : Alpha (Azimuth, red), and Beta (Elevation, Blue)


In this situation, the camera will always be “straigth”, aligned with horizon


Which means you are missing one degree of freedom : rotating arround view axis :
Screencast from 05-12-2024 10:56:09
In the above GIF (Blender) you see this black axis attached to the mouse ? It’s the Up Vector.

By default it’s (0,1,0) :


And you would shift it a bit when you need the camera not aligned with horizon :


As you can see, the angle arround axis is defined by the plane made by the view vector (purple) and the up vector (yellow). If you have the up vector (almost) aligned with view vector, you create a huge instability of the camera angle. You should always try to keep your up vector perpendicular to view vector :slight_smile:

3 Likes

Thank you for your response. Is it possible to use quaternions with ArcRotateCamera?
As a result I need to see the box from exactly this position, as I tried to set up with upVector+alpha. I cannot rotate the box directly for some reasons, I want to rotate camera. But my approaches with ArcRotateCamera+Quaternion gave no result as if the ArcRotateCamera doesn’t work with quaternions

To me ArcRotateCamera is really to be used as is, I.E. rotating arround a target using Alpha & Beta. If you want to use any direction, why don’t you use a FreeCamera ?

1 Like

I tried FreeCamera and found out that camera’s position is what I need (probably). With defining a target it gives the same result for both ArcRotateCamera and FreeCamera.
The top of view depends on upVector so now I changed it to (0, 0, 1). User can change input field to set degrees for new top of view, but only around view axis (by the top of view i mean the triangle on the picture).

So I suppose I still have to rotate upVector by user’s angle. Because i set position and in case of changing alpha all is broken. I thought that the view vector can change itself depending on upVector. So if no, is the view vector same for upVector(0, 1, 0) and upVector(0, 0, 1)?
How can I know view vector coordinates?

Sorry for long time answer, all this time i was investigating

You can use Babylon.js docs with (0,1,0) as local vector.