In GLSL, and more specificly in the fragment language, gl_FragCoord is an input variable that contains the window relative coordinate (x, y, z, 1/w) values for the fragment. The detailed description of its contents and how normalized device coordinates (NDC) can be obtained from it are explained in this post.
The first two values (x,y) contain the pixel’s center coordinates where the fragment is being rendered. For instance, with a frame buffer resolution of 800×600, a fragment being rendered in the bottom-left corner would fall over the pixel position (0.5,0.5); a fragment rendered into the most top-right corner would have coordinates (799.5, 599.5). For applications that use multi-sampling these values may fall elsewhere on the pixel area.
The third value (z) is the fragment’s depth mapped in the non-linear range [0,1]. It maps fragment depths from [znear, zfar] to [0,1]. It must be taken into account that converting from this value to eye coordinates by a simple scaling plus bias operation will lead to incorrect eye coordinates due to the fact that it is not a linear mapping. In order to obtain eye coordinates, one must convert from gl_FragCoord to NDC coordinates and then unproject using the inverse projection equations. More explanations on how to do that in the post about pixel position reconstruction.
And the fourth and last value contained in the .w member is (1/w), that is the perspective division resulting from the projection equations.
Fragment position in NDC (Normalized Device Coordinates)
In order to perform the conversion from gl_FragCoord units to NDC, we must convert gl_FragCoord values to the range [0,1] and then compute a simple scale and bias operation to convert them to normalized device coordinates. Depth value in gl_FragCoord already comes in range [0,1], but (x,y) values come in screen pixel coordinates, so we need to divide them by the screen size for normalization.
// Screen size
uniform float screenWidth;
uniform float screenHeight;
// Converting (x,y,z) to range [0,1]
float x = gl_FragCoord.x/screenWidth;
float y = gl_FragCoord.y/screenHeight;
float z = gl_FragCoord.z; // Already in range [0,1]
// Converting from range [0,1] to NDC [-1,1]
float ndcx = x * 2.0 - 1.0;
float ndcy = y * 2.0 - 1.0;
float ndcz = z * 2.0 - 1.0;
vec3 ndc = vec3(ndcx, ndcy, ndcz);