Можно ли прочитать один образец из MSAA FBO? - PullRequest
0 голосов
/ 15 декабря 2018

Использование OpenGL для рисования объектов, а также мой фрагментный шейдер, выводящий скалярный целочисленный идентификатор.Для рисования объектов я использую множественную выборку для сглаживания, поэтому, когда я создаю буфер для целочисленного идентификатора, я должен создать его как буфер MSAA, чтобы FBO было завершено:

  glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_RGBA8,
                        cam.getWidth(), cam.getHeight());
  glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_DEPTH_COMPONENT,
                        cam.getWidth(), cam.getHeight());
  glBindRenderbuffer(GL_RENDERBUFFER, rboObjId);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_R32UI,
                        cam.getWidth(), cam.getHeight());
  glBindRenderbuffer(GL_RENDERBUFFER, rboColorNoMsaaId);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
                        cam.getWidth(), cam.getHeight());
  glBindRenderbuffer(GL_RENDERBUFFER, rboObjNoMsaaId);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_R32UI,
                        cam.getWidth(), cam.getHeight());

  glBindRenderbuffer(GL_RENDERBUFFER, 0);
  glBindFramebuffer(GL_FRAMEBUFFER, fboId);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_RENDERBUFFER, rboDepthId);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rboObjId);
  glBindFramebuffer(GL_FRAMEBUFFER, fboNoMsaaId);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorNoMsaaId);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rboObjNoMsaaId);

Как видно из кода выше, у меня есть 2 FBO.Первый - это MSAA, в котором есть буфер для рисования сцены, буфер глубины и целочисленный буфер для идентификаторов.Второе FBO с одиночной выборкой (не MSAA) и имеет только буфер сцены рисования и буфер целых чисел.После того, как я нарисовал все (фрагментный шейдер устанавливает значения для каждого пикселя), я считал буфер целочисленного идентификатора (GL_COLOR_ATTACHMENT1), сначала перетащив его в одиночный FBO выборки, чтобы я мог получить из него glReadPixels.В этом конкретном коде я просто читаю 1 пиксель, на который указывает мышь:

  glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
  glReadBuffer(GL_COLOR_ATTACHMENT1);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboNoMsaaId);
  glDrawBuffer(GL_COLOR_ATTACHMENT1);
  glBlitFramebuffer(mouse_x_pos, cam.getHeight() - mouse_y_pos, mouse_x_pos+1, cam.getHeight() - mouse_y_pos + 1,
                    0, 0, 1, 1,
                    GL_COLOR_BUFFER_BIT, GL_NEAREST);
  glBindFramebuffer(GL_READ_FRAMEBUFFER, fboNoMsaaId);
  glReadBuffer(GL_COLOR_ATTACHMENT1);
  GLuint objectId;
  glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &objectId);

Моя проблема в том, что когда я блею, мультисэмплы для нужного мне пикселя интерполируются в единыйПиксель я могу прочитать.Я хочу это для цветового буфера, который я использую для рисования сцены, но я не хочу этого для целочисленных идентификаторов, которые я читаю.Если я читаю пиксель, содержащий фрагменты как для идентификатора 50, так и для идентификатора 100, я хочу прочитать либо 50, либо 100 (все равно, какие).Но я получаю какое-то значение от 50 до 100, например, 75. 75 может на самом деле быть совершенно другим пикселем, поэтому я не хочу этого вообще.

Есть ли что-то, что я могу сделать, чтобы прочитать одинвыборка для целочисленного идентификатора вместо интерполяции нескольких выборок?

1 Ответ

0 голосов
/ 15 декабря 2018

Вместо разрешения текстуры мультисэмпла путем блиттинга вы можете реализовать собственное разрешение мультисэмпла на этапе рендеринга в текстуру.Вы можете использовать сэмплер типа sampler2DMS и использовать это texelFetch( variant:

gvec4 texelFetch( gsampler2DMS sampler, ivec2 P, int sample);

, поэтому P являются 2D ненормализованными текселевыми координатами,sample - идентификатор образца.Если вы действительно не заботитесь о том, какое из значений вы получаете, вы можете просто использовать образец 0 все время.Но вы также можете, например, перебрать все сэмплы и взять тот, который встречается чаще всего, или любой другой, который соответствует вашим потребностям.

Чтобы это работало, вам придется переключиться с рендеринга буфера для прикрепления идентификатора к2D-текстура с несколькими выборками.

Таким образом, вы можете связать FBO без мультисэмплинга, как FBO рисования, сделать стандартный блик для текстур глубины и цвета, а также выполнить полноэкранный рендеринг с текстурой ID с мультисэмплом, записав вцветное вложение немодсэмплированного идентификатора.

...