Рендеринг прозрачной текстуры на glTexture

Некоторое время я работал в opengl относительно плавно, но недавно я заметил, что когда я визуализирую примитив с прозрачной текстурой на мою текстуру fbo (настраиваемый буфер кадра), он делает текстуру fbo прозрачной в пикселях текстуры примитива. прозрачный. Проблема в том, что за этим примитивом (сплошным цветом) есть вещи, уже отрендеренные до прозрачного. Таким образом, текстура fbo не должна быть прозрачной в этих пикселях - смешение сплошного и прозрачного цвета должно приводить к сплошному цвету, не так ли?

По сути, opengl добавляет прозрачности моей текстуре fbo только потому, что последний нарисованный примитив имеет прозрачные пиксели, хотя за ним уже есть сплошные цвета, уже нарисованные в текстуре fbo. Разве opengl не должен смешивать прозрачную текстуру с существующими пикселями fbo и приводить к сплошному цвету, если текстура fbo уже заполнена сплошными цветами перед рендерингом прозрачного примитива?

Что происходит, когда я визуализирую свою текстуру fbo в буфер кадра по умолчанию, так это то, что чистый цвет растекается по его частям - там, где последняя нарисованная текстура прозрачна. Но когда я визуализирую ту же сцену прямо в буфер кадра opengl по умолчанию, сцена выглядит нормально, и чистый цвет не перетекает в прозрачную текстуру.

Что еще более интересно, цвет glClearColor - виден только там, где альфа текстуры примитива имеет градиент - чистый цвет не влияет на то, где альфа текстуры 1.0 или 0.0 ... это ошибка? Похоже, что больше всего это влияет на текстуру примитива в пикселях с альфа 0,5. Затем переход выше или ниже уменьшает влияние glClearColor.

Я знаю, что это немного сложный вопрос / ситуация, я честно старался изо всех сил объяснить

Я использую:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

чтобы отрисовать частично прозрачный примитив в fbo-текстуру, а затем текстуру fbo в кадровый буфер по умолчанию

Вот как выглядит fbo-текстура, нарисованная в fbo opengl по умолчанию:

glClearColor установлен в красный цвет.


person HelloWorldCpp    schedule 23.03.2017    source источник
comment
Перед тем, как нарисовать текстуру fbo на экране, вы не забыли сбросить смешивание? Также было бы неплохо любой код или снимок экрана, на котором это происходит.   -  person vallentin    schedule 23.03.2017
comment
Вы проверили, что GL_BLEND включен?   -  person Matteo Mecucci    schedule 23.03.2017
comment
Скриншот добавлен :) Я не хочу сбрасывать смешивание, потому что я хочу иметь прозрачные fbo-текстуры, проблема в том, что fbo-текстура прозрачна там, где она не должна быть, смешиваясь с прозрачным цветом рамки по умолчанию буфер   -  person HelloWorldCpp    schedule 23.03.2017
comment
Где вы видите прозрачность, а где ее быть не должно? Разве это не результат фильтрации? (При наложении текстуры fbo на квад)   -  person vallentin    schedule 23.03.2017
comment
Кажется, что clearColor (красный) влияет на fbo-текстуру, где текстура квадрата имеет градиент, полностью непрозрачные части правильные (слева от изображения), а полностью прозрачные части также правильные, полностью смешиваясь с фоном ( правая сторона) - градиент между ними, однако, зависит от прозрачного цвета   -  person HelloWorldCpp    schedule 23.03.2017
comment
Если я уберу альфа-канал fbo-текстуры (установив для него значение const 1.0 для каждого пикселя в шейдере), сцена будет отображаться нормально. Но мне нужно, чтобы fbo-текстура была прозрачной в пикселях, где я ничего не рисую, поэтому я подозреваю, что проблема возникает, когда я рисую в fbo-текстуре. Opengl добавляет прозрачность к частям, которые не должны быть прозрачными, поскольку четырехугольник должен сливаться с небом, создавая сплошной цвет (поскольку небо сплошного цвета с альфа-каналом 1.0).   -  person HelloWorldCpp    schedule 23.03.2017


Ответы (1)


смешивание сплошного и прозрачного цвета должно привести к сплошному цвету, не так ли?

Только если ваш режим наложения говорит об этом. И это не так:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

При этом ко всем четырем компонентам цветов применяется одна и та же операция смешивания. Это приводит к тому, что конечный альфа-канал является результатом умножения исходной альфы на себя и прибавления ее к альфа-каналу назначения, умноженному на 1-src alpha.

Теперь вы можете использовать отдельные функции наложения для цвета и альфа:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);

Последние два параметра определяют смешивание только для альфа-канала, а первые два определяют смешивание для цветов RGB. Таким образом сохраняется альфа. Отдельная функциональность смешивания доступна в GL 3.x и выше, но также доступна как расширение на более старом оборудовании.

Но мне кажется, что вы, наверное, вообще не хотите менять альфу. Поэтому просто записывает альфа-маску при рендеринге в текстуру:

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);

Не забудьте отменить альфа-маску, когда захотите написать ее снова.

person Nicol Bolas    schedule 23.03.2017
comment
Привет, извините, что вернулся, но теперь, когда я сбрасываю все компоненты маски в значение true после завершения рендеринга до 1-й fbo-текстуры, а затем пытаюсь отрендерить другой слой (2-я текстура fbo) ЗА первой fbo-текстурой, прозрачная четырехугольная текстура из 1-й fbo-текстуры видна только там, где в этом fbo уже есть сплошные цвета ... хотя она хорошо работает для 1 fbo-текстуры! Есть идеи, как правильно отрендерить несколько fbo-текстур поверх друг друга? заранее спасибо - person HelloWorldCpp; 23.03.2017
comment
Если я не сброшу glColorMask, нижний слой не будет отображаться - person HelloWorldCpp; 23.03.2017