0
\$\begingroup\$

I've got a fixed projection perspective camera with a vertical FOV of 70 deg and rotated 45deg on Y axis.

Player movement is along Camera's X axis (right/left), Z axis (front/back), Y axis is set to 0.

What I'd like to achieve is for the player to move directly towards the screen top/bottom when pressing forward/back keys instead of moving along camera's Z axis which causes and illusion of traveling at an angle the further from the center of the screen you are (which makes sense but is not desired in this case).

The screenshot below depicts:

  • Green: Direction to camera
  • Blue: Camera's Z axis (player movement forward/back)
  • Red: Desired forward/back movement vector

enter image description here

I was able to brute-force some values like if camera's Z axis are at 45deg to the player-camera direction then the desired rotation would be half of that (22.5deg) but I can't seem to find a solution for the rest of the world positions due to my lack of Math knowledge.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I've thought of a possible solution to this, but it feels really inelegant, so I would be interested in hearing other people's take on this.

My idea is as follows:

Take the position of the player in screen space (2D). Add to it the desired movement direction (0,1) to get another 2D point in screen space.

Now, project both those points (the player position and the result of adding the vector) into 3D space. If you are using godot (which I think is what that screenshot is), the camera has a project_position method that does this. The catch here is that any point in the screen maps to infinitely many points in space, so you need to specify a depth to get a single 3D point. I believe any depth should work, as long as you keep it consistent for both points, but it probably makes the most sense to use the depth of the player character (its z position in the camera's local space).

If you now connect those two 3D points you get a vector in 3D space which, when drawn on the camera, looks completely vertical.

Of course, this vector is not going to be parallel to the surface on which the caracter is walking, so you probably want to project it there and whatnot.

I feel like there is a much better solution using the camera's projection matrix to undo the perspective deformation, but I'm afraid I don't know how :(

\$\endgroup\$
4
  • \$\begingroup\$ Hi, thanks for your answer this was one of the things I've tried, but couldn't quite implement due to the depth, will give it one more chance though. I do believe that there might be a better approach with projection/view matrices \$\endgroup\$ Commented Sep 6, 2022 at 12:02
  • \$\begingroup\$ I gave your suggestion a try and indeed it creates an interesting optical illusion of a 90deg line towards bottom edge of the screen but in fact it's a vector pointing towards the camera. For the life of me I couldn't apply it to the player movement without utterly destroying everything \$\endgroup\$ Commented Sep 6, 2022 at 18:55
  • \$\begingroup\$ hm, could you maybe post the code you are using? It seems to me like the concept should work, it could be an implementation bug. \$\endgroup\$
    – PepeOjeda
    Commented Sep 7, 2022 at 6:57
  • \$\begingroup\$ Thanks for your time, I'll go for a raycast solution until I stumble upon a mathematical solution to perspective transforms \$\endgroup\$ Commented Sep 7, 2022 at 15:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .