GLES2.0 + framebuffer淡化伪像

时间:2015-04-25 06:33:34

标签: android opengl-es glsl framebuffer

我正在使用GLES 2.0或3.0在android上编写一个简单的测试程序。 (如果解决方案只适用于另一个,那就是我将要使用的那个。)

问题:

  • 基本上我在褪色时遇到奇怪的像素瑕疵。
  • 可以通过使截止阈值更高来“隐藏”此问题,但是淡入淡出仍然具有不完整的一致性,而对于我的目的,这将无效。

示例:

  • Example Pictures (Sorry, I cant post images directly yet)
  • 帧缓冲区分辨率已降低,以使工件更加明显。
  • 所有经过测试的设备都会出现此问题(Nexus 7 2012和2013,Galaxy Tab S 8.4,Galaxy S6 Edge,Galaxy Note 4)
  • 在较新的设备上,问题似乎只是小粉红色的均匀点,在较旧的设备上看起来像链接的图片中看起来不完整。
  • 在最终渲染上运行模糊传递也是不可能的,因为这需要节能和移动友好。

布局:

  • 我创建了2个帧缓冲区。 (使用GLES20.GL_UNSIGNED_SHORT_5_6_5 格式。)
  • 我将第一个设置为渲染目标。
  • 我绘制了一个四倍的缓冲区大小到帧缓冲区。
  • 四边形片段着色器设置为渲染一个以圆圈移动的黑点。
  • 四边形也可以采用纹理并将其与点混合。
  • 然后我切换回渲染到屏幕。
  • 我使用先前设置的渲染目标作为纹理渲染另一个四边形。
  • 然后每帧切换纹理重复此过程。

呈现代码:

int i = 0;
@Override public void onDrawView() {
    setRenderTarget(mRenderTexture[i]);
    mTestShader.setTexture0(mRenderTexture[(i + 1) % 2].getTextureHandle());
    mTestShader.draw(mBlitQuad);
    setRenderTarget(null);
    mBlitShader.setTexture0(mRenderTexture[i].getTextureHandle());
    mBlitShader.draw(mBlitQuad);
    i = ++i % 2;
}

着色器代码:

precision highp float;

uniform float u_GlobalTime;
uniform vec3 u_Resolution;
uniform sampler2D u_Texture0;

varying vec2 v_TexCoord;

void main(void) {
    vec2 uv = v_TexCoord * 2.0 - 1.0;
    uv.x *= u_Resolution.z;
    vec2 pos = vec2(cos(u_GlobalTime), sin(u_GlobalTime)) * 0.5;
    vec4 circle = vec4(1.0 - smoothstep(0.09, 0.11, length(pos - uv)));
    vec4 px = max(texture2D(u_Texture0, v_TexCoord), circle) - 0.025;
    gl_FragColor = step(0.15, px) * px;
}

有关此问题的任何帮助吗?

编辑:
感谢Jerem在谷歌上搜索了一些谷歌后,我找到了GLES20.glDisable(GLES20.GL_DITHER)。这有助于解决这个问题,而在较新的设备上,它可以完美运行。在较旧的设备上,我仍然遇到像HERE所见的伪像。

EDIT2:经过一些测试后,切换到具有均匀RGB颜色的缓冲格式似乎已经完成了GLES30.GL_UNSIGNED_SHORT_5_5_5_1的技巧。我的猜测是它与GPU如何压缩帧缓冲区有关,因为绿色更明显。 (知道它为什么不喜欢5_6_5格式的具体原因仍然会有所帮助。)
两个修复后的最终结果:i.imgur.com/bQsG9YJ.png。

1 个答案:

答案 0 :(得分:2)

它是一个多部分解决方案,调用GLES20.glDisable(GLES20.GL_DITHER),将渲染缓冲区格式设置为GLES30.GL_UNSIGNED_SHORT_5_5_5_1,正如Jerem所说,尽管实验,你也可以在禁用alpha的情况下获得更好的结果在我的设备选择上似乎没有任何影响,可能在其他设备上。