60
void main(void)
{
  vec4 clipCoord = glModelViewProjectionmatrix * gl_Vertex;
  gl_Position = clipCoord;

  gl_FrontColor = gl_Color;

  vec3 ndc = clipCoord.xyz / clipCoord.w;

So the clipCoord is just doing standard fixed pipeline transforms. Why do I divide by w, and what do I get from this?

Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
anon
  • 41,035
  • 53
  • 197
  • 293

1 Answers1

67

W is the fourth coordinate of a three dimensional vertex; This vertex is called homogeneous vertex coordinate.

In few words, the W component is a factor which divides the other vector components. When W is 1.0, the homogeneous vertex coordinates are "normalized". To compare two vertices, you should normalize the W value to 1.0.

Think of the vertex (1,1,1,1). Now increase the W value (w > 1.0). The normalized position is scaling! and it is going to the origin. Think of the vertex (1,1,1,1). Now decrease the W value (W < 1.0). The normalized position is going to an infinite point.

Apart from scaling vertex coordinates, the W coordinate is necessary since you have to multiply a 4x4 matrix (the model view and/or the projection matrices) with a 4x1 matrix (the vertex).

Of course, the Red Book is the definite guide:

Red Book Appendix

meetar
  • 7,443
  • 8
  • 42
  • 73
Luca
  • 11,646
  • 11
  • 70
  • 125
  • 14
    why would this avlue ever be not 1 ? – anon Mar 11 '10 at 07:40
  • 7
    @anon: in short, because a projection matrix changes its value. Look at the Appendix Luca is pointing at, at the bottom part. a typical projection does w_out = -z_in. That's why people sometimes call this the "perspective divide". – Bahbar Mar 11 '10 at 08:41
  • 8
    @anon, from [this thread](http://www.opengl.org/discussion_boards/showthread.php/170202-GLSL-Why-is-gl_Vertex-a-vec4) there are two common values, w=1 for a **point**, and w=0 for a **vector**. – Air May 19 '14 at 19:11
  • 5
    A consequence of how homogeneous coordinates work is that, if W is exactly 0, the vector does not behave as a "position" but as a "direction" (think directional light); i.e., it represents all the lines parallel to a given line. – Nicolas Miari Oct 08 '14 at 03:15
  • 34
    I finally understood it when I read in the Red Book that "`homogeneous vertex (x, y, z, w)T corresponds to the three-dimensional point (x/w, y/w, z/w)T`" and that "`the sequence of points (1, 2, 0, 1), (1, 2, 0, 0.01), and (1, 2.0, 0.0, 0.0001), corresponds to the euclidean points (1, 2), (100, 200), and (10000, 20000)`" – user31389 Apr 12 '16 at 11:04
  • i can see how we need the value to be `0` for defining a direction but i don't understand why we need `(10, 10, 10, 2)` where we already have `(5, 5, 5, 1)` and essentially just use the w as a boolean value to indicate if the vector is a point or direction. – toraman Oct 08 '21 at 18:58
  • 3
    @toraman because when you multiply a vec4 with a mat4x4 you get the a vec4, which w component is not 1.0 or a boolean. Indeed you get the actual 3d position by diving by w. See Bahbar comment above. – Luca Oct 08 '21 at 19:33
  • @Luca this makes perfect sense. thank you – toraman Oct 16 '21 at 01:08
  • I wonder why you didn't mention perspective interpolation that uses w comment. – Mehran Oct 19 '22 at 18:55