glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_ALPHA)显示为黑色,不透明

时间:2014-10-31 19:29:16

标签: opengl-es-2.0

我正在开发适用于iOS的OpenLG ES 2.0应用程序,并且我在混合功能方面遇到了一些意想不到的行为。我认为这可能只是缺乏理解而不是我的应用程序特有的。我的想法是,如果你有一个纹理多边形,你打电话:

glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)
在绘制之前,您将能够看到纹理不透明的多边形背后的清晰颜色。然而,当我尝试这个时,我看到的只是黑色,我希望它是透明的。

我已经调整了raywenderlich.com中的一些代码,因此请在一个非常简单的场景中展示这一点并将其放在GitHub here上。我希望能够让鱼显示出清晰的颜色(绿色),但它却是黑色的。

非常感谢任何帮助。谢谢!

Black fish

3 个答案:

答案 0 :(得分:2)

这看起来像预期的行为。根据您的问题,我认为主要的断开是关于什么是清晰的颜色,以及清除颜色缓冲区时会发生什么。

清晰的颜色正如其名称所暗示的那样。当您拨打glClear(GL_COLOR_BUFFER_BIT | ...)时,它是用于填充颜色缓冲区的颜色。除此之外它没有任何作用。特别是,背景颜色,通过渲染的部分显示在框架的末尾是透明的。

基于此,让我们来看看你的例子中发生的事情:

  1. 用绿色清除整个颜色缓冲区。
  2. 你画出覆盖窗户一部分的灰色方块。对于颜色缓冲区的该区域,先前的内容由灰色颜色/图案替换。绿色从这个区域消失,除非你再次变绿,否则不会再回来。
  3. 您可以在启用混合的情况下绘制鱼。基于混合方程,鱼纹理透明的先前渲染的部分保持不变,并且其不透明的部分被设置为零。零是黑色。
  4. 有许多不同的方法可以实现您正在寻找的结果。

    1. 您将鱼纹理中的鱼的颜色设为绿色,并使用(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)作为混合功能。这样做的缺点是背景颜色被烘焙到纹理中。
    2. 类似于1.使用相同的混合功能,但在渲染鱼时,将背景颜色作为制服提供到片段着色器中。然后在着色器中,使用从纹理中采样的alpha值作为片段颜色的alpha分量,并使用均匀颜色作为片段颜色的RGB分量。片段着色器的关键部分如下所示:

      uniform vec3 FishColor;
      uniform sampler2D FishSampler;
      ...
      vec4 texVal = texture2D(FishSampler, ...);
      glFragColor = vec4(FishColor, texVal.a);
      
    3. 使用单个绘制调用渲染灰色方块和鱼,两个纹理都绑定。在绘制调用期间启用与(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)的混合,并在片段着色器中组合正方形和鱼:

      uniform sampler2D SquareSampler;
      uniform sampler2D FishSampler;
      ...
      vec4 squareTexVal = texture2D(SquareSampler, ...);
      vec4 fishTexVal = texture2D(FishSampler, ...);
      glFragColor = vec4(squareTexVal.rgb, 1.0 - fishTexVal.a);
      

      请注意,正方形和鱼纹理的纹理坐标很可能必须不同才能正确放置它们。

答案 1 :(得分:0)

这非常具体我理解你的问题。

你可以:

  1. 确保以明确颜色启用Alpha
  2. 鱼纹理仅包含alpha值(即颜色位为零)
  3. 以明确的颜色将alpha设置为零
  4. 首先使用glBlendFunc(GLES20.GL_ONE,GLES20.GL_ONE);
  5. 渲染鱼
  6. 然后使用glBlendFunc(GLES20.GL_ONE_MINUS_DST_ALPHA,GLES20.GL_DST_ALPHA);
  7. 渲染其他纹理

    你应该“透视”第二个纹理。

答案 2 :(得分:0)

as you know, when you use glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
first draw dest is glClearColor(0, 0, 0, 1.0); black color
src is you texture you fish image, because you use src zero, at last the color is black,

you can use 
//    src*(1)+dest*(1-src.alpha)
//    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
//    src*(src.alpha)+dest*(1-src.alpha)
//    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);