Ответ 1
Я думаю, что здесь есть две возможные проблемы.
Помните, что все перекрывающиеся линии смешиваются здесь дважды. Однажды, когда они смешиваются с текстурой FBO и снова, когда текстура FBO смешивается над сценой.
Итак, первая возможность заключается в том, что у вас нет смешивания, если вы рисуете одну линию над другой в наложении FBO. Когда вы рисуете на поверхности RGBA с смещением, текущая альфа просто записывается непосредственно в альфа-канал наложения FBO. Затем, когда вы смешаете всю тексту FBO над сценой, эта альфа делает ваши линии полупрозрачными. Поэтому, если вы смешиваете "мир", но не между элементами наложения, возможно, что смешение не происходит.
Другая связанная проблема: когда вы смешаете одну линию над другой в "стандартном" режиме смешивания (src alpha, 1 - src alpha) в FBO, альфа-канал "смешанной" части будет содержать смесь альфах двух элементов наложения. Вероятно, это не то, что вы хотите.
Например, если вы нарисуете две 50% альфа-линии друг над другом в оверлее, чтобы получить эквивалентный эффект, когда вы blit FBO, вам нужно, чтобы FBO-альфа... 75%. (То есть 1 - (1 -.5) * (1-0.5), что и произойдет, если вы просто нарисовали две 50% альфа-линии над вашей сценой. Но когда вы рисуете две 50% линии, вы будете получить 50% альфа в FBO (смесь 50% с... 50%.
Это поднимает окончательный вопрос: предварительно смешивая линии друг с другом, прежде чем смешивать их по всему миру, вы меняете порядок розыгрыша. Если вы, возможно, имели:
blend (смесь (смесь (цвет фона, модель), первая строка), вторая строка);
теперь у вас будет
blend (смесь (первая строка, вторая строка), смесь (цвет фона, модель)).
Другими словами, предварительное смешивание линий наложения в FBO изменяет порядок смешивания и, таким образом, изменяет окончательный вид таким образом, который вы не можете захотеть.
Во-первых, простой способ обойти это: не использовать FBO. Я понимаю, что это ответ на вопрос "переработайте свое приложение", но использование FBO - не самая дешевая вещь, и современные карты GL очень хороши в рисовании линий. Таким образом, одним из вариантов было бы: вместо смешивания строк в FBO, написать геометрию линии в объект буфера вершин (VBO). Просто растягивайте VBO каждый раз. Если вы рисуете меньше, скажем, 40 000 строк за раз, это почти наверняка будет так же быстро, как вы делали раньше.
(Один совет, если вы идете по этому маршруту: используйте glBufferSubData для записи строк, а не glMapBuffer - сопоставление может быть дорогостоящим и не работает на поддиапазонах на многих драйверах... лучше просто позволить драйверу скопировать несколько новых вершин.)
Если это не вариант (например, если вы рисуете сочетание типов фигур или используете сочетание состояния GL, так что "запоминание" того, что вы сделали, намного сложнее, чем просто накопление вершин), тогда вы может хотеть изменить, как вы рисуете в VBO.
В основном то, что вам нужно сделать, это включить отдельное смешивание; инициализируйте наложение до черного + 0% альфа (0,0,0,0) и смешайте "стандартное смешивание" RGB, но добавьте смесь альфа-каналов. Это все еще не совсем корректно для альфа-канала, но, как правило, оно намного ближе - без этого чрезмерно вытянутые области будут слишком прозрачными.
Затем, при рисовании FBO, используйте "предварительно умноженный" альфа, то есть (один, один минус-src-alph).
Вот почему нужен последний шаг: когда вы рисуете в FBO, вы уже умножали каждый призыв на призыв по его альфа-каналу (если смешение включено). Поскольку вы чернели черным, зеленая (0,1,0,0,5) линия теперь темно-зеленая (0,0,5,0,0,5). Если альфа включена, и вы снова смешиваетесь снова, альфа повторно применяется, и у вас будет 0,0.25,0,0,5.). Просто используя цвет FBO как есть, вы избегаете второго альфа-умножения.
Это иногда называют "предварительно умноженной" альфа, потому что альфа уже умножена на цвет RGB. В этом случае вы хотите получить правильные результаты, но в других случаях программисты используют его для скорости. (При предварительном умножении он удаляет мульти на пиксель, когда выполняется операция blend op.)
Надеюсь, что это поможет! Получение смешивания прямо, когда слои не смешиваются в порядке, становится очень сложным, и отдельная смесь недоступна на старом оборудовании, поэтому простое рисование строк каждый раз может быть путем наименьшего страдания.