Альфа-смешивание с несколькими текстурами оставляет цветную границу

Следующая проблема: у меня есть две текстуры, и я хочу объединить их в новую текстуру. Таким образом, одна текстура используется как фон, другая будет наложена. Текстура наложения инициализируется с помощью glClearColor (1.0, 1.0, 1.0, 0.0). Объекты рисуются на текстуре, у этих объектов есть альфа-значения.

Теперь при смешивании двух текстур вокруг объектов остается белая рамка. Граница происходит из-за того, что цвет фона во второй текстуре белый, не так ли?

Как я могу использовать альфа-смешение, когда мне не нужно думать о цвете фона наложенной текстуры?


person Donny    schedule 16.09.2011    source источник
comment
Разве вы не хотели бы вместо этого разместить здесь этот вопрос? gamedev.stackexchange.com   -  person AlexanderMP    schedule 16.09.2011
comment
@AlexanderMP: Почему? Это чисто графический вопрос; это не имеет никакого отношения к играм или разработке игр конкретно.   -  person Nicol Bolas    schedule 16.09.2011
comment
Если бы я подумал, что ему здесь вообще не должно быть места, я бы проголосовал за его закрытие. Однако я думаю, что на специализированном сайте этот вопрос быстрее получил бы хороший ответ. Это было больше похоже на предложение. :) Здесь, на SO, сложные вопросы или вопросы, касающиеся очень специфических вещей, как правило, теряются, иногда их уже никогда не найти, если не назначена награда.   -  person AlexanderMP    schedule 16.09.2011
comment
Боюсь, я не понимаю вопроса. Граница происходит из-за того, что цвет фона во второй текстуре белый, не так ли? Какая вторая текстура? Вы говорите о текстуре сзади или о текстуре, которую вы накладываете сверху? Потому что вы только что сказали, что устанавливаете для него черный цвет и нулевую альфа-канал. Вы забыли позвонить glClear после установки четкого цвета?   -  person Nicol Bolas    schedule 16.09.2011
comment
@AlexanderMP: Я хочу сказать, что вы можете сказать одно и то же о каждом вопросе с тегом OpenGL на нем. Или тег D3D. И подавляющее большинство из них получают ответы. Нет ничего, что выделяло бы этот вопрос из тысяч других вопросов под этими тегами.   -  person Nicol Bolas    schedule 16.09.2011
comment
я вполне уверен в скорости отклика stackoverflow, но большое спасибо ...   -  person Donny    schedule 16.09.2011
comment
@nicol: извините, только что изменил свой вопрос, я хотел очистить фон до белого, и да, я имею в виду наложенную текстуру   -  person Donny    schedule 16.09.2011
comment
подумайте об объекте, который я хочу нарисовать в наложенной текстуре с уменьшающимся значением альфа. Если альфа-значение равно 1, у меня нет проблем, когда альфа-значение начинает падать, я могу видеть сквозь свой объект на белом фоне. Когда я начинаю наложение, белый фон копируется на новую текстуру фона.   -  person Donny    schedule 16.09.2011
comment
Вы не можете игнорировать цвет фона. Если есть большое фоновое изображение, сначала нарисуйте его (с альфа-каналом 255), а затем наложите остальные. В противном случае, возможно, серый цвет 127, 127, 127 в общем случае меньше всего повлияет на ваши изображения. Однако для решения проблемы с границами вы можете взглянуть на это: opengl.org/sdk/docs/man/xhtml/glTexParameter.xml, где говорится о GL_CLAMP_TO_EDGE (в разделе GL_TEXTURE_WRAP_S). Установив правильный параметр текстуры, вы можете избежать рисования OpenGL границы текстуры, что обычно нежелательно.   -  person Shahbaz    schedule 20.09.2011


Ответы (4)


Я решил проблему сам, но большое вам спасибо, ребята!

Проблема заключалась в следующем: для объединения обеих текстур я использовал glblend (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), который не работает из-за того, что OpenGL использует предварительно умноженные альфа-значения. Смешивание с glblend (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) работает, поскольку исходный термин теперь будет: 1 * src_alpha * src_color!

person Donny    schedule 19.09.2011

Как я могу использовать альфа-смешение, когда мне не нужно думать о цвете фона наложенной текстуры?

Вы не можете; ваша функция наложения включает в себя цвет фона, потому что он на самом деле может не быть «фоном». Вы визуализируете несколько объектов в текстуре, поэтому цвет «фона» может фактически быть ранее визуализированным объектом.

Лучше всего свести к минимуму воздействие. Нет особой необходимости, чтобы цвет фона был белым. Просто сделай это черным. Это не заставит артефакты исчезнуть; Надеюсь, это сделает его менее заметным.

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

Но если фон на самом деле прозрачный, без полностью непрозрачного цвета, математика просто перестает работать. Вы получите артефакты; вопрос в том, насколько они будут заметны.

Если у вас есть доступ к более продвинутому оборудованию, вы можете использовать некоторые методы программного смешивания на основе шейдеров. Но это повлияет на производительность.

person Nicol Bolas    schedule 16.09.2011
comment
от этого у меня был бы тот же эффект, но вместо белой границы я бы получил черную, не так ли? - person Donny; 16.09.2011

Хотя я думаю, что вы, вероятно, получите лучшие результаты с черным фоном, как указал Никол Болас. Но вам следует дважды проверить свои функции смешивания, потому что, как вы указываете, это НЕ ДОЛЖНО иметь значения ...

1.0 * 0.0 + 0.734 * 1.0 = 0.734

Чего я действительно не понимаю, так это того, почему ваша основная текстура полностью прозрачна? Это предназначено? Если вы не смешиваете текстуры, а затем используете их где-нибудь еще, инициализация Alpha = 1.0 - отличная идея.

person rioki    schedule 19.09.2011
comment
не основа полностью прозрачна, а наложение, по крайней мере, когда я очищаю его в начале рендеринга! после рисования текстуры корса будут некоторые значения цвета и альфа отличные от 0! - person Donny; 19.09.2011

Убедитесь, что вы отключили запись глубины, прежде чем рисовать прозрачную текстуру (чтобы одна прозрачная текстура не могла «блокировать» другую, предотвращая отрисовку ее части). Для этого просто позвоните glDepthMask(false). Когда вы закончите рисовать прозрачные объекты, вызовите glDepthMask(true), чтобы вернуть нормальную глубину записи.

person fintelia    schedule 19.09.2011