我有一个径向渐变纹理 (RGBA),它从中心的黑色完全不透明到边缘的完全透明:

我已经使用最近使用 GLKit 的 OpenGL 模板建立了一个 iOS 项目。我添加了纹理功能并在 setupGL 方法中设置了以下代码:

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

当我在白色背景上的正射投影中重叠这些纹理中的两个(每个都有一个单独的 z)时,我期望是这样的:

但是我得到了这个:

我的问题很简单:为什么? OpenGL ES 2.0 的混合能不能达到这个效果? (我之前已经在 OpenGL ES 1.1 中使用过它)是否有我遗漏的常见问题?这可能是我的纹理的预乘 alpha 问题吗?如果是这样,我的 PNG 或我加载它的方式会很奇怪吗?我正在使用 GLKTextureLoader 加载纹理。

我很可能是错的,但我知道这不可能是着色器问题,因为 alpha 混合发生在它到达片段着色器之前。我的着色器所做的只是直接传递信息。 (也许这是一个问题?)

顶点着色器:
attribute vec4 position;
attribute vec2 texCoordIn;

varying vec2 texCoordOut;

uniform mat4 modelViewProjectionMatrix;

void main()
{
    gl_Position = modelViewProjectionMatrix * position;
    texCoordOut = texCoordIn;
}

片段着色器:
varying lowp vec2 texCoordOut;
uniform sampler2D texture;

void main()
{
    gl_FragColor = texture2D(texture, texCoordOut);
}

我也试过如下设置 glBendFunc,但我得到了相同的结果:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

欢迎任何提示或常见问题。谢谢!

最佳答案

如果 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 产生相同的结果,则表明您的纹理具有 1.0 的统一 alpha。因此,您将获得相当于加法混合的效果,从而给出您显示的结果。如果出现任何情况,您就是在预乘 alpha,然后将 alpha channel 扔掉。

因此,要检查的显而易见的事情是(i)磁盘上的文件; (ii) 您的纹理加载代码。如果您不要求 GLKTextureLoaderApplyPremultiplication(无论如何这不应该影响您的 alpha channel ;大概您是直接从磁盘加载?)那么怀疑会落在(i)上,尽管您在上面直接包含的图像似乎正确行事。

混合发生在片段着色器之后。为了进一步调试问题,您可以尝试丢弃其余信息,例如,将 alpha channel 中的值作为 alpha = 1.0 的红色 channel 传递。

关于ios - 为什么 alpha 混合渐变纹理会在 OpenGL ES 2.0 中产生意想不到的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12906784/

10-15 09:36