У меня есть фрагментный шейдер, который обрабатывает 2D-изображение. Иногда пиксель может считаться «недействительным» (значение RGB 0/0/0) для нескольких кадров, в то время как остальные кадры являются допустимыми. Это вызывает временной шум, поскольку эти пиксели мерцают.
Я хотел бы реализовать своего рода временной фильтр, в котором каждый цикл рендеринга, каждый пиксель «показывается» (значение RGB не 0/0/0) тогда и только тогда, когда этот пиксель был «действителен» в последних X циклах, где X может быть 5, 10 и т. д. Я подумал, что если бы у меня был массив того же размера, что и изображение, я мог бы установить элемент, соответствующий пикселю, равным 0, когда этот пиксель недействителен, и увеличить его в противном случае. И если значение >= X, то пиксель может отображаться.
Задержка изображения, вызванная временным фильтром, не является проблемой, но я хочу минимизировать затраты на производительность.
Таков контекст. Я ищу механизм, который позволяет мне читать и писать (поэтому униформа отсутствует) между различными циклами рендеринга одного и того же фрагментного шейдера. Считывание данных из моего приложения OpenGL является плюсом, но не обязательно.
Я наткнулся на Shader Storage Buffer Object, подойдет ли он мне?
Есть ли другие проблемы, о которых я должен знать? Выступления? Когерентность/барьеры памяти?
Точно так же, как предыдущий конвейер обрабатывает это. Я согласен с тем, что нулевое значение RGB кажется допустимым значением, но это карта глубины, и мы не можем получить это значение, если точка не отсутствует. Я предполагаю, что наличие этой информации на другом канале не изменит общий вопрос здесь.
Моей первой мыслью было загрузка/сохранение изображений, которое, держу пари, вы уже используете для обработки изображений. Это имеет смысл, поскольку вы имеете дело с пикселями. Я думаю, что SSBO также может работать, но вам, вероятно, придется вычислять адреса самостоятельно.
похоже, что к каждому пикселю обращается только один «экземпляр» (вызов) шейдера, поэтому проблемы согласованности нет. Проблемы согласованности возникают, когда вы хотите, чтобы несколько экземпляров шейдера обращались к одному и тому же фрагменту данных.
Да, SSBO — это подходящий инструмент для обеспечения постоянной памяти между циклами шейдеров.
Поскольку я не мог найти причину, по которой это не сработает, я реализовал ее, и мне действительно удалось получить SSBO в виде массива, в котором каждый элемент сопоставлен с пикселем, чтобы выполнять временную фильтрацию для каждого пикселя.
Мне пришлось сделать несколько вещей, чтобы не было артефактов на изображении:
GL_DYNAMIC_COPY
при связывании данных с glBufferData
.volatile
в шейдере.memoryBarrierBuffer();
) в моем шейдере, чтобы разделить запись и чтение SSBO.Как упомянул @user253751 в комментарии, мне пришлось преобразовать координаты текстуры в массивы индексов.
Я проверил затраты производительности при использовании SSBO, и в моем случае они были незначительными: <0,1 мс для кадра 848x480.
Есть ли причина, по которой то, является ли пиксель «действительным», является частью цвета, а не информацией о боковом канале (например, альфа)?