Use perspective projection

Description

We can move our cube around, but we can't see the sides of it. We're using orthographic projection which doesn't reveal the depth of an object.

What we want is a perspective projection. Objects that are further away should appear closer to the center of the screen. The perspective projection divides the X and Y components by the depth Z. Objects further away (i.e. a larger Z) will have smaller X and Y values and appear closer to the origin.

Note that we don't do the division explicitly. It happens by setting the divisor as the fourth component of the vec4 for gl_Position. This is such a common operation in 3D applications that OpenGL handles the division for us as part of the rendering pipeline.

So a value of vec4(x, y, z, w) will yield a position of vec3(x / w, y / w, z / w).

Screenshot

Commands

git clone git@github.com:atsheehan/iridium
cd iridium
git checkout af936f024c372f0123f273edc452124e7a863033
cargo run --release

Code Changes

Modified shaders/cube.vertGitHub

@@ -1,14 +1,7 @@
11 #version 150
22
3- const float LEFT = 0.0;
4- const float RIGHT = 8.0;
5- const float BOTTOM = 0.0;
6- const float TOP = 8.0;
73 const float NEAR = 0.0;
8- const float FAR = 8.0;
9- const float WIDTH = RIGHT - LEFT;
10- const float HEIGHT = TOP - BOTTOM;
11- const float DEPTH = FAR - NEAR;
4+ const float FAR = 10000.0;
125
136 uniform vec3 position = vec3(2.0, 3.0, 6.0);
147
@@ -78,10 +71,10 @@
7871 vertices[35] = far_bottom_left;
7972
8073 mat4 world_to_clip_transform =
81- mat4(2.0 / WIDTH, 0.0, 0.0, -(RIGHT + LEFT) / WIDTH,
82- 0.0, 2.0 / HEIGHT, 0.0, -(TOP + BOTTOM) / HEIGHT,
83- 0.0, 0.0, 2.0 / DEPTH, -(FAR + NEAR) / DEPTH,
84- 0.0, 0.0, 0.0, 1.0);
74+ mat4(1.0, 0.0, 0.0, 0.0,
75+ 0.0, 1.0, 0.0, 0.0,
76+ 0.0, 0.0, 1.0, 0.0,
77+ 0.0, 0.0, 1.0, 0.0);
8578
8679 mat4 model_to_world_transform =
8780 mat4(1.0, 0.0, 0.0, position.x,
@@ -1,14 +1,7 @@
1 #version 150
2
3- const float LEFT = 0.0;
4- const float RIGHT = 8.0;
5- const float BOTTOM = 0.0;
6- const float TOP = 8.0;
7 const float NEAR = 0.0;
8- const float FAR = 8.0;
9- const float WIDTH = RIGHT - LEFT;
10- const float HEIGHT = TOP - BOTTOM;
11- const float DEPTH = FAR - NEAR;
12
13 uniform vec3 position = vec3(2.0, 3.0, 6.0);
14
@@ -78,10 +71,10 @@
78 vertices[35] = far_bottom_left;
79
80 mat4 world_to_clip_transform =
81- mat4(2.0 / WIDTH, 0.0, 0.0, -(RIGHT + LEFT) / WIDTH,
82- 0.0, 2.0 / HEIGHT, 0.0, -(TOP + BOTTOM) / HEIGHT,
83- 0.0, 0.0, 2.0 / DEPTH, -(FAR + NEAR) / DEPTH,
84- 0.0, 0.0, 0.0, 1.0);
85
86 mat4 model_to_world_transform =
87 mat4(1.0, 0.0, 0.0, position.x,
@@ -1,14 +1,7 @@
1 #version 150
2
 
 
 
 
3 const float NEAR = 0.0;
4+ const float FAR = 10000.0;
 
 
 
5
6 uniform vec3 position = vec3(2.0, 3.0, 6.0);
7
@@ -78,10 +71,10 @@
71 vertices[35] = far_bottom_left;
72
73 mat4 world_to_clip_transform =
74+ mat4(1.0, 0.0, 0.0, 0.0,
75+ 0.0, 1.0, 0.0, 0.0,
76+ 0.0, 0.0, 1.0, 0.0,
77+ 0.0, 0.0, 1.0, 0.0);
78
79 mat4 model_to_world_transform =
80 mat4(1.0, 0.0, 0.0, position.x,