I've been scanning the specifications for both OpenGL and GLSL, and I can't find a definitive answer as to how exactly are gl_FragCoord's x and y components computed, other than they are the

fragment’s window-space position

(OpenGL 4.6 specification, page 491)

which does not help me understand why glViewport() doesn't seem to affect the values of gl_FragCoord in the fragment stage, since that is the case for window-space coordinates in the vertex stage.

The actual problem I'm trying to solve is rendering a bunch of draws (that depend on gl_FragCoord for their shading) to an atlas, without modifying the shaders of the draws to be aware of the atlas. Here's pseudocode for the driving part (all viewports have identical dimensions, just different offsets):

    for (size_t i = 0; i < FrameCount; ++i)
        auto& Vp = Viewports[i];
        glViewport(Vp.X, Vp.Y, Vp.X + Vp.Width, Vp.Y + Vp.Height);
        BindConstants(Vp.Width, Vp.Height);
        glDrawArrays(GL_TRIANGLES, 0, Triangles);

BindConstants() simply binds a uniform with the viewport's width & height. When trying to simply output the UVs with the following shader:

#version 330
uniform vec2 Resolution;

void main(void)
    vec2 UV = gl_FragCoord.xy / Resolution;
    gl_FragColor = vec4(UV, 0.0, 1.0);

I get the following image, which clearly shows that colour is being clipped to 1.0 beyond the first viewport in a 5x5 atlas:

enter image description here

I've also done additional simple tests that show that gl_FragCoord is based off of the entire frame buffer's origin, rather than what's specified via glViewport().

I have worked around this issue by rendering to a temporary FBO and blitting to the target frame buffer at the desired offset, but it's silly to go to such lengths for a dead-simple use-case like this.

Am I missing something? Is it possible at all without a temporary FBO, and, above all, without modifying the shaders?


1 Answer 1


since that is the case for window-space coordinates in the vertex stage.

There are no "window-space coordinates in the vertex stage". Or at least, not in the vertex shader.

Window-space is not relative to the viewport; it's relative to the window (or framebuffer, in this case). The viewport transform is used to convert from NDC-coordinates (which are relative to the viewport) to window coordinates (which are not).

If you need your fragment shader to have viewport-relative coordinates, then you need to either compute them in the fragment shader (by providing the viewport as a uniform) or pass NDC coordinates from the vertex shader as an in/out variable pair (just compute gl_Position.xy/gl_Position.w).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.