Копирование FBO без мультисэмплирования в мультисэмплированный

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

До сих пор мы выполняли рендеринг непосредственно в основной FBO, который был FBO с множественной выборкой, созданным с использованием EGL_SAMPLES = 8.

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

Вникнув в это, я обнаружил, что мне пришлось реализовать систему с мультисэмплированным FBO, а также текстурированным без мультисэмплирования FBO, в котором мне пришлось разрешить мультисэмплированный FBO. Затем просто перенесите разрешенное в основной FBO.

Все это работает, но проблема в том, что при использовании вышеупомянутой системы и основного FBO без мультидискретизации (EGL_SAMPLES = 0) я получаю довольно большое падение частоты кадров по сравнению с частотой кадров, которую я получаю, когда использую только основной FBO с EGL_SAMPLES = 8.

Углубившись в это, я обнаружил, что люди пишут в Интернете, а также размещают здесь сообщение https://community.arm.com/thread/6925, в котором говорится, что самый быстрый подход к мультисэмплингу - использовать EGL_SAMPLES. И действительно, именно так это выглядит и на jetson tk1, который является нашей целевой платой.

Что, наконец, подводит меня к вопросу и приношу свои извинения за длинное вступление:

Есть ли способ спроектировать это так, чтобы использовать внеэкранный fbo без множественной выборки для всего рендеринга, который в конечном итоге переносится в основной мультисэмплированный FBO, который использует EGL_SAMPLES?


person Boofish    schedule 03.12.2016    source источник
comment
Этот последний абзац полностью перевернут. Вы не начинаете с растеризации одной выборки на пиксель, а затем копируете ее в буфер кадра с множественной выборкой. Вы хотите пойти в другом направлении и преобразовать мультисэмплированный буфер в один сэмпл, иначе вы просто тратите VRAM.   -  person Andon M. Coleman    schedule 04.12.2016


Ответы (2)


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

Применение MSAA в конце конвейера в финальном блит-коде не даст никаких преимуществ и, вероятно, не бесплатно (оно будет почти бесплатным для модулей рендеринга на основе плиток, таких как IMG Series 6 и Mali (блог, на который вы ссылаетесь), менее бесплатным на рендерах в немедленном режиме, таких как Nvidia на вашей плате Jetson).

Примечание для сглаживания за пределами экрана "стандартный" подход - это рендеринг в буфер кадра MSAA, а затем разрешение в качестве второго прохода (например, использование glBlitFramebuffer для преобразования в один буфер выборки). Этот отскок неэффективен на многих архитектурах, поэтому существует это расширение, чтобы помочь:

Фактически это обеспечивает такое же неявное разрешение, что и функциональность оконной поверхности EGL.

Ответы на ваши вопросы в комментариях.

Является ли в этом случае результирующая текстура мультисэмплированной текстурой?

С точки зрения приложения нет. Данные с множественной выборкой находятся внутри неявно выделенного буфера, выделенного драйвером. См. Этот фрагмент спецификации:

«Реализация выделяет неявный буфер мультисэмплов с выборками TEXTURE_SAMPLES_EXT и тем же внутренним форматом, шириной и высотой, что и указанный уровень текстуры».

Для этого может потребоваться реальное выделение буфера MSAA в основной памяти на некоторых архитектурах графического процессора (и поэтому он будет не быстрее, чем ручной glBlitFramebuffer подход без расширения), но, как известно, он эффективно бесплатен для других (например, плитка на основе графических процессоров, где неявный «буфер» - это небольшая оперативная память внутри графического процессора, а не в основной памяти вообще).

Цель состоит в том, чтобы размыть фон за виджетами.

MSAA ни в коем случае не является размытием общего назначения - он только сглаживает пиксели, совпадающие с краями треугольников. Если вы хотите размыть треугольные грани, вам лучше просто использовать разделяемое размытие по Гауссу, реализованное как пара фрагментных шейдеров, и реализовать его как проход постобработки 2D.

person solidpixel    schedule 05.12.2016
comment
Да, решение, которое я пробовал, было тем, что вы здесь описываете. Выполните рендеринг в внеэкранный MSAA FBO (с буфером рендеринга с множественной выборкой, а не с текстурой, как мы на GL ES3 или ниже), затем разрешите одиночный выборочный FBO с текстурой, а затем используйте glBlitFrameBuffer, чтобы преобразовать его в основной FBO. Это медленно. Особенно в разрешении 1920х1080. Но это расширение, о котором вы говорите, звучит интересно. Является ли в этом случае результирующая текстура мультисэмплированной текстурой? Лучшим решением для нас было бы иметь возможность каким-то образом иметь 2-мерную текстуру сцены, к которой мы можем получить доступ в любое время. Цель состоит в том, чтобы размыть фон за виджетами. - person Boofish; 05.12.2016
comment
Спасибо за Ваш ответ. На самом деле под размытием я имел в виду то, что я хотел бы скопировать часть того, что уже было нарисовано, и перерисовать его размытым, пока я все еще нахожусь в цикле рендеринга. Вот почему я пытаюсь выполнить рендеринг на текстуру. Проблема в том, что я использую MSAA для сглаживания, что усложняет этап рендеринга в текстуру. Я упомянул размытие, чтобы обозначить цель этого испытания, если вы знаете какие-либо более простые способы ее достижения. У меня уже есть однопроходный шейдер размытия по Гауссу, который работает хорошо. Просто нужно иметь возможность попробовать то, что уже есть в моем MSAA FBO. - person Boofish; 06.12.2016

Есть ли способ спроектировать это для использования внеэкранного fbo без множественной выборки для всего рендеринга, который в конечном итоге переносится на основной мультисэмплированный FBO, который использует EGL_SAMPLES?

Ни в коем случае, что действительно полезно.

Блиттинг кадрового буфера разрешает блит из буферов с одиночной выборкой в ​​буферы с множественной выборкой. Но все, что это делает, - это присваивать каждому образцу в пикселе то же значение, что и исходному.

Блиттинг не может генерировать новую информацию. Так что реального сглаживания вы не получите. Все, что вы получите, - это те же данные, которые будут храниться гораздо менее эффективно.

person Nicol Bolas    schedule 04.12.2016