Как правильно обрабатывать альфа-композитинг с помощью OpenGL

Я использовал glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) для альфа-композиции, как сказано в документе (и фактически то же самое было сказано в документе Direct3D).

Сначала все было хорошо, пока я не скачал результат с графического процессора и не сделал изображение в формате PNG. Результат альфа-компонента неверен. Перед рисованием я очистил буфер кадров с непрозрачным черным цветом. И после того, как я нарисовал что-то полупрозрачное, буфер кадров стал полупрозрачным.

1 ответ

Решение

Ну причина очевидна. С glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)мы фактически игнорируем целевой альфа-канал и предполагаем, что он всегда равен 1. Это нормально, когда мы рассматриваем буфер кадра как нечто непрозрачное.

Но что, если нам нужно правильное значение альфа? glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) и сделайте исходное умножение источника (предварительно умноженную текстуру / цвет вершины или умножьте альфа-компонент на альфа-компоненты, прежде чем установить его в gl_FragColor).

glBlendFunc может только умножить исходные цветовые компоненты на один фактор, но для альфа-композиции необходимо, чтобы место назначения умножалось на оба one_minus_src_alpha а также dst_alpha, Так что это должно быть предварительно умножено. Мы не можем выполнить предварительное умножение в буфере кадра, но пока исходное и целевое объекты предварительно умножены, результат предварительно умножается. То есть сначала очищаем буфер кадров любым предварительно умноженным цветом (например: 0.5, 0.5, 0.5, 0.5 на 50% прозрачный белый вместо 1.0, 1.0, 1.0, 0.5) и нарисуйте на нем предварительно умноженные фрагменты с помощью glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)и у нас будет правильный альфа-канал в результате. Но не забудьте отменить предварительное умножение, если оно не требуется для конечного результата

Другие вопросы по тегам