【问题标题】:OpenGL texture blending problemsOpenGL纹理混合问题
【发布时间】:2011-03-29 01:16:15
【问题描述】:

我正在使用 OpenGL ES 为 iPad 创建一个 2d 应用程序,但在绘制透明图像时遇到了一些问题。

我使用的是完全透明的 png-24 图像。我还改变了一些纹理的颜色,它们是白色的,有些区域是透明或半透明的。一切正常。

但是,当我尝试设置其中一种纹理的 alpha 值时,它的工作并不完全正确。颜色太饱和了,如果 alpha 值 = 0,我会在浅灰色背景上留下白色而不是透明的图像。当这样的透明图像在暗图像之上时,暗图像变成与透明图像颜色相似的颜色。

我尝试了glTexEnviglBlendFunc 的许多参数组合,但均未成功。

我对 OpenGL 不是很了解,所以如果有人有任何建议,那就太好了。让我知道是否有任何有用的细节。

谢谢。


这里是OpenGL的初始化

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glDisable(GL_DEPTH_TEST); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND);

【问题讨论】:

    标签: iphone ipad opengl-es


    【解决方案1】:

    听起来你告诉 OpenGL 你的纹理已经预乘了 alpha,但实际上并没有。

    glBlendFunc 使用什么参数?

    More explanation of pre-multiplied alpha

    【讨论】:

    • 混合函数设置为glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);。我也在我的问题中添加了 OpenGL 初始化代码。
    • 显然混合功能实际上被设置为glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); 在我的代码中的其他地方。将其更改为 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 修复了设置透明颜色的问题,但它破坏了半透明纹理的渲染以及变成可怕灰色的纹理边缘。
    • @Anthony:你的纹理中很可能混合了预乘和未乘的 Alpha。您可以保持一致,也可以四处切换glBlendFunc
    • 我认为 alpha 预乘可能是问题所在,尽管所有图像的问题都是一致的。 alpha 预乘是烘焙到图像中的东西还是在编译过程中发生的事情?我怎样才能禁用它?谢谢
    • @Anthony:图像中存在(或不存在),但绝不是永久固定的,您可以在加载时轻松更改它。
    【解决方案2】:

    感谢大家的意见。我想我找到了解决办法。

    问题在于纹理具有预乘 alpha,但应用纹理的多边形没有。使用 glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 后,我所要做的就是手动将多边形的 R、G 和 B 颜色值乘以 alpha 值,这样所有内容基本上都在使用预乘 alpha 并且呈现一致。

    我不确定这是否是最有效的解决方案,但到目前为止它似乎工作得很好,只需在我的图像渲染类中添加几行代码即可在不透明度时更新颜色值变了。

    呜呜

    【讨论】:

      【解决方案3】:
      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA);
      

      这是无效的,您在检查 GL 错误吗?检查 glTexEnv 手册页以查看有效值:

      http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml

      GL_ALPHA 不是纹理函数,有效的纹理函数是 GL_ADD、GL_MODULATE、GL_DECAL、GL_BLEND、GL_REPLACE 和 GL_COMBINE。

      您可能希望将 GL_ALPHA 替换为 GL_MODULATE,以便可以使用顶点颜色 (glColor) 控制纹理 alpha。此模式将纹理与顶点颜色相乘。

      【讨论】:

      • 我把纹理环境函数改成了glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);。你是对的,但这并不能解决我的问题。如果我使用glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);,我会遇到在透明多边形上渲染的纹理的问题,正如我所描述的那样奇怪地渲染。如果我使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,那些透明度会正确渲染,但纹理中的半透明像素会变成灰色。你对此有什么想法吗?谢谢。
      • @Anthony 你确定你的帧缓冲中有一个 alpha 通道吗?这是一个常见的错误。
      【解决方案4】:

      如果您使用的是 24 位 PNG,则可能没有 Alpha 通道。尝试转换为 32 位 PNG 并编辑 Alpha 通道。或者,您可以自己将 24 位转换为 32 位,并从图像数据中生成 alpha 通道(例如:通过色度键控)。

      如果您想要添加混合,请使用 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glBlendFunc(GL_SRC_ALPHA, GL_ONE);

      【讨论】:

      • PNG 的 Alpha 通道工作正常。问题是当我更改纹理映射到的顶点的颜色时。使用任何不透明颜色都可以正常工作,但透明颜色会导致这些问题。这有意义还是我解释不正确?
      • 你在通过glTexEnv设置什么吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      相关资源
      最近更新 更多