Как правильно обрабатывать альфа-композитинг с помощью 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)
и у нас будет правильный альфа-канал в результате. Но не забудьте отменить предварительное умножение, если оно не требуется для конечного результата