<blockquote>
<p>since that is the case for window-space coordinates in the vertex stage.</p>
</blockquote>
<p>There are no &quot;window-space coordinates in the vertex stage&quot;. Or at least, not in the vertex <em>shader</em>.</p>
<p>Window-space is not relative to the viewport; it's relative to the <em>window</em> (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).</p>
<p>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 <code>uniform</code>) or pass NDC coordinates from the vertex shader as an <code>in</code>/<code>out</code> variable pair (just compute <code>gl_Position.xy/gl_Position.w</code>).</p>

CC BY-SA 4.0
2019-05-31T05:33:52.360Z
2020-11-23T16:37:02.947Z
2020-11-23T16:37:02.947Z
Nicol Bolas
<p>I've been scanning the specifications for both OpenGL and GLSL, and I can't find a definitive answer as to <em>how exactly</em> are <code>gl_FragCoord</code>'s <code>x</code> and <code>y</code> components computed, other than they are the </p>

<blockquote>
  <p>fragment’s window-space position</p>
</blockquote>

<p>(<a href="https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf" rel="noreferrer">OpenGL 4.6 specification</a>, page 491)</p>

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

<p>The actual problem I'm trying to solve is rendering a bunch of draws (that depend on <code>gl_FragCoord</code> 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):</p>

<pre class="lang-cpp prettyprint-override"><code>    for (size_t i = 0; i &lt; FrameCount; ++i)
    {
        auto&amp; 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);
    }
</code></pre>

<p><code>BindConstants()</code> simply binds a uniform with the viewport's width &amp; height. When trying to simply output the UVs with the following shader:</p>

<pre><code>#version 330
uniform vec2 Resolution;

void main(void)
{
    vec2 UV = gl_FragCoord.xy / Resolution;
    gl_FragColor = vec4(UV, 0.0, 1.0);
}
</code></pre>

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

<p><a href="https://i.sstatic.net/GIh9o.png" rel="noreferrer"><img src="https://i.sstatic.net/GIh9o.png" alt="enter image description here"></a></p>

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

<p>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.</p>

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

<opengl><fragment-shader>
gl_FragCoord and glViewport
IneQuation
# gl_FragCoord and glViewport

(Asked by: username_0 on 2019-05-30)

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](https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf), 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):

```cpp
    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](https://i.sstatic.net/GIh9o.png)](https://i.sstatic.net/GIh9o.png)

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?**

**Tags:** opengl, fragment-shader


---

## 1 answers

### Answer by username_1 on 2019-05-31. Score: 3

> 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`).


---

