2015-10-20 92 views
2

我简化了我的问题来绘制一个正方形来说明。我想绘制一个纹理,它将alpha通道从0减至255,并垂直回0,以便与背景融合。现在它使背景变暗,我找不到原因。这是使用iOS上的OpenGL ES 9.在OpenGL ES中混合不能像我认为的那样工作

首先,我启用我想我要的混合:

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

然后我填的是缓冲带绿色:

glClearColor(0, 0.5, 0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT); 

我有这个像我使用的质地:

Texture

我画以下的顶点({X,Y,Z},{R,G,B,A},{TX,TY})与GL_TRIANGLES:

{{0.4, 0.3, 0}, {1, 0, 0, 1}, {0, 0}}, 
{{0.6, 0.3, 0}, {1, 0, 0, 1}, {1, 0}}, 
{{0.4, 0.5, 0}, {1, 0, 0, 1}, {0, 1}}, 
{{0.6, 0.3, 0}, {1, 0, 0, 1}, {1, 0}}, 
{{0.4, 0.5, 0}, {1, 0, 0, 1}, {0, 1}}, 
{{0.6, 0.5, 0}, {1, 0, 0, 1}, {1, 1}}, 

我希望顶点的红色成分,以调节质地,因为这是我的片段着色器:

varying lowp vec4 DestinationColor; 

varying lowp vec2 TexCoordOut; 
uniform sampler2D Texture; 

void main(void) { 
    gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); 
} 

这样做,但结果不是简单地在绿色红色。天黑的边缘,在那里我会想到要绘制只是绿色:

Problem

的答案类似的问题here说我应该使用glTexEnv(GL_BLEND)。不过,我认为这是一个OpenGL ES 1 API。

任何人都知道我可以如何实现所需的混合?我想让红色在绿色中消失。顶部和底部应该是绿色的,而不是较深的。不应该有明显的水平边缘。

编辑:我添加更多图片说明我的问题。下面是GIMP两个粉红色圆点:

Pink dots in GIMP

当我在其他(GIMP)的顶部移动一个,他们很好地融为一体。他们还与绿色背景很好地融合:

Pink dots in GIMP, overlayed

当我重新创建在OpenGL ES,我得到的颜色变深,这是尤其是粉红色的圆点叠加可见。我做了一个很窄的这个时候,所以你能看到的效果更好:

Pink dots in OpenGL ES

我都尝试glBlendFunc和glBlendFuncSeparate,这就造成同样的效果。请注意背景alpha是1.

+0

我在混合功能上有些生疏,但是你的截图看起来像结果类似于Photoshop的“繁殖”。我认为你需要一个不同的混合函数,但不能完全回答哪一个... –

+0

应该有一个常用混合函数的“备忘单”,以供参考... –

+0

我到达了这个混合函数,因为它被推荐为“正常”。 GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA应该表示color_blended = color_src * alpha_src + color_destination *(1 - alpha_src)。这就是我困惑的原因。假设alpha是0.1,红色是1,绿色是0.5,那些边缘应该是0.1(1,0,0)+(1-0.1)(0,0.5,0)=(0.1,0.45,0),对?如果您打开一个颜色比较网站并将#1A7300(混合示例)与#008000(背景)进行比较,则不会太暗。 –

回答

0

您的问题很可能是显示alpha通道本身,而不是颜色。由于您使用直接混合功能,因此它会将alpha通道设置为低于1.0的值,然后您将其看作显示屏上的预乘颜色值:RGB = RGB*A。您应该使用混合功能分开单独处理alpha通道:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE) 

现在,这将混合的颜色如你预期,但保持1.0目的地阿尔法值,你鲜明的色彩设置。

+0

这是非常有用的信息,这看起来像一个更好的混合方式。但我很遗憾地说它对我没有任何影响。 –

+1

难道你的纹理是从图像中加载的,所以颜色是alpha预乘?基本上同样的事情发生在将图像转换为RGBA原始数据并且颜色RGB与alpha相乘时产生阴影结果。尝试检查一些半透明的像素,如果RGB部分是相同的或是否缩放(它需要是相同的) –

+0

绝妙的主意!我并没有想到纹理本身可能是错误的。我只是看,我正在使用(iOS常量)kCGImageAlphaPremultipliedLast将纹理绘制到内存中。我猜你几乎可以肯定找到了我的问题的根源。我用kCGImageAlphaLast得不到任何数据,所以我会继续努力。我很快会回来验证这确实是解决方案。 –

0

如果您的设备使用默认设置,假设像素数据是预先多元化的,那么您可能会得到类似于您所看到的结果。我建议将您的Alpha通道图像转换为简单的灰度图,然后将其保存为PNG并验证它是灰度而不是BGRA格式。然后,以正常方式将此8位每像素数据加载到纹理中,而不必担心任何预乘问题(灰度不包含和alpha通道)。接下来,通过读取灰度测试中的单个字节,然后将现有的DestinationColor的3个分量乘以该线性alpha值,执行着色器中的预乘步骤。例如,这个预先倍增的步骤让我的着色器在iOS上工作。

相关问题