如何在透明纹理上停止OpenGL背景渗色

时间:2013-03-09 18:14:16

标签: opengl-es-2.0 transparency

我有一个iOS OpenGL ES 2.0 3D游戏,我正在努力让透明纹理很好地工作,在这个特殊的栅栏示例中。

我将从最终结果开始。绿色背景/清晰颜色的部分穿过围栏的边缘 - 注意它不是所有边缘,有些是好的:

Background bleed evidence

右上角没有出血的原因是手术顺序。从下面的镜头中可以看出,绘制顺序包括一些在围栏之前绘制的建筑物。但大部分都是在围栏之后:

Draw progression with depth

因此,一种解决方案是始终最后绘制透明纹理对象。我想探索其他解决方案,因为我的管道可能并不总是允许这样做。我正在寻找其他建议来解决这个问题,而无需对我的绘图进行排序。

这可能是一个深度或混合功能,但我已经尝试了大量的东西,似乎没有任何工作(不同的混合功能,不同的丢弃alpha级别,不同的背景颜色,不同的纹理设置)。

以下是我实施的一些细节。

在我的碎片着色器中,我丢弃了具有透明度的碎片 - 这样它们就无法渲染到深度:

lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.5)
    discard;

我正在使用一个巨大的PVR纹理图集和mipmapping - 纹理本身应该只有0或1的alpha,但混合的东西可能导致这个:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

我在渲染时使用以下混合:

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

任何修复这种出血的建议都会很棒!

编辑 - 根据评论LINEAR / NEAREST中的建议尝试了不同的纹理过滤器,但结果相同。注意我也尝试过NEAREST / NEAREST并且没有运气:

enter image description here

2 个答案:

答案 0 :(得分:1)

尝试增加alpha过滤器限制,

lowp vec4 texVal = texture2D(sTexture, texCoord); if(texVal.w < 0.9) discard;

答案 1 :(得分:0)

我知道这是一个古老的问题,但是我试图找到我非常相似的OpenGL问题的答案时遇到过几次。以为我会在这里与有相似之处的人分享我的发现。我的代码中的罪魁祸首看起来像这样:

glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);

我使用粉红色的透明色,便于在调试时进行视觉参考。尽管它在背景和主体颜色之间混合时是透明的,但它会像问题截图中的症状一样流血。修复它的原因是包装此代码以掩盖glClear步骤。它看起来像这样:

glColorMask(false, false, false, true);
glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(true, true, true, true);

据我所知,这意味着当明确的过程开始时它只在alpha通道上运行。在此之后,所有重新启用以按预期继续该过程。如果对OpenGL有更深入了解的人能够更好地解释它,我很乐意听到!