2013-04-30 5 views
2

Я пишу пользовательский интерфейс на основе PyOpenGL для ручного выравнивания изображений. Я показываю свои два изображения как текстурированные квадрациклы, движущиеся изображения поверх статической ссылки. Движущееся изображение показано красным цветом с изменяющейся альфа, то есть glColor4f(1.,0.,0.,overlay_opacity), а статическое изображение показано голубым цветом с постоянной непрозрачностью, равной одной, то есть glColor4f(0.,1.,1.,1.). Затем пользователь может изменять overlay_opacity с помощью прокрутки мыши, чтобы исчезать между движущимися и опорными изображениями.opengl: смешанное смешивание нелинейных добавок

На данный момент я пользуюсь glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA). Хотя это позволяет мне плавно переходить между голубыми и красными изображениями, это также означает, что когда overlay_opacity равно 0,5, я получаю только половину максимальной интенсивности красных и голубых изображений, поэтому результат выглядит тусклым и грязным. Если я использую glBlendFunc(GL_SRC_ALPHA,GL_ONE), я всегда получаю максимальную интенсивность для моего голубого изображения, поэтому я не могу его погасить. То, что я действительно хочу, это какое-то нелинейное смешивание, которое выглядит как третий график ниже:

enter image description here

Я предполагаю, что я мог бы, возможно, сделать это в пиксельный шейдер, но кажется, что там должно быть намного проще чтобы достичь того же результата, используя только glBlendFunc(). Я также пробовал GL_SRC_ALPHA_SATURATE, который, похоже, не работает в моей реализации.

+0

Я бы просто кусаю пулю и делаю быстрый шейдер. Нет вопросов о том, что происходит :) –

+0

@MichaelDorgan: вы не можете контролировать смешивание с помощью шейдера. Смешивание - одна из вещей, которые все еще остаются жесткими даже в современных графических процессорах. – datenwolf

ответ

2

Быстрый ответ: нет, это невозможно, используя только вызовы OpenGL. GL_SRC_ALPHA_SATURATE не должны делать то, что вы хотите, либо, его коэффициент RGB будет min(Asrc, (1-Adest)), в вашем случае это, вероятно, всегда в конечном итоге равна Asrc, как я полагаю, ваш альфа назначения всегда равен 0.

Длинный ответ: Ваш лучший и только вариант - записать упомянутый шейдер фрагмента. Чтобы достичь того, чего вы хотите, вам придется использовать некоторые обманки. Я рекомендую предварительное умножение цвета наложения с альфа-фактором и вывод другого альфа-значения для смешивания цвета адресата. Уравнение, аналогичное этому должно хватить:

// Note I cap off the alpha values in both cases to achieve the desired non-linear ramp 
float alpha = overlay_opacity * 2.0f; 
out = vec4(color.rgb * min(1.0f, alpha), min(1.0f, 2.0f - alpha)); 

Затем используйте следующие функции наложения, чтобы убедиться, что цвет назначения смесей, а также:

glBlendFunc(GL_ONE, GL_SRC_ALPHA); 

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

Надеюсь, это решит вашу проблему, удачи!

1

Поскольку вы смешиваете только изображения, вы можете сделать это с помощью трюка: сначала визуализируйте изображение A, модулируя его цвета. Затем вы нарисуете второе изображение поверх него, используя glBlendFunc(GL_ONE, GL_ONE), чтобы сделать его аддитивным и снова изменить цвет. Сделав цвета модуляции для заднего и переднего слоев, следуйте желаемой кривой смешивания, вы получите то, что хотите.

 Смежные вопросы

  • Нет связанных вопросов^_^