# Why does my self-written rendering engine make further away objects look larger?

I am writing a very simple rendering engine. I have already made a few tests, but somehow the images it creates look wrong. Objects that are further away from the camera look larger than objects closer to the camera. I have constructed this example:

pos = [-10, 0, 0] # Camera position
target = [1, 0, 0] # Camera looks at this point
up = [0, 0, 1] # z direction is "up"

fov_y = 25 * degree # field of view in y direction (camera y axis)
aspect_ratio = 1
near = 0.01 # Near clipping plane distance
far = 5000 # Far clipping plane distance


I added two lines to the scene, a red one from [1, 0, 0] to [1, 0, 1] and a black one from [4, 0, 0] to [4, 0, 1]. The black one is clearly further away from the camera, but appears larger:

From the above description, at first I have constructed the view matrix

V = [[0, -1, 0,   0],
[0,  0, 1,   0],
[1,  0, 0, -10],
[0,  0, 0,   1]]


which seems to be correct. The perspective matrix I calculated is

P = [[4.5107,      0,         0,     0],
[0,      4.5107,         0,     0],
[0,           0, -1.000004, -0.02],
[0,           0,         -1,    0]]


I'm assuming the problem is somewhere here. The full transformation matrix is (using numpy):

T = numpy.dot(P, V)


and the transformed points:

p_transformed = numpy.dot(p_untransformed, T.T) # Transpose on the right hand side


For example, [1, 0, 1] becomes [0, 4.5107, 8.98, 9] and [4, 0, 1] becomes [0, 4.5107, 5.98, 6] and since the last step is to divide the first three components by the last one, this results in the second line being larger than the first one.

Is there a mistake somewhere? If so, where is it?

## Edit: Formulae

Here are the formulae I used:

where

d = normalized(target - pos) # direction vector of the camera
r = normalized(cross(d, up)) # x unit vector in camera space
u = normalized(cross(r, d)) # y unit vector in camera space


Furthermore, the formula for P is

(Source)

where

n, f # position of near an far clipping plane
t = n * tan(0.5 * radians(fov_y))
b = -t
r = t * aspect_ratio
l = -r

• Write out formally the formulae you use to construct the view and projection matrices. Jun 21, 2020 at 19:22
• You're missing a minus in your view matrix. Just make the view matrix the inverse of the camera matrix. Also, your projection matrix flips the coordinate system so your camera starts looking in the opposite direction. Try fixing the missing sign first. Jun 21, 2020 at 20:21
• They did not make P_z positive when computing the view matrix. Rather than flip cross products, correctly set those up so no sign flips would need to leak into your matrices later on. Jun 21, 2020 at 20:54
• The projection matrix is correct. I checked it and got the same results with some minor floating point variations. @lightxbulb is right about the wrong sign. Jun 21, 2020 at 22:25
• Write an answer to it yourself and self-accept it so this doesn't have to stay open. Jun 22, 2020 at 0:09