Jump to content
  • Advertisement
Sign in to follow this  
drwhat

[D3D11] ViewMatrix problem. Camera flipping 180 Degrees.

This topic is 797 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a basic DirectX11 pipeline setup (probably the same as numerous tutorials online).   I am drawing 2 flat squares orthogonal to each other. (The top of a box, and one of its side).   Each frame I move my camera around one axis so it takes 5 seconds to complete a revolution.   (Basically I just take the sin/cos of angle over time such that 2PI = 5 seconds).    When I rotate around the Y-Axis, by varying x and z position of my camera it rotates perfectly.   However if I ever rotate around the X, or Z axis  and thus the y component of my camera changes,  halfway around the rotation the camera will always flip upside and continue the rotation.  Then when it reaches the original position, flips back "upright".  

 

It seems to occur when the camera is looking down(or up)  the y-axis, and the other co-ordinate (either X ,or Z) switches from positive to negative.  I assume this is a result of creating the View Matrix with the UPVector of (0.0 , 1.0, 0.0).   If anyone more familiar with the math could help explain why it does that, it would be greatly appreciated.   There doesn't seem to be any particular reason for the camera to spin 180 degrees like that.  Other than the spinning at the two y-axis poles when I rotate in 2 dimensions everything else seems to be working exactly as I expect it to.

 

EDIT:  I just realized what was happening by imagining a camera going over the top of the earth, As it crosses the north pole, the "top" of the camera will be pointing downward, so DirectX is flipping it back upright.   I guess I just need to keep track of when I want my camera to be upside and tell DirectX that.

Edited by drwhat

Share this post


Link to post
Share on other sites
Advertisement

Yep it is your up vector, you'll need to keep the camera vector in local space not world space.

Share this post


Link to post
Share on other sites

Sounds like you mostly figured it out. The "Up" vector is a vector that points "above" the camera. You can use the 0,1,0 cheat as long as you don't cross that horizon line and try to go upside down.

 

The "Up" vector is used with the forward vector to compute a right or left vector. Let me back up a step or two. You give it the camera position, the position to look at, and the "Up" vector. The first two positions are shoved into vectors and then you do vector subtraction on them to build the vector that gives the facing direction of the camera, but that doesn't give you the orientation of the camera. To get the orientation you need 3 mutually perpendicular vectors. The "Up" vector is a vector that points above the camera and that vector and the forward vector can form a plane (the only plane those two can simultaneously live on together). And from that you can do a vector cross product to give you a vector that points perfectly out of that plane. If the Up vector had of been exactly what it was supposed to be, you could use it as is, but there's an assumption that you're cheating or at least not specifying it exactly. So, you use the forward vector and the right facing vector (the one you just calculated) to do another cross product and get the direction facing perfectly out of that plane. Then you can throw away the Up vector because you now have 3 mutually perpendicular vectors that describe the orientation of the camera. Combine that with the camera position and you have a 4 by 4 view matrix.

 

If you tell it down is up though, you'll get a left facing vector for the first cross product instead of a right facing vector, which would have then given you a down vector instead of an up vector on the next calculation. By giving it the wrong vector (world up instead of the camera's up) you short circuited the math and it can never turn upside down because you're telling it the area above the camera is the world up even when the camera is upside down.

 

A better solution than all of this is to trust your view matrix to hold your camera orientation. That's what it's for. So, instead of rebuilding it every frame, just let it do it's job: build it once and adjust it as needed. Rotate it or transform it when you need to. It's no different than an object's world matrix except it is inversed. So, you either need to do an inverse rotation or transformation, or inverse it, change it, and invert it back. But you only have to build it once with a LookAt function. In fact, you could start it out as an identity matrix and never use a LookAt function. Experiment with it and see what you think.

Share this post


Link to post
Share on other sites

@BBeck:  Thanks for your reply.   My original problem was when I was first getting a handle on how DirectX worked.   Following what I think is your advice, I know have a camera Class that just holds the camera position, and a position its looking at.  Then I build 3 orthonormal Vectors for Up, LookAt, and Right.  This has worked very well.

 

Edit: On a side note,  is there any way to mark a problem as solved, by some tag, or changing the topic Title?

Edited by drwhat

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!