Как передать цвет и глубину в мультисэмпловой текстуре?

Чтобы реализовать «отслаивание глубины», я визуализирую свою сцену OpenGL в серии буферов кадра, каждый из которых снабжен цветовой текстурой rgba и текстурой глубины. Это нормально работает, если меня не волнует сглаживание. Если я это сделаю, то, по-видимому, правильнее всего будет включить GL_MULTISAMPLING и использовать GL_TEXTURE_2D_MULTISAMPLE вместо GL_TEXTURE_2D. Но я не понимаю, какие другие вызовы нужно заменить.

В частности, как мне адаптировать мою конструкцию фреймбуфера для использования glTexImage2DMultisample вместо glTexImage2D?

Нужно ли мне изменять вызовы на glFramebufferTexture2D помимо использования GL_TEXTURE_2D_MULTISAMPLE вместо GL_TEXTURE_2D?

Если я передаю в текстуры и цвет, и глубину, нужно ли мне вызывать glRenderbufferStorageMultisample?

Наконец, есть ли что-нибудь glBlit*, что мне нужно сделать в дополнение к настройке текстур для фреймбуфера для рендеринга?

Есть много связанных вопросов по этой теме, но ни одно из найденных мной решений, похоже, не указывает на каноническое руководство или четкий пример, объединяющий все это вместе.


person Alec Jacobson    schedule 24.05.2015    source источник
comment
Я думаю, что обычно, если вы делаете такие вещи, как очистка глубины или отложенное затенение и рендеринг в FBO, мультисэмплинг AA не подходит. Я могу ошибаться, поэтому не хочу отправлять формальный ответ, но я думаю, что в целом, если вы идете по этим типам маршрутов, общим решением является применение AA на основе изображений / пикселей, таких как FXAA, MLAA или SMAA, как ручная пост-обработка. В последнее время это становится очень распространенным явлением в играх, и я думаю, это потому, что они необходимы в результате использования таких методов, которые включают рендеринг в закадровые текстуры.   -  person    schedule 25.05.2015
comment
Что касается рендеринга того, что вы рисовали за кадром, для этой цели существует функция glBlitFramebuffer, но вы можете получить гораздо больше гибкости, просто настроив ортопроекцию и определив матрицу MV и визуализируя текстурированные четырехугольники с использованием текстуры (ов) прикрепления цвета FBO. Это позволит вам затем обработать результаты во фрагментном шейдере и выполнить пост-обработку, такую ​​как AA или отложенное затенение.   -  person    schedule 25.05.2015
comment
Спасибо, Айк. Я пробовал просто рендерить в гораздо больший буфер и понижать дискретизацию со сглаживанием, но такие вещи, как резкие линии толщиной 1 пиксель, не получаются так легко и красиво, как правильная мультисэмплинг на экране. Не говоря уже о том, что это было довольно медленно.   -  person Alec Jacobson    schedule 25.05.2015
comment
В зависимости от ваших требований к качеству / скорости / усилию существует целый ряд алгоритмов AA на основе изображений, которые могут работать в шейдере, в том числе те, которые не требуют дополнительной видеопамяти (нет необходимости выполнять рендеринг в больший буфер, чем обычно). В этой статье показан, например, метод FXAA и его внешний вид: geforce.com/whats-new/articles/   -  person    schedule 25.05.2015
comment
Это также может иметь некоторую актуальность - здесь обсуждается, как использовать мультисэмплинг вне экрана: Learnopengl .com / #! Advanced-OpenGL / Anti-Aliasing. Он показывает, как построить FBO с множественной выборкой. Стоит отметить, как в статье упоминается glBlitFramebuffer для разрешения изображения из мультисэмпловой цели и как мы можем получить доступ к текселям из мультисэмплированной текстуры, используя sampler2DMS во фрагментном шейдере. Я не совсем понимаю, можно ли иметь один мультисэмпловый FBO, который одновременно будет содержать как глубину, так и цвет. Нам там может понадобиться два прохода.   -  person    schedule 25.05.2015


Ответы (1)


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

Нужно ли мне изменять вызовы на glFramebufferTexture2D помимо использования GL_TEXTURE_2D_MULTISAMPLE вместо GL_TEXTURE_2D?

Нет, это все, что тебе нужно. Вы создаете текстуру с помощью glTexImage2DMultisample(), а затем присоединяете ее, используя GL_TEXTURE_2D_MULTISAMPLE в качестве третьего аргумента к glFramebufferTexture2D(). Единственное ограничение - уровень (5-й аргумент) должен быть 0.

Если я передаю в текстуры и цвет, и глубину, нужно ли мне вызывать glRenderbufferStorageMultisample?

да. Если вы присоединяете буфер глубины к тому же самому FBO, вам необходимо использовать мультисэмплированный буфер рендеринга с тем же количеством отсчетов, что и цветовой буфер. Таким образом, вы создаете свой буфер рендеринга глубины с помощью glRenderbufferStorageMultisample(), передавая тот же счетчик выборок, который вы использовали для буфера цвета.

Наконец, есть ли что-нибудь glBlit*, что мне нужно сделать в дополнение к настройке текстур для фреймбуфера для рендеринга?

Не для рендеринга во фреймбуфер. Когда вы закончите рендеринг, у вас есть несколько вариантов:

  1. Вы можете уменьшить (разрешить) мультисэмплерную текстуру до обычной текстуры, а затем использовать обычную текстуру для последующего рендеринга. Для разрешения мультисэмпловой текстуры вы можете использовать glBlitFramebuffer(), где мультисэмпловая текстура прикреплена к GL_READ_FRAMEBUFFER, а обычная текстура - к GL_DRAW_FRAMEBUFFER.

  2. Вы можете использовать мультисэмплерную текстуру для последующего рендеринга. Вам нужно будет использовать тип sampler2DMS для семплеров в вашем коде шейдера с соответствующими функциями семплирования.

Для варианта 1 я не вижу веских причин для использования мультисэмпловой текстуры. С таким же успехом вы можете использовать мультисэмплерный буфер рендеринга, который немного проще в использовании и должен быть не менее эффективным. Для этого вы создаете буфер рендеринга для прикрепления цвета и назначаете ему glRenderbufferStorageMultisample(), что очень похоже на то, что вам нужно для буфера глубины.

person Reto Koradi    schedule 25.05.2015
comment
Спасибо, Рето. Мне не хватало sampler2DMS в моих попытках. Я попробую это. - person Alec Jacobson; 26.05.2015