Использование буферов глубины и цвета с разным разрешением (буфер глубины субдискретизации)

Я хочу использовать буфер глубины субдискретизации для увеличения производительности программы. В моем случае не имеет значения, есть ли артефакты или возникнут геометрические ошибки.

Я настроил свой фреймбуфер так:

// Color attachment
glBindTexture(GL_TEXTURE_2D, colorAttachment);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 360, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);

// Depth attachment
glBindRenderbuffer(GL_RENDERBUFFER, depthAttachment);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 160, 90);

// Framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorAttachment, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthAttachment);

Однако сейчас glCheckFramebufferStatus(GL_FRAMEBUFFER) возвращается GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS что означает "Не все прикрепленные изображения имеют одинаковую ширину и высоту" в соответствии с документацией.

Существует исследовательская работа под названием " Полное трехмерное отслеживание кромок с фильтром частиц", в которой описано в разделе 3.5, что они фактически использовали буфер глубины с частичной выборкой для повышения производительности в своем приложении.

Буфер глубины субдискретизации: смежные пиксели вдоль края изображения настолько тесно связаны, что тестирование каждого отдельного краевого пикселя является избыточным. Для трекеров с одной гипотезой обычно разбрасывают точки выборки на расстоянии 10-20 пикселей друг от друга вдоль края. Выборка только каждого пикселя n-го края также уменьшает требуемую полосу пропускания графики, и, таким образом, дискретизируется только каждый 4-й пиксель. Вместо явного рисования пунктирных линий, это здесь достигается путем использования буфера глубины с субдискретизацией (160 × 120), поскольку это дополнительно обеспечивает уменьшение полосы пропускания для очистки и заполнения буфера глубины. Однако это также означает, что удаление скрытой линии может быть неточным примерно до четырех пикселей. Кроме того, на точность системы это не влияет.

Единственные обходные пути, которые очевидны:

  • Использование программы фрагментного шейдера для поиска в ранее обработанном буфере глубины, чтобы применить проверку глубины вручную.
  • Рендеринг буфера глубины в более низком разрешении, затем повторно сэмплируйте это к большему разрешению, затем используйте это как прежде.

Оба подхода не звучат так, как если бы они были наиболее эффективными идеями. Каков самый чистый способ достижения буфера глубины субдискретизации?

1 ответ

Решение

Страница документа, на которую вы ссылались, относится к OpenGL ES 1.0 и 2.0. OpenGL wiki имеет больше информации о разнице между 2.0 и 3.0, а именно, что начиная с 3.0 (и ARB_framebuffer_object), текстуры кадрового буфера могут быть разных размеров. Однако, если я правильно помню, когда у вас есть прикрепленные текстуры разных размеров, фактический используемый размер текстуры является пересечением всех прикрепленных текстур FBO. Я не думаю, что это то, что вы хотите.

Чтобы уменьшить размер вашей текстуры глубины, я предлагаю использовать glBlitFramebuffer для преобразования вашей большой текстуры в меньшую. Эта операция полностью выполняется на GPU, поэтому она очень быстрая. Окончательная текстура меньшего размера может затем использоваться в качестве входных данных для дальнейших операций рендеринга в ваших шейдерах, которые определенно обеспечат экономию полосы пропускания. Вместо того, чтобы выполнять усреднение нескольких значений глубины для каждого выполнения пиксельного шейдера, это будет выполнено один раз на тексель в меньшей текстуре. Меньшая текстура также является более быстрой для выборки, поскольку она лучше помещается в кэш.

Имейте в виду, однако, что усреднение выборок глубины может привести к диким неточностям, поскольку значения глубины не являются линейно распределенными.

Другие вопросы по тегам