Search code examples
graphics3dtrigonometryprojectionraycasting

Translating a y-shearing horizon offset to a pitch angle in a raycaster


I am writing a first-person shooter, using raycasting to render the world. I have added y-shearing successfully, so that I can look up and down (albeit with a bit of warping, as expected). If my y-pitch value is zero, the horizon line (indicated by the the thin red line) is in the center of the screen.

center

If I am looking completely down, my y-pitch value equals -half_screen_height, because that offset is added to the horizon line. You can see the same thin horizon line near the top.

down

For looking completely up, the inverse applies. Now, the problem which I'm facing is that I want to incorporate vertical aiming to target enemies at heights higher than zero, like this one:

enter image description here

I am able to trace a 2D projectile because I have the view angle of the player, and from there I can step a certain X and Y amount in a loop, so that x += cos(theta) * step and y += sin(theta) * step. That is fairly easy. But in order to trace in a 3rd dimension, I need another angle that tells me how much I am looking upwards or downwards. Does anyone have an idea on how I can translate a y-pitch horizon line offset to an angle?

Edit: just to clarify, a commenter said that this is an altitude change, which is not true. Below is a GIF that demonstrates the difference between y-shearing (shown first) and changing the player height (shown second). For a given y-pitch value, it is added to each wall column's y position on screen, thus moving it upwards; but that is not an altitude change.

shear vs altitude change

Note: the GIF is very compressed because of stackoverflow's 2mb size limit.


Solution

  • I see it like this:

    triangle

    So your aim forms a right angle triangle along with shear and some predefined perpendicular distance (or distance to target) so:

    tan(tilt) =      shear/d
        tilt  = atan(shear/d)
    

    The shear is signed so the tilt will be also signed...

    The idea is that ratio of sides in right angle triangle will give you tan or ctg (which depends on which of the 2 angles and on order of the sides in ratio). And atan,actg are inverse functions to tan,ctg so applying it on the ratio or tan will get the original tilt angle...

    You empiricaly determined:

    d=half_screen_w/tan(fov/2.0)
    

    So its like end of the gun is near projection plane.