title: In modern OpenGL, how do I avoid overwriting data in FBO colour attachments with invalid fragments?
body: <p>I have a batched rendering pipeline that uploads a bunch of quads to OpenGL. These are rendered to an FBO. Naturally, one of the attachments is visual output and another is depth, allowing for post-processing etc. However, a third attachment is intended for storing object IDs for picking, in a similar style to that explained <a href="http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html" rel="nofollow noreferrer">here</a>.</p>
  <p>There's a small catch. I would like some rendered items to be 'transparent' to picking. Essentially, some things (particles or visual decoration or whatever) are not pickable themselves, but should not prevent the picking of objects behind them.</p>
  <p>How might this be accomplished? Web searches suggest that <code>glAlphaFunc</code> might once have fulfilled this role, as I could have packed the object id into a texture with a transparency channel, and then deleted any fragments which I set the transparency to 0. A bit fiddly, but workable. However, that's been depreciated.</p>
  <p>The other common recommendation for similar problems is to use the <code>discard</code> keyword. This isn't workable because it deletes all output elements of the fragment, not just for a specified attachment.</p>
  <p>What's the solution here? Is there something clever I can do with blend functions that I just can't see? I'm pretty flummoxed.</p>
  <hr />
  <p><em>Fragment shader looks something like this:</em></p>
  <pre><code>#region Fragment
  
  #version 440 core
  
  layout(location = 0) out vec4 colour; // Visual
  layout(location = 1) out uint interactLayer; // Picking
  
  in vec2 texCoord;
  in flat int texUnit;
  in flat uint objectID;
  
  uniform sampler2D[32] u_texData;
  
  void main()
  {
      vec4 c1 = fragmentColour * texture(u_texData[texUnit], texCoord);
      
      if (c1.w == 0.0f) { discard; }
      colour = c1;
      
      if (objectID == 0xffffffffu) {
          // Please don't write to interactLayer values,
          // but also please don't discard the 'colour' value.
      }
      else {
          interactLayer = objectID;
      }
  }
  </code></pre>