Here are my settings for opengl, incase they matter:
glViewport(0,0,w,h); //w=800, h=600
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
For a while I thought that the clipping planes will apply to anything for which gl_Position.z is outside -1 to 1. But even when I force gl_Position.z to a constant number in the shader:
gl_Position.z = -0.01;
There is still correct z-buffering and clipping based on gl_Position.w! So what are the rules?
The value of gl_Position is in what OpenGL calls "clip space". It is a homogeneous coordinate system. In particular, the XYZ extents of clip space are [-W, +W]. So each vertex is in its own clip space.
I'm not sure exactly what you mean by "what are the rules." The clip-space gl_Position is clipped against the view area in homogeneous space. So they are clipped to the [-W, +W] region for each vertex. It's hard to imagine that in a projective homogeneous space, but the math works out, so it doesn't matter.
After that, the clipped vertices are transformed to normalized device coordinate (NDC) space. This means dividing the XYZ of the clip space by W. All of these vertices are in the range [-1, 1].
From there, the viewport transform happens. The glViewport
parameters scale the vertices from the [-1, 1] NDC space to the viewport region. This transforms points to window space; it is in window space that they are rasterized.
The XY of window space is controlled by glViewport
. The Z values for window space are controlled by glDepthRange
. The default depth range is a near value of 0 and far value of 1 (WARNING: the perspective matrix near/far planes have nothing in common with the depth range. Do not confuse the two). So it maps the [-1, 1] of the Z in NDC space to [near, far] in window space.
Those are "the rules."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With