I'm having trouble understanding the behaviour of my OpenGL program; and in drawing my Z-Buffer out to the screen.
It will probably be best to just start with code, here is my GLSL shader:
in vec3 vVertex;
smooth out vec4 vSmoothColor;
vec4 vPosition;
uniform mat4 MVP;
void main() {
vPosition = MVP * vec4(vVertex, 1);
float z = abs(vPosition.z);
vSmoothColor = vec4(z, z, z, 1);
gl_Position = vPosition;
}
My assumption was thus, after reading completely through the OpenGL SuperBible (blue book) and several other resources; I was under the impression the vPosition.z above should be mapped to [-1, 1]; which is then clamped to [0, 1] by the driver (assumedly).
My results were different, I expected; while using vSmoothColor as my output color; and a box moving along the Z axis from 1.f to 100.f, and the perspective matrix set up with a near and far of 1.f and 100.f, that my colors should have corresponded to the following (assuming Z mapped to [0, 1]):
Z Coord. vSmoothColor
10 0.1, 0.1, 0.1, 1
20 0.2, 0.2, 0.2, 1
...
80 0.8, 0.8, 0.8, 1
Instead, my color values (ie my clipspace coordinate "vPosition.z") corresponded to almost exactly the world space Z coordinate value:
Z Coord. vSmoothColor
10 10, 10, 10, 1
20 20, 20, 20, 1
...
80 80, 80, 80, 1
If that is the result in vPosition.z (ie the clipspace Z), how does the driver clamp the depth values for representation?
Although its been verified as correct against other implementations, here is my perspective matrix creation code:
inline Matrix4 perspective(float fovy, float aspect, float n, float f) {
const float t = n * tanf(radians(fovy / 2));
const float r = t * aspect;
const float d = f - n;
return Matrix4(
n / r, 0, 0, 0,
0, n / t, 0, 0,
0, 0, -(f + n) / d, -1,
0, 0, -(f * n * 2) / d, 0
);
}