<p>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:</p>
<pre><code>pos = [-10, 0, 0] # Camera position
target = [1, 0, 0] # Camera looks at this point
up = [0, 0, 1] # z direction is &quot;up&quot;

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
</code></pre>
<p>I added two lines to the scene, a red one from <code>[1, 0, 0]</code> to <code>[1, 0, 1]</code> and a black one from <code>[4, 0, 0]</code> to <code>[4, 0, 1]</code>. The black one is clearly further away from the camera, but appears larger:</p>
<p><a href="https://i.sstatic.net/oCPAg.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/oCPAg.png" alt="Two overlapping vertical lines starting from the same bottom point. The red one is thicker and smaller than the black one." /></a></p>
<p>From the above description, at first I have constructed the view matrix</p>
<pre><code>V = [[0, -1, 0,   0],
     [0,  0, 1,   0],
     [1,  0, 0, -10],
     [0,  0, 0,   1]]
</code></pre>
<p>which seems to be correct. The perspective matrix I calculated is</p>
<pre><code>P = [[4.5107,      0,         0,     0],
     [0,      4.5107,         0,     0],
     [0,           0, -1.000004, -0.02],
     [0,           0,         -1,    0]]
</code></pre>
<p>I'm assuming the problem is somewhere here. The full transformation matrix is (using numpy):</p>
<pre><code>T = numpy.dot(P, V)
</code></pre>
<p>and the transformed points:</p>
<pre><code>p_transformed = numpy.dot(p_untransformed, T.T) # Transpose on the right hand side
</code></pre>
<p>For example, <code>[1, 0, 1]</code> becomes <code>[0, 4.5107, 8.98, 9]</code> and <code>[4, 0, 1]</code> becomes <code>[0, 4.5107, 5.98, 6]</code> 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.</p>
<p>Is there a mistake somewhere? If so, where is it?</p>
<h2>Edit: Formulae</h2>
<p>Here are the formulae I used:</p>
<p><a href="https://i.sstatic.net/sAVdJ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/sAVdJ.png" alt="enter image description here" /></a></p>
<p>where</p>
<pre><code>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
</code></pre>
<p>Furthermore, the formula for P is</p>
<p><a href="https://i.sstatic.net/nsPTz.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/nsPTz.png" alt="enter image description here" /></a></p>
<p>(<a href="http://www.songho.ca/opengl/gl_projectionmatrix.html" rel="nofollow noreferrer">Source</a>)</p>
<p>where</p>
<pre><code>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
</code></pre>

CC BY-SA 4.0
2020-06-21T19:22:34.050Z
Write out formally the formulae you use to construct the view and projection matrices.
lightxbulb
CC BY-SA 4.0
2020-06-21T20:17:20.407Z
@lightxbulb I added the formulae.
HerpDerpington
CC BY-SA 4.0
2020-06-21T20:21:45.200Z
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.
lightxbulb
CC BY-SA 4.0
2020-06-21T20:50:29.927Z
@lightxbulb The minus sign in the camera matrix is missing, because *d* is defined to point in the opposite direction as usual; for example this [site](https://learnopengl.com/Getting-started/Camera) defines it the opposite way. The minus sign in the first and second component remain, because I also flipped the order of the crossproducts. I think that the matrix should work...
HerpDerpington
CC BY-SA 4.0
2020-06-21T20:54:30.600Z
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.
lightxbulb
CC BY-SA 4.0
2020-06-21T22:25:19.653Z
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.
wychmaster
CC BY-SA 4.0
2020-06-21T22:52:30.993Z
@lightxbulb I see what you mean. Thank you, that fixed it.
HerpDerpington
CC BY-SA 4.0
2020-06-22T00:09:39.377Z
Write an answer to it yourself and self-accept it so this doesn't have to stay open.
lightxbulb
<rendering><transformations><mathematics><projections>
Why does my self-written rendering engine make further away objects look larger?
HerpDerpington
# Why does my self-written rendering engine make further away objects look larger?

(Asked by: username_0 on 2020-06-21)

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:

[![Two overlapping vertical lines starting from the same bottom point. The red one is thicker and smaller than the black one.](https://i.sstatic.net/oCPAg.png)](https://i.sstatic.net/oCPAg.png)

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:

[![enter image description here](https://i.sstatic.net/sAVdJ.png)](https://i.sstatic.net/sAVdJ.png)

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

[![enter image description here](https://i.sstatic.net/nsPTz.png)](https://i.sstatic.net/nsPTz.png)

([Source](http://www.songho.ca/opengl/gl_projectionmatrix.html))

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

```

**Tags:** rendering, transformations, mathematics, projections

> **Comments:**
> **username_1**: Write out formally the formulae you use to construct the view and projection matrices.  
> **username_0**: @username_1 I added the formulae.  
> **username_1**: 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.  
> **username_0**: @username_1 The minus sign in the camera matrix is missing, because *d* is defined to point in the opposite direction as usual; for example this [site](https://learnopengl.com/Getting-started/Camera) defines it the opposite way. The minus sign in the first and second component remain, because I also flipped the order of the crossproducts. I think that the matrix should work...  
> **username_1**: 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.  
> **username_2**: The projection matrix is correct. I checked it and got the same results with some minor floating point variations. @username_1 is right about the wrong sign.  
> **username_0**: @username_1 I see what you mean. Thank you, that fixed it.  
> **username_1**: Write an answer to it yourself and self-accept it so this doesn't have to stay open.  

---

## 0 answers

