1

I have a shader that I use primarily with an FBO that has two color attachments. In this fragment shader so there are two output buffers.

in vec2 vs_tex_coords;
flat in uint vs_id;

out vec4 fs_color;
out uint fs_id;

uniform sampler2D u_texture;

void main()
{
     fs_color = texture(u_texture, vs_tex_coords)
     fs_id = vs_id;
}

Now, since I'm lazy, I'd like to reuse the same fragment shader also with the default framebuffer. In this case obviously there is only one color attachment (i.e. the screen color buffer). What happens with the second color output? Is it simply ignored or could it cause troubles? Does the standard mention anything about such a case?

I tested that behavior on two devices and it seemed to work fine. It simply ignored the second output buffer. But what can I say about other implementations?

Tarquiscani
  • 649
  • 7
  • 20
  • 3
    "*In this case obviously there is only one color attachment (i.e. the screen color buffer).*" Point of order: default framebuffers have potentially [several color attachments](https://www.khronos.org/opengl/wiki/Default_Framebuffer#Color_buffers) (more when using aux-buffers, but why would you use those these days). Just not user-defined textures/renderbuffers. – Nicol Bolas Jul 18 '19 at 16:07

1 Answers1

4

Now, I'm going to assume that, somewhere in your main OpenGL code, you are assigning those fragment shader output variables to specific output locations. Because if you aren't, then you're already relying on the implementation-defined output location ordering, and that's not reliable.

The following assumes that fs_color is assigned to the output location 0, and fs_id is assigned to the output location 1. Feel free to switch the numbers as appropriate for your needs.

Given that, the question you're asking is really about the framebuffer's draw buffers state. This is the array that specifies which output locations map to which color images in the framebuffer. All framebuffers, default and FBO alike, have this mapping table. But each framebuffer's table is separate.

So, if you didn't make a glDrawBuffers-equivalent call for the default framebuffer to set up the mapping from output locations to framebuffer images, the default is used. By default, the draw buffer state assigns location 0 to write to the GL_BACK buffer (or GL_FRONT if no back buffer exists). The specification is actually a bit underspecified here, as the state of the other locations is not stated. My guess would be that they would be GL_NONE (and thus the FS writes are ignored).

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thank you very much for your crystal-clear answer. Your first two assumptions are correct, sorry for being too concise in the question. And also the last assumption is correct, I don't call `glDrawBuffers` with the default framebuffer. Is it generally dangerous to rely on the default assignment? And if in my case I explicitly set, for the default FBO, the draw buffer location 1 to `GL_NONE` will I resolve any possible problem? – Tarquiscani Jul 18 '19 at 17:10