Плавно обратимое аддитивное/вычитающее смешение яркости в OpenGL

StackOverflow https://stackoverflow.com//questions/24018479

Вопрос

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

Например, это может быть простая шахматная доска поверх другого изображения:

enter image description here

Я хочу, чтобы текстура линейно увеличивала/уменьшала яркость фона в соответствии с:

(R_b + R_t * w, G_b + G_t * w, B_b + B_t * w, 1.0)

где *_b — значения фоновых пикселей (от 0 до 1), *_t — это значения пикселей со знаком для наложенной текстуры (между -1 и 1) и w — это весовой параметр, который также может варьироваться от -1 до 1.Цель состоит в том, чтобы, изменяя знак и величину w Я могу плавно изменять величину и полярность модуляции фона текстурой шахматной доски.

Чтобы дать вам графический пример:

enter image description here

С использованием glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) и простое изменение значения альфа моего наложения не даст того, что я хочу, потому что я не могу использовать отрицательные значения альфа для инвертирования полярности моего наложения.

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

Обновлять

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

Обновление 2

Чтобы быть совершенно ясным, если w > 0, Я хочу увеличивать яркость каждого пикселя внутри белый квадраты на моей шахматной доске, и снижаться яркость каждого пикселя внутри черный квадрат.Если w < 0 Я хочу сделать наоборот.

ДерхассОтвет очень близок к тому, что я ищу, но влияет только на пиксели в белых квадратах, а не на черные квадраты:

enter image description here

Люди плохо умеют оценивать абсолютную яркость, но разница будет заметнее, если я установлю красный цвет наложения (glColor4f(1., 0., 0., 0.25)):

enter image description here

Как видите, это приводит к добавлению/вычитанию красного цвета из белых квадратов, но не меняет черные квадраты.

Это было полезно?

Решение

Я думаю, вы можете использовать смешивание GL, если у вас есть w Параметр не будет меняться для каждого пикселя, а является глобальным для всего вызова отрисовки наложенной текстуры (как также предполагают ваши изображения).Вам просто нужно составить уравнение смеси в зависимости от знака w:

Установите коэффициенты смешивания на glBlendFunc(GL_SRC_ALPHA,GL_ONE), и

  • Для w>=0:использовать glBlendEquation(GL_FUNC_ADD) и установите альфу на w

  • Для w<0:использовать glBlendEquation(GL_FUNC_REVERSE_SUBTRACT) и установите альфу в -w

Как описано выше, это также изменит альфа-компонент вывода, но вы хотите, чтобы он был равен 1.0.Как вы сказали, ваш фреймбеффер уже имеет альфу = 1, когда вы визуализируете фон.Итак, вы можете просто использовать glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE,GL_ZERO,GL_ONE) что в сочетании с приведенными выше уравнениями установит результирующую альфу равным альфе пункта назначения, A_b в ваших обозначениях.

ОБНОВЛЯТЬ

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

Однако можно использовать отрицательные значения альфа, если плавающая запятая используется цветовой буфер (ARB_color_buffer_float).

Если цветовой буфер является фиксированной точкой, компоненты значений источника и назначения и коэффициентов смеси зажимаются до [0;1] или [-1;1] Соответственно для нормированного или подписанного нормализованного цветового буфера до оценки уравнения смеси.Если цветовой буфер находится с плавающей точкой, зажима не происходит.Получившиеся четыре значения отправляются в следующую операцию.

Обратите внимание, что это расширение вводит glClampColor() функционируют и определяют цели GL_CLAMP_READ_COLOR, GL_CLAMP_VERTEX_COLOR и GL_CLAMP_FRAGMENT_COLOR.Последние два устарели в современном GL и актуальны только для устаревшего конвейера фиксированных функций.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top