openglshadermultisamplingmouse-picking

How pick geometries in OpenGL with multisample framebuffer?


(Edit) I made working geometry picking with framebuffer. My goal is draw huge scene in one draw call, but I need to draw to multisample color texture attachment (GL_COLOR_ATTACHMENT0) and draw to (eddited) non-multisample picking texture attachment (GL_COLOR_ATTACHMENT1). The problem is if I use multisample texture to pick, picking is corrupted because of multi-sampling.

I write geometry ID to fragment shader like this:

//...

// Given geometry id
uniform int in_object_id;

// Drawed to screen (GL_COLOR_ATTACHMENT0)
out vec4 out_frag_color0;

// Drawed to pick texture (GL_COLOR_ATTACHMENT1)
out vec4 out_frag_color1;

// ...

void main() {

    out_frag_color0 = ...; // Calculating lighting and other stuff

    //...

    const int max_byte1 = 256;
    const int max_byte2 = 65536;
    const float fmax_byte = 255.0;

    int a1 = in_object_id % max_byte1;
    int a2 = (in_object_id / max_byte1) % max_byte1;
    int a3 = (in_object_id / max_byte2) % max_byte1;

    //out_frag_color0 = vec4(a3 / fmax_byte, a2 / fmax_byte, a1 / fmax_byte, 1);
    out_frag_color1 = vec4(a3 / fmax_byte, a2 / fmax_byte, a1 / fmax_byte, 1);
}

(Point of that code is use RGB space for store geometry ID which is then read back a using for changing color of cube)

This happens when I move cursor by one pixel to left:

enter image description here

Because of alpha value of cube pixel:

enter image description here

Without multisample is works well. But multisampling multiplies my output color and geometry id is then corrupted, so it selects random cube with multiplied value.

(Edit) I can't attach one multisample texture target to color0 and non-multisample texture target to color1, it's not supported. How can I do this in one draw call?

enter image description here

Multisampling is not my friend I am not sure If I understand it well (whole framebuffering). Anyway, this way to pick geometries looks horrible for me (I meant calculating ID to color). Am I doing it well? How can I solve multisample problem? Is there better way?

PS: Sorry for low english. :)

Thanks.


Solution

  • You can't do multisampled and non-multisampled rendering in a single draw call.

    As you already found, using two color targets in an FBO, with only one of them being multisampled, is not supported. From the "Framebuffer Completeness" section in the spec:

    The value of RENDERBUFFER_SAMPLES is the same for all attached renderbuffers; the value of TEXTURE_SAMPLES is the same for all attached textures; and, if the attached images are a mix of renderbuffers and textures, the value of RENDERBUFFER_SAMPLES matches the value of TEXTURE_SAMPLES.

    You also can't render to multiple framebuffers at the same time. There is always one single current framebuffer.

    The only reasonable option I can think of is to do picking in a separate pass. Then you can easily switch the framebuffer/attachment to a non-multisampled renderbuffer, and avoid all these issues.

    Using a separate pass for picking seems cleaner to me anyway. This also allows you to use a specialized shader for each case, instead of always producing two outputs even if one of them is mostly unused.