The gl_FragCoord variable stores four components: (x, y, z, 1/w)
What is the w coordinate and why is it stored as 1/w?
A homogeneous coordinate is given by: (x, y, z, w), which projects to: (x/w, y/w, z/w). gl_FragCoord
stores this projection, but rather than storing the (useless) (w/w) = (1) for the last component, it stores (1/w), to preserve useful information.
The GLSL and OpenGL specifications are needlessly confusing in this regard. The OpenGL spec is easier to understand: gl_FragCoord
stores the X, Y, and Z components of the window-space vertex position. The X, Y, and Z values are calculated as described for computing the window-space position (though the pixel-center and upper-left origin can modify the X and Y values). This is described in the Coordinate Transforms
section of the spec.
The W component of gl_FragCoord
is (1 / Wc), where Wc is the clip-space vertex position. It's gl_Position.w
from your vertex shader.
The only useful purpose for keeping Wc around is to reverse-transform gl_FragCoord to get the clip-space position back. Which, as that page shows, requires multiplying by Wc. But since gl_FragCoord
only stores the inverse of this value, it now requires dividing by gl_FragCoord.w
.
Therefore, we can assume that OpenGL stores it this way because OpenGL isn't allowed to make too much sense ;) See, it's a rule that every part of the OpenGL specification must have something that's a bit nonsensical. The XYZ components made too much sense, so they decided to have it stores the inverse of the value you actually want.
OK, technically this is a historical artifact from the days when 3D Labs created GLSL. I'm sure they did it for purely selfish hardware reasons, but I have no real proof of that.