Transform vertex to world coordinates

Description

The default coordinate space in OpenGL is -1.0 to 1.0 for all axes. Anything outside of this range won't be rendered. This is called the clip space.

However, specifying positions within this cube can be tedious. It would be preferable if we could use our own coordinate space. For example, if our world is 8.0 kilometers long on each side, we may want to specify positions between 0.0 and 8.0 on each axis. We'll call this the world space.

Transforming positions from the world space to clip space is something we can do in our vertex shader. For example, if we specify a vertex positioned at (6.0, 4.0, 2.0) in our world, the vertex shader can transform it to (0.5, 0.0, -0.5) in clip space automatically.

We can do this transform by multiplying our position vectors by a transformation matrix. To transform positions on each axis from the (0.0, 8.0) range to the (-1.0, 1.0) range, we can use an orthographic projection.

Converting between coordinate spaces is something we'll use often and much has been written about it. The Multiple Coordinates Spaces chapter in the game math book is a good read, as is this Learn OpenGL section.

Screenshot

Commands

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

Code Changes

Modified shaders/cube.vertGitHub

@@ -1,5 +1,15 @@
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;
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+
313 void main() {
414 vec3 near_bottom_left = vec3(0.0, 0.0, 0.0);
515 vec3 near_bottom_right = vec3(1.0, 0.0, 0.0);
@@ -65,5 +75,11 @@
6575 vertices[34] = near_bottom_left;
6676 vertices[35] = far_bottom_left;
6777
68- gl_Position = vec4(vertices[gl_VertexID], 1.0);
78+ mat4 world_to_clip_transform =
79+ mat4(2.0 / WIDTH, 0.0, 0.0, -(RIGHT + LEFT) / WIDTH,
80+ 0.0, 2.0 / HEIGHT, 0.0, -(TOP + BOTTOM) / HEIGHT,
81+ 0.0, 0.0, 2.0 / DEPTH, -(FAR + NEAR) / DEPTH,
82+ 0.0, 0.0, 0.0, 1.0);
83+
84+ gl_Position = vec4(vertices[gl_VertexID], 1.0) * world_to_clip_transform;
6985 }
@@ -1,5 +1,15 @@
1 #version 150
2
 
 
 
 
 
 
 
 
 
 
3 void main() {
4 vec3 near_bottom_left = vec3(0.0, 0.0, 0.0);
5 vec3 near_bottom_right = vec3(1.0, 0.0, 0.0);
@@ -65,5 +75,11 @@
65 vertices[34] = near_bottom_left;
66 vertices[35] = far_bottom_left;
67
68- gl_Position = vec4(vertices[gl_VertexID], 1.0);
 
 
 
 
 
 
69 }
@@ -1,5 +1,15 @@
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 void main() {
14 vec3 near_bottom_left = vec3(0.0, 0.0, 0.0);
15 vec3 near_bottom_right = vec3(1.0, 0.0, 0.0);
@@ -65,5 +75,11 @@
75 vertices[34] = near_bottom_left;
76 vertices[35] = far_bottom_left;
77
78+ mat4 world_to_clip_transform =
79+ mat4(2.0 / WIDTH, 0.0, 0.0, -(RIGHT + LEFT) / WIDTH,
80+ 0.0, 2.0 / HEIGHT, 0.0, -(TOP + BOTTOM) / HEIGHT,
81+ 0.0, 0.0, 2.0 / DEPTH, -(FAR + NEAR) / DEPTH,
82+ 0.0, 0.0, 0.0, 1.0);
83+
84+ gl_Position = vec4(vertices[gl_VertexID], 1.0) * world_to_clip_transform;
85 }