This is actually not so simple. Look at this image (this is a 2D projection for simplicity):

- . , . , , . , .
:

, . , (fovy, znear, zfar, aspect), , .
:
:
h = 2 * tan(fovy/2) * znear
w = aspect * h
:
rectangle = ( x0, y0, x1, y1 )
- :
rcenter = ( (x0+x1)/2, (y0+y1)/2 )
:

, , :
center = ( (rcenter.x / screen_width - 0.5) * w,
(0.5 - rcenter.y / screen_height) * h, 0 )
:
centerWS = center.x * camera_right_dir + center.y * camera_up_dir
(dir2n):
dir1 = camera_dir * znear
dir2 = dir1 + centerWS
dir2n = normalize(dir2)
(. 2):
, .
, :
(w, h) / dist = (w * (x1-x0)/screen_width, h * (y1-y0)/screen_height) / znear
(1, 1) / dist = ( (x1-x0)/screen_width, (y1-y0)/screen_height) / znear
(1/dist, 1/dist) = ( (x1-x0)/screen_width, (y1-y0)/screen_height) / znear
:
dist = znear * screen_width / (x1-x0)
:
dist = znear * screen_height / (y1-y0)
, , , , (x1-x0) (y1-y0) .
:
pos2 = pos1 + dir2n * (dist-znear)