Вопрос по android – Прозрачные изображения OpenGL имеют черный цвет

5

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

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

enter image description here

я использую

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

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

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

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

Редактировать: Я изменился

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. Почему Один минус источник добавил этот серый?

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

Ваш Ответ

4   ответа
1

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

Error: User Rate Limit Exceeded EmbMicro
Error: User Rate Limit Exceeded
0

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

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

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

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

Error: User Rate Limit Exceeded EmbMicro
Error: User Rate Limit Exceeded
11

Я изменился

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;

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

Error: User Rate Limit Exceeded
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);
}

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

Похожие вопросы