2

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.

Caspian Ahlberg
  • 934
  • 10
  • 19
  • The shearing is not a tilt but changing altitude instead (see the jumping GIF at the end in [here](https://stackoverflow.com/a/47251071/2521214) ). So you might shoot your projectiles from different altitude (but still not tilted) so no need for angle just add the altitude. If you tilt the projectile trajectory I am afraid it would look weird. If you still want to do it then the angle would be `tilt = atan(shear/d)` where `d` is some constant perpendicular distance you are aiming at. If you have a laser dot then its the distance to the hitted wall, If not then use `d` as something fixed. – Spektre Oct 08 '21 at 07:51
  • @Spektre See my updated post; this is not an altitude change. I know it would look a bit weird with the stretch from the shearing, but I am okay with that. I have already added altitude changing in my engine, and that is also be a way in which you can hit enemies, as the projectile ray currently accounts for if the bullet position lands in a raised tile or not. – Caspian Ahlberg Oct 08 '21 at 22:41
  • @Spektre For the constant perpendicular distance, I used the distance to the projection plane, which I define as `half_screen_w / tan(fov / 2.0)`. Your formula seems to produce correct angles, which is amazing! Can you explain how it works? – Caspian Ahlberg Oct 08 '21 at 22:52
  • 1
    I created answer with some description how it works but its basic goniometric math. Your GIF shows me its really a tilt :) how it works? You are casting ray per pixel or per column of screen? if per column how are you distorting the floor/ceiling? How are you differentiating between altitude and tilt? – Spektre Oct 09 '21 at 07:56
  • 1
    btw you can use 16 colors GIFs with dithering and lower framerate ... that will shrink the size considerably. I often hit the 2MB limit too ... – Spektre Oct 09 '21 at 12:32
  • 1
    @Spektre I am differentiating between the two like this: for a tilt value of N (equivalent to the y-pitch above), I add N to the screen y-coordinate of every object in the scene, thus shifting walls + billboard sprites up or down. Here is how I am doing altitude changes: if my height is 1.5, I am standing above 1.5 blocks (same unit system as in 2D). Not accounting for multi-height walls (as that becomes more complicated), for a given wall column, the y-coordinate of the top equals `horizon_line - half_wall_height + player_height * wall_height`. – Caspian Ahlberg Oct 09 '21 at 18:34
  • Got it tilt is applied before projection and altitude after ... – Spektre Oct 10 '21 at 06:32
  • @Spektre Also, I am casting one ray per column of the screen; that ray travels until it hits the highest possible tile height or it is out of map to traverse. – Caspian Ahlberg Oct 10 '21 at 19:22

1 Answers1

2

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.

Spektre
  • 49,595
  • 11
  • 110
  • 380