title: Best way to sample a fullscreen texture
body: <p>What is the best way to sample fullscreen textures in a fragment shader, so for example the g-buffer in a deferred renderer, or the scene texture within a postprocess shader?</p>
  
  <p>At the moment I use the following two ways:</p>
  
  <ul>
  <li><p>Pass the screen size to the shader as a uniform and calculate (u,v) from <code>gl_FragCoord</code>:</p>
  
  <pre><code>vec2 texCoord = gl_FragCoord.xy / vScreenSize;
  vec3 c = texture( tex, texCoord ).rgb;
  </code></pre>
  
  <p>Does not seem to be ideal since a division is required and supplying the shader with the screen size is cumbersome.</p></li>
  <li><p>Convert <code>gl_FragCoord.xy</code> into an <code>ivec</code> and use <code>texelFetch</code>:</p>
  
  <pre><code>vec3 c = texelFetch( tex, ivec2(gl_FragCoord.xy), 0 ).rgb;
  </code></pre>
  
  <p>Also not ideal because the conversion from <code>float</code> to <code>int</code> is required.</p></li>
  </ul>
  
  <p>So is there a better way? I really just want to sample a buffer at the exact point where my pixel shader is drawing.</p>
  
  <hr>
  
  <p>// EDIT:</p>
  
  <hr>
  
  <p>Ok, with the suggestions of interpolated texture-coordinates that come from the vertex shader I managed to figure out the following code:</p>
  
  <p>Vertex shader:</p>
  
  <pre><code>#version 150
  
  uniform mat4 im_ModelViewProjectionMatrix;
  
  in vec3 iv_Vertex;
  noperspective out vec2 vVertCoord;
  
  void main( void )
  {
      gl_Position = im_ModelViewProjectionMatrix * vec4(iv_Vertex, 1.0);
      vVertCoord = (gl_Position.xy / gl_Position.w) * (0.5) + vec2(0.5);
  }
  </code></pre>
  
  <p>I basically calculate normalized device coordinates (NDC) from the clip space position with the perspective division and then map the NDCs (that range from [-1,1]) into the interval [0,1]. This works great for fullscreen quads (even without the perspective division because coordinates are so simple). The arbitrary geometry I need to draw as light-geometry in my deferred renderer has some problems though. In the vertex shader I output <code>vVertCoord</code> as a color for red=x and green=y:</p>
  
  <pre><code>#version 150
  
  noperspective in vec2 vVertCoord;
  out vec4 colorOut;
  
  void main( void )
  {
      colorOut = vec4(vVertCoord.x, vVertCoord.y, 0, 1);
  }
  </code></pre>
  
  <p>This is the result when I am inside a point-light-sphere, everything looks fine (the black lines are rendered on purpose):</p>
  
  <p><img src="https://i.stack.imgur.com/uDMcK.png" alt="All fine"></p>
  
  <p>However, if I move closer to the light-geometry this is the result:</p>
  
  <p><img src="https://i.stack.imgur.com/raeHg.png" alt="Not ok"></p>
  
  <p>What is that red patch in the top left corner doing there? You don't want to see the results in real-color with the debugging colors disabled because it looks like an lsd-trip, everything warps around when you move the camera. Is this precision related? Note that all is fine when I use gl_FragCoord in the pixel shader instead.</p>