2012-04-29 4 views
4

Я работаю над игрой для Android, и мне было интересно, почему всякий раз, когда я рисую изображения с прозрачностью, кажется, что некоторые черные добавляются к прозрачным частям. Это происходит повсюду, и некоторые из моих эффектов выглядят странно.OpenGL прозрачные изображения черны в них

Вот пример. Два круга - это только белые изображения с размытием, но вы можете видеть, когда один накладывается на другой, у него есть тень. Если я перекрываю два круга в Inkscape, я получаю чистый белый цвет, где они перекрываются.

enter image description here

Я использую

GLES20.glEnable(GLES20.GL_BLEND); 
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

для моего смешивания.

Любая идея, почему это происходит и как я могу избежать этого?

Редактировать: единственное, что я могу придумать, это то, что два изображения имеют одинаковые z, поэтому, возможно, они смешиваются только с фоном, а не друг с другом?

Edit: Я изменил

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

в

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_DST_ALPHA); 

Вот результат я искал.

enter image description here

Единственное, в настоящее время является то, что прозрачные образы, которые я имел, что есть прозрачный черный в них игнорируются, что имеет смысл, потому что я думаю, что альфа назначения 1. Почему бы один источник минус добавить, что серый?

+0

Что касается вопроса в вашем редактировании, вы ошибаетесь, и это невозможно. – Tim

+0

Лично я думаю, что тень выглядит потрясающе. Но это только я. – ashes999

ответ

9

Я понял, как исправить.

Я изменил

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

в

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

Оказывается, что Android предварительно умножает альфа текстур PNG изображений при загрузке его (делая белый поседеть).

Я добавил

vColor.r = vColor.r * vColor.a; 
vColor.g = vColor.g * vColor.a; 
vColor.b = vColor.b * vColor.a; 

моей вершинного шейдера сделать умножение для моих других цветов.

+0

Вы можете разделить альфу. Читайте мой комментарий ниже –

1

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

+0

Да, мое изображение полностью белое, а размытие и форма определяются альфа-каналом. – EmbMicro

+1

Это, но какую библиотеку вы используете? Это, конечно, преумножает вашу альфа-версию –

0

Вы используете линейную выборку? Моя мысль может быть, если у вас очень маленькое изображение (меньше, чем 30-40 пикселей в измерении), вы можете получить интерполированные альфа-значения между внутренней частью круга (альфа = 1) с внешней стороны круга (alpha = 0). Это даст вам промежуточные альфа-значения, которые приведут к виду эффекта размытия.

Попробуйте следующий код, когда у вас есть текстуры круга, связанные:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

Может быть, вы можете провести фактическую текстуру, что вы используете такими, что мы можем проверить это? Также, пожалуйста, напишите свой код чертежа, если это не поможет.

+0

. Я не думаю, что вы понимаете. Я ХОЧУ размытие, оно находится в исходном изображении. То, чего нет в оригинале, это черная его часть, где она перекрывается. Я отправлю оригинал в вопросе. – EmbMicro

+0

@ EmbMicro О, извините, я неправильно понял. Какой из этих двух кругов в исходном изображении вы нарисовали первым, и какова ваша настройка буфера глубины, например, если вы используете глубинное тестирование? – Tim

0

Вы также можете разделить на альфа, потому что проблема заключается в том, что при экспорте текстур программное обеспечение обработки изображений может предварительно размножать ваш альфа-канал. Я закончил с альфа-разделением в свой фрагмент-шейдер. Следующий код HLSL, но вы можете легко преобразовать его в GLSL:

float4 main(float4 tc: TEXCOORD0): COLOR0 
{ 
    float4 ts = tex2D(Tex0,tc); 

    //Divide out this pre-multiplied alpha 
    float3 outColor = ts.rgb/ts.a; 

    return float4(outColor, ts.a); 
} 

Обратите внимание, что эта операция является потерей данных, очень потерями и даже если это будет, скорее всего, хватай в таких случаях, это не общее решение , В вашем случае вы можете полностью игнорировать COLOR и подавать оригинальные альфа-и белые в вашем шейдере фрагмента, например. return float4(1,1,1,ts.a); (конвертировать в GLSL)

 Смежные вопросы

  • Нет связанных вопросов^_^