Following this resource for cubemap, it uses a trick for always having the cubemap at z=1 with gl_Position = pos.xyww. With perspective division, each pixel will have its depth set to w / w = 1. I have some questions regarding this.
void main()
{
vec4 pos = projection * view * vec4(aPos, 1.0);
gl_Position = pos.xyww;
}
- What I don’t understand is regarding depth fighting. There are always 2 possibles pixels rendered at the same position for a cubemap, one behind us and one in front of us, because we are basically projecting the cube into a parallelepiped. With this, every pixel is set to
z=1. So for a given(x, y)position, there are two possible candidates with the same depth. So with this method, we don’t know which pixel is in front and which is behind us. So aren’t we supposed to see depth fighting with that, are at least an undefined value for the pixel? This could cause problems if the texture is different between each face of the cube.
And some auxiliary questions:
-
Can we replace
gl_Position = pos.xywwbygl_Position = vec4(pos.xy / pos.w, 1.0, 1.0)to achieve the same effect? -
Furthermore, is it guaranteed that
w / w = 1for anywwith the floating precision? If it will be set to something like1.000000001then the cubemap will never be shown withGL_EQUAL(I know we can still useGL_LEQUAL).
>Solution :
Clipping is done in clip space not in normalized device space. The clipping rule is -w < x, y, z < w. If w is < 0, this rule is not fulfilled. So clip coordinates with w < 0 are clipped. In perspective projection, the clip positions "behind" the camera have a negative w component. The perspective division is part of the render pipeline. You can trust that z/w is 1 when w==z.
You cannot do the perspective division in the vertex shader, because perspective divide converts from clip space to normalized device space. As a result, clipping no longer works, since -1 < z/w < 1 is also satisfied when w < 0 and z == w.